Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4645 → Rev 4647

/branches/arm/contrib/conf/gxemul.sh
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/branches/arm/contrib/conf/mips32-gx.sh
0,0 → 1,10
#!/bin/sh
 
DISK_IMG=hdisk.img
 
# Create a disk image if it does not exist
if [ ! -f "$DISK_IMG" ]; then
tools/mkfat.py uspace/dist/data "$DISK_IMG"
fi
 
gxemul $@ -E testmips -C R4000 -X image.boot -d d0:"$DISK_IMG"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
Added: svn:mergeinfo
/branches/arm/contrib/conf/ia32-qe.sh
0,0 → 1,10
#!/bin/sh
 
DISK_IMG=hdisk.img
 
# Create a disk image if it does not exist
if [ ! -f "$DISK_IMG" ]; then
tools/mkfat.py uspace/dist/data "$DISK_IMG"
fi
 
qemu -m 32 -hda "$DISK_IMG" -cdrom image.iso -boot d
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/arm/contrib/conf/ppc32-qe.sh
0,0 → 1,3
#!/bin/sh
 
qemu-system-ppc -M mac99 -boot d -cdrom image.iso
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/arm/contrib/conf/pearpc.conf
1,7 → 1,7
ppc_start_resolution = "800x600x32"
pci_ide0_master_installed = 0
 
prom_bootmethod = "force"
prom_loadfile = "image.boot"
pci_ide0_master_installed = 1
pci_ide0_master_image = "image.iso"
pci_ide0_master_type = "cdrom"
 
key_toggle_mouse_grab = "F11"
/branches/arm/contrib/conf/arm32-gx.sh
0,0 → 1,3
#!/bin/sh
 
gxemul $@ -E testarm -X image.boot
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/arm/contrib/conf/msim.conf
3,6 → 3,7
#
 
add dcpu cpu0
add dcpu cpu1
 
add rwm mainmem 0x00000000
mainmem generic 16M
10,7 → 11,7
 
add rom bootmem 0x1fc00000
bootmem generic 4096k
bootmem load "image.boot"
bootmem load "image.boot"
 
add dprinter printer 0x10000000
add dkeyboard keyboard 0x10000000 2
/branches/arm/contrib/toolchain/toolchain.ia64.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.2"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
34,7 → 34,6
WORKDIR=`pwd`
TARGET="${PLATFORM}-pc-linux-gnu"
PREFIX="${CROSS_PREFIX}/${PLATFORM}"
INCLUDESDIR="${WORKDIR}/include"
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
OBJDIR="${WORKDIR}/gcc-obj"
/branches/arm/contrib/toolchain/toolchain.arm32.sh
19,19 → 19,16
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.2"
GDB_VERSION="6.8"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
GDB="gdb-${GDB_VERSION}.tar.bz2"
 
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
 
PLATFORM="arm"
WORKDIR=`pwd`
40,7 → 37,6
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
OBJDIR="${WORKDIR}/gcc-obj"
GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
 
echo ">>> Downloading tarballs"
 
60,10 → 56,6
wget -c "${GCC_SOURCE}${GCC_CPP}"
check_error $? "Error downloading GCC C++."
fi
if [ ! -f "${GDB}" ]; then
wget -c "${GDB_SOURCE}${GDB}"
check_error $? "Error downloading GDB."
fi
 
echo ">>> Creating destionation directory"
if [ ! -d "${PREFIX}" ]; then
88,8 → 80,6
check_error $? "Error unpacking GCC Objective C."
tar -xvjf "${GCC_CPP}"
check_error $? "Error unpacking GCC C++."
tar -xvjf "${GDB}"
check_error $? "Error unpacking GDB."
 
echo ">>> Compiling and installing binutils"
cd "${BINUTILSDIR}"
107,13 → 97,5
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
check_error $? "Error compiling/installing GCC."
 
echo ">>> Compiling and installing Cross GDB for arm arch"
cd "${GDBDIR}"
check_error $? "Change directory failed."
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--disable-nls" "--program-prefix=${TARGET}-"
check_error $? "Error configuring GDB."
PATH="${PATH}:${PREFIX}/bin" make all install
check_error $? "Error compiling/installing GDB."
 
echo
echo ">>> Cross-compiler and Debugger for ${TARGET} installed."
echo ">>> Cross-compiler for ${TARGET} installed."
/branches/arm/contrib/toolchain/toolchain.ppc32.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.2"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
/branches/arm/contrib/toolchain/toolchain.ppc64.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.1"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
/branches/arm/contrib/toolchain/toolchain.mipseb32.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.1"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
32,7 → 32,7
 
PLATFORM="mips"
WORKDIR=`pwd`
TARGET="${PLATFORM}-sgi-irix5"
TARGET="${PLATFORM}-linux-gnu"
PREFIX="${CROSS_PREFIX}/${PLATFORM}"
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
/branches/arm/contrib/toolchain/toolchain.amd64.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.2"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
/branches/arm/contrib/toolchain/toolchain.ia32.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.2"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
/branches/arm/contrib/toolchain/toolchain.mipsel32.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.1"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
/branches/arm/contrib/toolchain/toolchain.sparc64.sh
19,8 → 19,8
CROSS_PREFIX="/usr/local"
fi
 
BINUTILS_VERSION="2.18"
GCC_VERSION="4.3.1"
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
 
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
/branches/arm/contrib/font/bdf2c.pl
0,0 → 1,164
#!/usr/bin/perl -w
 
#
# Copyright (c) 2000 Dmitry Bolkhovityanov
# Copyright (c) 2009 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
use strict;
 
my $skip;
 
my $width;
my $height;
my $offset_x;
my $offset_y;
 
my $gwidth;
my $gheight;
my $goffset_x;
my $goffset_y;
 
my $index;
my @glyphs;
my @chars;
 
open(BDF, "u_vga16.bdf") or die("Unable to open source font\n");
 
READHEADER: while (<BDF>) {
/^FONTBOUNDINGBOX\s/ and do {
($skip, $width, $height, $offset_x, $offset_y) = (split);
die("Font width is not 8px\n") if ($width != 8);
die("Font height is not 16px\n") if ($height != 16);
};
/^CHARS\s/ && last READHEADER;
}
 
READCHARS: while (<BDF>) {
/^ENCODING\s+([0-9]+)\s*$/ && do {
$index = $1;
};
/^BBX\s/ && do {
($skip, $gwidth, $gheight, $goffset_x, $goffset_y) = (split);
};
/^BITMAP/ && do {
my @glyph = ();
my $y;
# Add empty lines at top
my $empties = $height + $offset_y - $goffset_y - $gheight;
for ($y = 0; $y < $empties; $y++) {
$glyph[$y] = 0;
}
# Scan the hex bitmap
for ($y = $empties; $y < $empties + $gheight; $y++) {
$_ = <BDF>;
$glyph[$y] = hex(substr($_, 0, 2)) >> $goffset_x;
}
# Add empty lines at bottom
my $fill = $height - $gheight - $empties;
for ($y = $empties + $gheight; $y < $empties + $gheight + $fill; $y++) {
$glyph[$y] = 0;
}
if ($index != 0) {
$glyphs[$index] = (\@glyph);
push(@chars, $index);
}
};
/^ENDFONT/ && last READCHARS;
}
 
close(BDF);
 
@chars = sort { $a <=> $b } (@chars);
 
print "#define FONT_GLYPHS " . (@chars + 1). "\n";
print "#define FONT_SCANLINES " . $height . "\n";
 
print "\n";
print "uint16_t fb_font_glyph(const wchar_t ch)\n";
print "{\n";
print "\tif (ch == 0x0000)\n";
print "\t\treturn 0;\n\n";
 
my $pos = 0;
my $start = -1;
my $start_pos = 0;
my $prev = 0;
for $index (@chars) {
if ($prev + 1 < $index) {
if ($start != -1) {
if ($start == $prev) {
printf "\tif (ch == 0x%.4x)\n", $start;
print "\t\treturn " . $start_pos . ";\n";
} else {
printf "\tif ((ch >= 0x%.4x) && (ch <= 0x%.4x))\n", $start, $prev;
print "\t\treturn (ch - " . ($start - $start_pos) . ");\n";
}
print "\t\n";
}
$start = $index;
$start_pos = $pos;
}
$pos++;
$prev = $index;
}
 
print "\treturn " . @chars . ";\n";
print "}\n";
 
print "\n";
print "uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES] = {";
 
for $index (@chars) {
print "\n\t{";
my $y;
for ($y = 0; $y < $height; $y++) {
print ", " if ($y > 0);
printf "0x%.2x", $glyphs[$index]->[$y];
}
print "},";
}
 
print "\n\t\n\t/* Special glyph for unknown character */\n\t{";
my $y;
for ($y = 0; $y < $height; $y++) {
print ", " if ($y > 0);
printf "0x%.2x", $glyphs[63]->[$y];
}
 
print "}\n};\n";
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/arm/contrib/font/u_vga16.bdf
0,0 → 1,66709
STARTFONT 2.1
FONT -Bolkhov-VGA-Medium-R-Normal--16-160-75-75-C-80-iso10646-1
SIZE 16 75 75
FONTBOUNDINGBOX 8 16 0 -4
STARTPROPERTIES 24
FOUNDRY "Bolkhov"
FAMILY_NAME "VGA"
WEIGHT_NAME "Medium"
SLANT "R"
SETWIDTH_NAME "Normal"
ADD_STYLE_NAME ""
PIXEL_SIZE 16
POINT_SIZE 160
RESOLUTION_X 75
RESOLUTION_Y 75
SPACING "C"
AVERAGE_WIDTH 80
CHARSET_REGISTRY "iso10646"
CHARSET_ENCODING "1"
CAP_HEIGHT 10
X_HEIGHT 7
FONT_ASCENT 12
FONT_DESCENT 4
FACE_NAME "VGA Unicode"
COPYRIGHT "Copyright (c) 2000 Dmitry Bolkhovityanov, bolkhov@inp.nsk.su"
HOMEPAGE "http://www.inp.nsk.su/~bolkhov/files/fonts/univga/"
NOTICE "VGA is a trademark of IBM Corporation."
DEFAULT_CHAR 0
_XMBDFED_INFO "Edited with xmbdfed 4.4."
ENDPROPERTIES
CHARS 2899
STARTCHAR char0
ENCODING 0
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DA
02
80
82
02
80
82
02
80
B6
00
00
00
00
ENDCHAR
STARTCHAR space
ENCODING 32
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR exclam
ENCODING 33
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
3C
3C
18
18
18
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR quotedbl
ENCODING 34
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
66
66
66
24
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR numbersign
ENCODING 35
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
6C
6C
FE
6C
6C
6C
FE
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR dollar
ENCODING 36
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
7C
C6
C2
C0
7C
06
06
86
C6
7C
18
18
00
00
ENDCHAR
STARTCHAR percent
ENCODING 37
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C2
C6
0C
18
30
60
C6
86
00
00
00
00
ENDCHAR
STARTCHAR ampersand
ENCODING 38
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
6C
38
76
DC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR quotesingle
ENCODING 39
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
30
30
20
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR parenleft
ENCODING 40
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
30
30
30
30
30
30
18
0C
00
00
00
00
ENDCHAR
STARTCHAR parenright
ENCODING 41
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
18
0C
0C
0C
0C
0C
0C
18
30
00
00
00
00
ENDCHAR
STARTCHAR asterisk
ENCODING 42
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
3C
FF
3C
66
00
00
00
00
00
00
ENDCHAR
STARTCHAR plus
ENCODING 43
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
18
7E
18
18
00
00
00
00
00
00
ENDCHAR
STARTCHAR comma
ENCODING 44
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
18
18
18
30
00
00
00
ENDCHAR
STARTCHAR hyphen
ENCODING 45
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FE
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR period
ENCODING 46
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR slash
ENCODING 47
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
02
06
0C
18
30
60
C0
80
00
00
00
00
ENDCHAR
STARTCHAR zero
ENCODING 48
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
C6
C6
D6
D6
C6
C6
6C
38
00
00
00
00
ENDCHAR
STARTCHAR one
ENCODING 49
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
38
78
18
18
18
18
18
18
7E
00
00
00
00
ENDCHAR
STARTCHAR two
ENCODING 50
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
06
0C
18
30
60
C0
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR three
ENCODING 51
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
06
06
3C
06
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR four
ENCODING 52
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
1C
3C
6C
CC
FE
0C
0C
0C
1E
00
00
00
00
ENDCHAR
STARTCHAR five
ENCODING 53
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C0
C0
C0
FC
06
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR six
ENCODING 54
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
60
C0
C0
FC
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR seven
ENCODING 55
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
06
06
0C
18
30
30
30
30
00
00
00
00
ENDCHAR
STARTCHAR eight
ENCODING 56
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
7C
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR nine
ENCODING 57
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
7E
06
06
06
0C
78
00
00
00
00
ENDCHAR
STARTCHAR colon
ENCODING 58
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
00
00
00
18
18
00
00
00
00
00
ENDCHAR
STARTCHAR semicolon
ENCODING 59
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
00
00
00
18
18
30
00
00
00
00
ENDCHAR
STARTCHAR less
ENCODING 60
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
06
0C
18
30
60
30
18
0C
06
00
00
00
00
ENDCHAR
STARTCHAR equal
ENCODING 61
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
00
00
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR greater
ENCODING 62
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
60
30
18
0C
06
0C
18
30
60
00
00
00
00
ENDCHAR
STARTCHAR question
ENCODING 63
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
0C
18
18
18
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR at
ENCODING 64
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
C6
C6
DE
DE
DE
DC
C0
7C
00
00
00
00
ENDCHAR
STARTCHAR A
ENCODING 65
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
6C
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR B
ENCODING 66
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR C
ENCODING 67
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR D
ENCODING 68
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
66
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR E
ENCODING 69
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR F
ENCODING 70
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR G
ENCODING 71
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR H
ENCODING 72
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR I
ENCODING 73
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR J
ENCODING 74
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
0C
0C
0C
0C
0C
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR K
ENCODING 75
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR L
ENCODING 76
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
60
60
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR M
ENCODING 77
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR N
ENCODING 78
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR O
ENCODING 79
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR P
ENCODING 80
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR Q
ENCODING 81
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
C6
D6
DE
7C
0C
0E
00
00
ENDCHAR
STARTCHAR R
ENCODING 82
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
6C
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR S
ENCODING 83
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
60
38
0C
06
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR T
ENCODING 84
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR U
ENCODING 85
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR V
ENCODING 86
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
6C
38
10
00
00
00
00
ENDCHAR
STARTCHAR W
ENCODING 87
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
00
00
00
ENDCHAR
STARTCHAR X
ENCODING 88
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
6C
7C
38
38
7C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Y
ENCODING 89
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Z
ENCODING 90
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
86
0C
18
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR bracketleft
ENCODING 91
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
30
30
30
30
30
30
30
30
3C
00
00
00
00
ENDCHAR
STARTCHAR backslash
ENCODING 92
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
80
C0
E0
70
38
1C
0E
06
02
00
00
00
00
ENDCHAR
STARTCHAR bracketright
ENCODING 93
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
0C
0C
0C
0C
0C
0C
0C
0C
3C
00
00
00
00
ENDCHAR
STARTCHAR asciicircum
ENCODING 94
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
6C
C6
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR underscore
ENCODING 95
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
FF
00
00
ENDCHAR
STARTCHAR grave
ENCODING 96
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
18
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR a
ENCODING 97
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR b
ENCODING 98
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
78
6C
66
66
66
66
7C
00
00
00
00
ENDCHAR
STARTCHAR c
ENCODING 99
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR d
ENCODING 100
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR e
ENCODING 101
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR f
ENCODING 102
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
64
60
F0
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR g
ENCODING 103
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR h
ENCODING 104
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR i
ENCODING 105
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR j
ENCODING 106
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
06
00
0E
06
06
06
06
06
06
66
66
3C
00
ENDCHAR
STARTCHAR k
ENCODING 107
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
66
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR l
ENCODING 108
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR m
ENCODING 109
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
EC
FE
D6
D6
D6
D6
C6
00
00
00
00
ENDCHAR
STARTCHAR n
ENCODING 110
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR o
ENCODING 111
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR p
ENCODING 112
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
7C
60
60
F0
00
ENDCHAR
STARTCHAR q
ENCODING 113
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
CC
CC
CC
CC
CC
7C
0C
0C
1E
00
ENDCHAR
STARTCHAR r
ENCODING 114
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR s
ENCODING 115
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR t
ENCODING 116
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR u
ENCODING 117
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR v
ENCODING 118
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
66
66
3C
18
00
00
00
00
ENDCHAR
STARTCHAR w
ENCODING 119
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR x
ENCODING 120
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
6C
38
38
38
6C
C6
00
00
00
00
ENDCHAR
STARTCHAR y
ENCODING 121
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR z
ENCODING 122
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
30
60
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR braceleft
ENCODING 123
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
18
18
18
70
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR bar
ENCODING 124
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
00
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR braceright
ENCODING 125
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
18
18
18
0E
18
18
18
18
70
00
00
00
00
ENDCHAR
STARTCHAR asciitilde
ENCODING 126
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR char127
ENCODING 127
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
38
6C
C6
C6
C6
FE
00
00
00
00
00
ENDCHAR
STARTCHAR space
ENCODING 160
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR exclamdown
ENCODING 161
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
18
18
18
3C
3C
3C
18
00
00
00
00
ENDCHAR
STARTCHAR cent
ENCODING 162
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
3C
66
60
60
60
66
3C
18
18
00
00
00
00
ENDCHAR
STARTCHAR sterling
ENCODING 163
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
64
60
F0
60
60
60
60
E6
FC
00
00
00
00
ENDCHAR
STARTCHAR currency
ENCODING 164
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
66
3C
66
66
66
3C
66
00
00
00
00
00
ENDCHAR
STARTCHAR yen
ENCODING 165
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
3C
18
7E
18
7E
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR brokenbar
ENCODING 166
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
00
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR section
ENCODING 167
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
C6
60
38
6C
C6
C6
6C
38
0C
C6
7C
00
00
00
ENDCHAR
STARTCHAR dieresis
ENCODING 168
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR copyright
ENCODING 169
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
99
A5
A1
A1
A5
99
42
3C
00
00
00
00
ENDCHAR
STARTCHAR ordfeminine
ENCODING 170
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
3C
6C
6C
3E
00
7E
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR guillemotleft
ENCODING 171
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
36
6C
D8
6C
36
00
00
00
00
00
00
ENDCHAR
STARTCHAR logicalnot
ENCODING 172
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FE
06
06
06
06
00
00
00
00
00
ENDCHAR
STARTCHAR hyphen
ENCODING 173
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
3C
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR registered
ENCODING 174
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
44
BA
B2
AA
44
38
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR macron
ENCODING 175
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR degree
ENCODING 176
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
6C
38
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR plusminus
ENCODING 177
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
7E
18
18
00
7E
00
00
00
00
00
ENDCHAR
STARTCHAR twosuperior
ENCODING 178
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D8
30
60
C8
F8
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR threesuperior
ENCODING 179
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D8
30
18
D8
70
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR acute
ENCODING 180
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR mu
ENCODING 181
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
F6
C0
C0
C0
00
ENDCHAR
STARTCHAR paragraph
ENCODING 182
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7F
DB
DB
DB
7B
1B
1B
1B
1B
1B
00
00
00
00
ENDCHAR
STARTCHAR periodcentered
ENCODING 183
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR cedilla
ENCODING 184
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
0C
38
00
ENDCHAR
STARTCHAR onesuperior
ENCODING 185
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
70
30
30
30
78
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR ordmasculine
ENCODING 186
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
6C
38
00
7C
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR guillemotright
ENCODING 187
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D8
6C
36
6C
D8
00
00
00
00
00
00
ENDCHAR
STARTCHAR onequarter
ENCODING 188
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
66
CE
9E
3E
06
06
00
00
ENDCHAR
STARTCHAR onehalf
ENCODING 189
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
60
DC
86
0C
18
3E
00
00
ENDCHAR
STARTCHAR threequarters
ENCODING 190
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
30
62
36
EC
18
30
66
CE
9E
3E
06
06
00
00
ENDCHAR
STARTCHAR questiondown
ENCODING 191
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
30
30
60
C0
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Agrave
ENCODING 192
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Aacute
ENCODING 193
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Acircumflex
ENCODING 194
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
6C
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Atilde
ENCODING 195
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Adieresis
ENCODING 196
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Aring
ENCODING 197
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
38
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR AE
ENCODING 198
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
6C
CC
CC
FE
CC
CC
CC
CC
CE
00
00
00
00
ENDCHAR
STARTCHAR Ccedilla
ENCODING 199
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
C2
66
3C
18
0C
38
00
ENDCHAR
STARTCHAR Egrave
ENCODING 200
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
18
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR Eacute
ENCODING 201
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR Ecircumflex
ENCODING 202
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR Edieresis
ENCODING 203
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR Igrave
ENCODING 204
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
18
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Iacute
ENCODING 205
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Icircumflex
ENCODING 206
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
3C
42
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Idieresis
ENCODING 207
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
66
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Eth
ENCODING 208
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
F6
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR Ntilde
ENCODING 209
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Ograve
ENCODING 210
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Oacute
ENCODING 211
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ocircumflex
ENCODING 212
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Otilde
ENCODING 213
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Odieresis
ENCODING 214
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR multiply
ENCODING 215
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
3C
18
3C
66
00
00
00
00
00
00
ENDCHAR
STARTCHAR Oslash
ENCODING 216
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7A
C4
CE
CE
D6
D6
E6
E6
46
BC
00
00
00
00
ENDCHAR
STARTCHAR Ugrave
ENCODING 217
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Uacute
ENCODING 218
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ucircumflex
ENCODING 219
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Udieresis
ENCODING 220
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Yacute
ENCODING 221
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Thorn
ENCODING 222
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
7C
66
66
66
66
7C
60
F0
00
00
00
00
ENDCHAR
STARTCHAR germandbls
ENCODING 223
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
6C
66
66
66
66
EC
00
00
00
00
ENDCHAR
STARTCHAR agrave
ENCODING 224
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR aacute
ENCODING 225
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
30
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR acircumflex
ENCODING 226
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR atilde
ENCODING 227
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR adieresis
ENCODING 228
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR aring
ENCODING 229
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR ae
ENCODING 230
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
76
36
7E
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR ccedilla
ENCODING 231
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR egrave
ENCODING 232
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR eacute
ENCODING 233
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR ecircumflex
ENCODING 234
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR edieresis
ENCODING 235
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR igrave
ENCODING 236
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
18
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR iacute
ENCODING 237
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR icircumflex
ENCODING 238
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR idieresis
ENCODING 239
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR eth
ENCODING 240
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
1C
3C
06
7E
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR ntilde
ENCODING 241
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR ograve
ENCODING 242
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR oacute
ENCODING 243
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR ocircumflex
ENCODING 244
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR otilde
ENCODING 245
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR odieresis
ENCODING 246
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR divide
ENCODING 247
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
00
7E
00
18
18
00
00
00
00
00
ENDCHAR
STARTCHAR oslash
ENCODING 248
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7A
C4
CE
D6
E6
46
BC
00
00
00
00
ENDCHAR
STARTCHAR ugrave
ENCODING 249
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uacute
ENCODING 250
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
30
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR ucircumflex
ENCODING 251
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR udieresis
ENCODING 252
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR yacute
ENCODING 253
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR thorn
ENCODING 254
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
7C
66
66
66
66
66
7C
60
60
F0
00
ENDCHAR
STARTCHAR ydieresis
ENCODING 255
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR Amacron
ENCODING 256
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR amacron
ENCODING 257
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Abreve
ENCODING 258
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR abreve
ENCODING 259
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Aogonek
ENCODING 260
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
6C
C6
C6
FE
C6
C6
C6
C6
0C
18
0E
00
ENDCHAR
STARTCHAR aogonek
ENCODING 261
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
0C
7C
CC
CC
CC
76
0C
18
0E
00
ENDCHAR
STARTCHAR Cacute
ENCODING 262
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
3C
66
C2
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR cacute
ENCODING 263
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ccircumflex
ENCODING 264
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
3C
66
C2
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR ccircumflex
ENCODING 265
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Cdotaccent
ENCODING 266
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
3C
66
C2
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR cdotaccent
ENCODING 267
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ccaron
ENCODING 268
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
3C
66
C2
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR ccaron
ENCODING 269
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Dcaron
ENCODING 270
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
F8
6C
66
66
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR dcaron
ENCODING 271
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
0C
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Dcroat
ENCODING 272
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
F6
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR dcroat
ENCODING 273
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
3E
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Emacron
ENCODING 274
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR emacron
ENCODING 275
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ebreve
ENCODING 276
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR ebreve
ENCODING 277
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Edotaccent
ENCODING 278
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR edotaccent
ENCODING 279
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Eogonek
ENCODING 280
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
66
62
68
78
68
62
66
FE
18
30
1C
00
ENDCHAR
STARTCHAR eogonek
ENCODING 281
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR Ecaron
ENCODING 282
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR ecaron
ENCODING 283
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Gcircumflex
ENCODING 284
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
3C
66
C2
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR gcircumflex
ENCODING 285
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR Gbreve
ENCODING 286
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
3C
66
C2
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR gbreve
ENCODING 287
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR Gdotaccent
ENCODING 288
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
3C
66
C2
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR gdotaccent
ENCODING 289
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR Gcommaaccent
ENCODING 290
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
DE
C6
C6
66
3A
00
18
18
30
ENDCHAR
STARTCHAR gcommaaccent
ENCODING 291
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
30
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR Hcircumflex
ENCODING 292
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR hcircumflex
ENCODING 293
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
E0
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR Hbar
ENCODING 294
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
FF
66
66
7E
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR hbar
ENCODING 295
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
F8
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR Itilde
ENCODING 296
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR itilde
ENCODING 297
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Imacron
ENCODING 298
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7E
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR imacron
ENCODING 299
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7E
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Ibreve
ENCODING 300
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
3C
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR ibreve
ENCODING 301
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
3C
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Iogonek
ENCODING 302
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
3C
18
18
18
18
18
18
18
3C
18
30
1C
00
ENDCHAR
STARTCHAR iogonek
ENCODING 303
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
38
18
18
18
18
18
3C
18
30
1C
00
ENDCHAR
STARTCHAR Idotaccent
ENCODING 304
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR dotlessi
ENCODING 305
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR IJ
ENCODING 306
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F7
63
63
63
63
63
63
7B
7B
EE
00
00
00
00
ENDCHAR
STARTCHAR ij
ENCODING 307
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
00
EE
66
66
66
66
66
F6
06
66
3C
00
ENDCHAR
STARTCHAR Jcircumflex
ENCODING 308
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
1C
22
1E
0C
0C
0C
0C
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR jcircumflex
ENCODING 309
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
04
0E
1B
00
0E
06
06
06
06
06
06
66
66
3C
00
ENDCHAR
STARTCHAR Kcommaaccent
ENCODING 310
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
18
18
30
ENDCHAR
STARTCHAR kcommaaccent
ENCODING 311
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
66
6C
78
78
6C
66
E6
00
18
18
30
ENDCHAR
STARTCHAR kgreenlandic
ENCODING 312
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
E6
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR Lacute
ENCODING 313
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
30
00
F0
60
60
60
60
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR lacute
ENCODING 314
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
38
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Lcommaaccent
ENCODING 315
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
60
60
60
62
66
FE
00
18
18
30
ENDCHAR
STARTCHAR lcommaaccent
ENCODING 316
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
3C
00
18
18
30
ENDCHAR
STARTCHAR Lcaron
ENCODING 317
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
F0
60
60
60
60
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR lcaron
ENCODING 318
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
38
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Ldot
ENCODING 319
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
66
66
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR ldot
ENCODING 320
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
30
30
30
36
36
30
30
30
78
00
00
00
00
ENDCHAR
STARTCHAR Lslash
ENCODING 321
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
78
E0
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR lslash
ENCODING 322
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
1E
78
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Nacute
ENCODING 323
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR nacute
ENCODING 324
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR Ncommaaccent
ENCODING 325
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
00
18
18
30
ENDCHAR
STARTCHAR ncommaaccent
ENCODING 326
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
00
18
18
30
ENDCHAR
STARTCHAR Ncaron
ENCODING 327
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
C6
E6
F6
FE
DE
CE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR ncaron
ENCODING 328
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR napostrophe
ENCODING 329
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
60
C0
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR Eng
ENCODING 330
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
06
06
1C
00
ENDCHAR
STARTCHAR eng
ENCODING 331
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
06
06
1C
00
ENDCHAR
STARTCHAR Omacron
ENCODING 332
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR omacron
ENCODING 333
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Obreve
ENCODING 334
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR obreve
ENCODING 335
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ohungarumlaut
ENCODING 336
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
CC
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR ohungarumlaut
ENCODING 337
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
CC
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR OE
ENCODING 338
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6E
D8
D8
D8
DE
D8
D8
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR oe
ENCODING 339
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
D6
D6
DE
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR Racute
ENCODING 340
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
FC
66
66
66
7C
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR racute
ENCODING 341
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
DC
76
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR Rcommaaccent
ENCODING 342
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
6C
66
66
66
E6
00
18
18
30
ENDCHAR
STARTCHAR rcommaaccent
ENCODING 343
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
66
60
60
60
F0
00
18
18
30
ENDCHAR
STARTCHAR Rcaron
ENCODING 344
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
FC
66
66
66
7C
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR rcaron
ENCODING 345
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
DC
76
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR Sacute
ENCODING 346
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
7C
C6
C6
60
38
0C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR sacute
ENCODING 347
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Scircumflex
ENCODING 348
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
7C
C6
C6
60
38
0C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR scircumflex
ENCODING 349
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Scedilla
ENCODING 350
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
C6
C6
60
38
0C
C6
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR scedilla
ENCODING 351
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
60
38
0C
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR Scaron
ENCODING 352
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
7C
C6
C6
60
38
0C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR scaron
ENCODING 353
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Tcommaaccent
ENCODING 354
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
18
0C
38
00
ENDCHAR
STARTCHAR tcommaaccent
ENCODING 355
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
18
0C
38
00
ENDCHAR
STARTCHAR Tcaron
ENCODING 356
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
7E
7E
5A
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR tcaron
ENCODING 357
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
10
30
FC
30
30
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR Tbar
ENCODING 358
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
3C
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR tbar
ENCODING 359
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
FC
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR Utilde
ENCODING 360
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR utilde
ENCODING 361
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Umacron
ENCODING 362
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR umacron
ENCODING 363
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
78
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Ubreve
ENCODING 364
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR ubreve
ENCODING 365
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
78
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Uring
ENCODING 366
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
38
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uring
ENCODING 367
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
38
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Uhungarumlaut
ENCODING 368
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
CC
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uhungarumlaut
ENCODING 369
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Uogonek
ENCODING 370
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uogonek
ENCODING 371
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
76
30
60
38
00
ENDCHAR
STARTCHAR Wcircumflex
ENCODING 372
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
00
00
00
ENDCHAR
STARTCHAR wcircumflex
ENCODING 373
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR Ycircumflex
ENCODING 374
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR ycircumflex
ENCODING 375
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR Ydieresis
ENCODING 376
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
66
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Zacute
ENCODING 377
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
FE
C6
8C
18
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR zacute
ENCODING 378
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
FE
CC
18
30
60
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR Zdotaccent
ENCODING 379
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
FE
C6
8C
18
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR zdotaccent
ENCODING 380
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
FE
CC
18
30
60
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR Zcaron
ENCODING 381
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
FE
C6
8C
18
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR zcaron
ENCODING 382
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
FE
CC
18
30
60
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR longs
ENCODING 383
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
64
60
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni0180
ENCODING 384
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
F8
60
78
6C
66
66
66
66
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0181
ENCODING 385
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
B3
B3
33
3E
33
33
33
33
7E
00
00
00
00
ENDCHAR
STARTCHAR uni0182
ENCODING 386
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
64
60
60
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni0183
ENCODING 387
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
62
60
78
6C
66
66
66
66
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0184
ENCODING 388
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
E6
E6
66
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni0185
ENCODING 389
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
E0
E0
78
6C
66
66
66
66
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0186
ENCODING 390
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
86
06
06
06
06
86
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni0187
ENCODING 391
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
03
3E
66
C2
C0
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0188
ENCODING 392
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
03
7E
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0189
ENCODING 393
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
F6
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR uni018A
ENCODING 394
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
B6
B3
33
33
33
33
33
36
7C
00
00
00
00
ENDCHAR
STARTCHAR uni018B
ENCODING 395
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
4C
0C
0C
7C
CC
CC
CC
CC
7E
00
00
00
00
ENDCHAR
STARTCHAR uni018C
ENCODING 396
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
4C
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni018D
ENCODING 397
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
7C
30
18
CC
78
00
ENDCHAR
STARTCHAR uni018E
ENCODING 398
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
CC
8C
2C
3C
2C
0C
8C
CC
FE
00
00
00
00
ENDCHAR
STARTCHAR uni018F
ENCODING 399
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
06
06
06
FE
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0190
ENCODING 400
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C2
C0
78
C0
C0
C2
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0191
ENCODING 401
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
60
60
60
60
60
C0
00
ENDCHAR
STARTCHAR florin
ENCODING 402
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
36
32
30
78
30
30
30
30
30
30
30
E0
00
ENDCHAR
STARTCHAR uni0193
ENCODING 403
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
03
3E
66
C2
C0
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR uni0194
ENCODING 404
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
6C
6C
6C
38
38
10
38
6C
38
00
00
ENDCHAR
STARTCHAR uni0195
ENCODING 405
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
F3
DB
DB
DB
DB
DB
CE
00
00
00
00
ENDCHAR
STARTCHAR uni0196
ENCODING 406
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
30
30
30
30
30
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR uni0197
ENCODING 407
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0198
ENCODING 408
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
6D
6C
78
70
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni0199
ENCODING 409
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
60
66
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni019A
ENCODING 410
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni019B
ENCODING 411
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C8
38
70
D0
38
38
6C
64
C6
C2
00
00
00
00
ENDCHAR
STARTCHAR uni019C
ENCODING 412
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D6
D6
D6
D6
D6
D6
D6
D6
FE
EC
00
00
00
00
ENDCHAR
STARTCHAR uni019D
ENCODING 413
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
76
7E
7E
6E
66
66
66
66
60
60
C0
00
ENDCHAR
STARTCHAR uni019E
ENCODING 414
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
06
06
06
00
ENDCHAR
STARTCHAR uni019F
ENCODING 415
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
FE
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Ohorn
ENCODING 416
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
03
7A
CC
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR ohorn
ENCODING 417
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
06
78
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni01A2
ENCODING 418
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
73
DF
DB
DB
DB
DB
DB
DB
DB
73
03
03
03
00
ENDCHAR
STARTCHAR uni01A3
ENCODING 419
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
73
DF
DB
DB
DB
DB
73
03
03
03
00
ENDCHAR
STARTCHAR uni01A4
ENCODING 420
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
B3
B3
33
3E
30
30
30
30
78
00
00
00
00
ENDCHAR
STARTCHAR uni01A5
ENCODING 421
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
60
7C
66
66
66
66
66
7C
60
60
F0
00
ENDCHAR
STARTCHAR uni01A6
ENCODING 422
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
7C
66
66
7C
78
6C
6C
E6
06
00
00
00
ENDCHAR
STARTCHAR uni01A7
ENCODING 423
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
0C
38
60
C0
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01A8
ENCODING 424
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
0C
38
60
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01A9
ENCODING 425
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
62
30
18
18
30
62
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR uni01AA
ENCODING 426
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D8
78
18
18
18
18
18
18
18
18
1B
0E
00
ENDCHAR
STARTCHAR uni01AB
ENCODING 427
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
0C
6C
38
00
ENDCHAR
STARTCHAR uni01AC
ENCODING 428
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
FE
9A
58
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni01AD
ENCODING 429
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
36
30
FC
30
30
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR uni01AE
ENCODING 430
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
18
18
18
0E
00
ENDCHAR
STARTCHAR Uhorn
ENCODING 431
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
03
CE
CC
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uhorn
ENCODING 432
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
06
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01B1
ENCODING 433
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
EE
6C
6C
6C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01B2
ENCODING 434
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
C6
C6
C6
C6
C6
C6
C6
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni01B3
ENCODING 435
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
63
B3
B3
33
1E
0C
0C
0C
0C
1E
00
00
00
00
ENDCHAR
STARTCHAR uni01B4
ENCODING 436
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
06
0D
CC
CC
CC
CC
CC
CC
7C
0C
18
F0
00
ENDCHAR
STARTCHAR uni01B5
ENCODING 437
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
86
0C
7E
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR uni01B6
ENCODING 438
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
FC
60
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR uni01B7
ENCODING 439
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
06
0C
18
30
7C
06
06
06
06
C6
7C
00
00
ENDCHAR
STARTCHAR uni01B8
ENCODING 440
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C0
60
30
18
7C
C0
C0
C0
C0
C6
7C
00
00
ENDCHAR
STARTCHAR uni01B9
ENCODING 441
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
C0
60
30
78
C0
C0
C0
C6
7C
00
ENDCHAR
STARTCHAR uni01BA
ENCODING 442
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
06
0C
18
3C
06
7C
C0
C6
7C
00
ENDCHAR
STARTCHAR uni01BB
ENCODING 443
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
06
0C
7E
30
60
C0
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR uni01BC
ENCODING 444
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
60
60
78
0C
06
06
06
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni01BD
ENCODING 445
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
60
78
0C
06
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni01BE
ENCODING 446
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
18
4C
6C
38
00
00
00
00
ENDCHAR
STARTCHAR uni01BF
ENCODING 447
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
6C
78
70
60
60
F0
00
ENDCHAR
STARTCHAR uni01C0
ENCODING 448
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni01C1
ENCODING 449
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
6C
6C
6C
6C
6C
6C
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR uni01C2
ENCODING 450
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
7E
18
7E
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni01C3
ENCODING 451
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
3C
3C
18
18
18
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni01C4
ENCODING 452
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1B
0E
04
F7
D9
D9
DA
DA
DA
DC
DC
F7
00
00
00
00
ENDCHAR
STARTCHAR uni01C5
ENCODING 453
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F5
DA
D8
DF
D9
DA
DA
DA
DC
F7
00
00
00
00
ENDCHAR
STARTCHAR uni01C6
ENCODING 454
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3D
1A
18
7F
D9
DA
DA
DA
DC
6F
00
00
00
00
ENDCHAR
STARTCHAR uni01C7
ENCODING 455
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C7
C3
C3
C3
C3
C3
C3
C3
CB
F6
00
00
00
00
ENDCHAR
STARTCHAR uni01C8
ENCODING 456
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F3
63
60
67
63
63
63
67
6F
FF
03
1B
0E
00
ENDCHAR
STARTCHAR uni01C9
ENCODING 457
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E3
63
60
67
63
63
63
63
63
F3
03
33
1E
00
ENDCHAR
STARTCHAR uni01CA
ENCODING 458
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
FB
FB
FB
DB
DB
DB
DB
DE
00
00
00
00
ENDCHAR
STARTCHAR uni01CB
ENCODING 459
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
F8
FF
FB
FB
DB
DB
DB
DB
03
33
1E
00
ENDCHAR
STARTCHAR uni01CC
ENCODING 460
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
00
B7
DB
DB
DB
DB
DB
DB
03
33
1E
00
ENDCHAR
STARTCHAR uni01CD
ENCODING 461
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni01CE
ENCODING 462
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01CF
ENCODING 463
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni01D0
ENCODING 464
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni01D1
ENCODING 465
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01D2
ENCODING 466
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01D3
ENCODING 467
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01D4
ENCODING 468
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01D5
ENCODING 469
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
00
6C
00
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01D6
ENCODING 470
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
78
00
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01D7
ENCODING 471
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
10
6C
00
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01D8
ENCODING 472
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
30
00
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01D9
ENCODING 473
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
28
10
6C
00
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01DA
ENCODING 474
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
78
30
00
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01DB
ENCODING 475
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
10
6C
00
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01DC
ENCODING 476
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01DD
ENCODING 477
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
06
FE
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni01DE
ENCODING 478
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
00
6C
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni01DF
ENCODING 479
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01E0
ENCODING 480
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
30
30
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni01E1
ENCODING 481
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
30
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni01E2
ENCODING 482
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
3E
6C
CC
CC
FE
CC
CC
CC
CE
00
00
00
00
ENDCHAR
STARTCHAR uni01E3
ENCODING 483
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
CC
76
36
7E
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR uni01E4
ENCODING 484
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
DE
C6
DF
66
3A
00
00
00
00
ENDCHAR
STARTCHAR uni01E5
ENCODING 485
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
CC
CC
CC
CC
7C
0C
3E
CC
78
00
ENDCHAR
STARTCHAR Gcaron
ENCODING 486
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
3C
66
C2
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR gcaron
ENCODING 487
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR uni01E8
ENCODING 488
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
E6
66
66
6C
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni01E9
ENCODING 489
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
E0
60
66
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni01EA
ENCODING 490
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
C6
C6
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uni01EB
ENCODING 491
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uni01EC
ENCODING 492
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uni01ED
ENCODING 493
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
7C
C6
C6
C6
C6
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uni01EE
ENCODING 494
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
FE
0C
18
30
7C
06
06
06
06
C6
7C
00
00
ENDCHAR
STARTCHAR uni01EF
ENCODING 495
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
FE
06
0C
18
3C
06
06
06
C6
7C
00
ENDCHAR
STARTCHAR uni01F0
ENCODING 496
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1B
0E
04
00
0E
06
06
06
06
06
06
66
66
3C
00
ENDCHAR
STARTCHAR uni01F1
ENCODING 497
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F7
D9
D9
DA
DA
DA
DA
DC
DC
F7
00
00
00
00
ENDCHAR
STARTCHAR uni01F2
ENCODING 498
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
D8
D8
DF
D9
DA
DA
DA
DC
F7
00
00
00
00
ENDCHAR
STARTCHAR uni01F3
ENCODING 499
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
7F
D9
DA
DA
DA
DC
6F
00
00
00
00
ENDCHAR
STARTCHAR uni01F4
ENCODING 500
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
3C
66
C2
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR uni01F5
ENCODING 501
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
30
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR uni01F6
ENCODING 502
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D8
D8
D8
DB
FB
DB
DB
DB
DB
CE
00
00
00
00
ENDCHAR
STARTCHAR uni01F7
ENCODING 503
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
66
6C
78
70
60
60
60
60
E0
00
ENDCHAR
STARTCHAR uni01F8
ENCODING 504
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni01F9
ENCODING 505
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
18
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR Aringacute
ENCODING 506
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
38
6C
38
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR aringacute
ENCODING 507
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
38
6C
38
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR AEacute
ENCODING 508
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
3E
6C
CC
CC
FE
CC
CC
CC
CE
00
00
00
00
ENDCHAR
STARTCHAR aeacute
ENCODING 509
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
CC
76
36
7E
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR Oslashacute
ENCODING 510
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
7A
C4
CE
CE
D6
E6
E6
46
BC
00
00
00
00
ENDCHAR
STARTCHAR oslashacute
ENCODING 511
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7A
C4
CE
D6
E6
46
BC
00
00
00
00
ENDCHAR
STARTCHAR uni0200
ENCODING 512
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni0201
ENCODING 513
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0202
ENCODING 514
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni0203
ENCODING 515
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0204
ENCODING 516
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni0205
ENCODING 517
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0206
ENCODING 518
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni0207
ENCODING 519
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0208
ENCODING 520
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0209
ENCODING 521
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni020A
ENCODING 522
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
3C
66
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni020B
ENCODING 523
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni020C
ENCODING 524
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni020D
ENCODING 525
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni020E
ENCODING 526
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni020F
ENCODING 527
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0210
ENCODING 528
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
FC
66
66
66
7C
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni0211
ENCODING 529
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
DC
76
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni0212
ENCODING 530
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
00
FC
66
66
66
7C
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni0213
ENCODING 531
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
00
DC
76
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni0214
ENCODING 532
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0215
ENCODING 533
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0216
ENCODING 534
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
00
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0217
ENCODING 535
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR Scommaaccent
ENCODING 536
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
60
38
0C
06
C6
C6
7C
00
18
18
30
ENDCHAR
STARTCHAR scommaaccent
ENCODING 537
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
60
38
0C
C6
7C
00
18
18
30
ENDCHAR
STARTCHAR Tcommaaccent
ENCODING 538
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
00
18
18
30
ENDCHAR
STARTCHAR tcommaaccent
ENCODING 539
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
00
18
18
30
ENDCHAR
STARTCHAR uni021C
ENCODING 540
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
86
06
1C
74
06
06
06
06
1C
F0
00
00
ENDCHAR
STARTCHAR uni021D
ENCODING 541
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
0E
3C
06
06
1C
F0
00
00
ENDCHAR
STARTCHAR uni021E
ENCODING 542
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
C6
C6
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni021F
ENCODING 543
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
E0
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni0222
ENCODING 546
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
C6
C6
C6
7C
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0223
ENCODING 547
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
66
66
66
3C
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0224
ENCODING 548
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
86
0C
18
30
60
C0
C0
FC
06
0C
00
00
ENDCHAR
STARTCHAR uni0225
ENCODING 549
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
30
60
C0
FC
06
0C
00
00
ENDCHAR
STARTCHAR uni0226
ENCODING 550
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni0227
ENCODING 551
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0228
ENCODING 552
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
18
0C
38
00
ENDCHAR
STARTCHAR uni0229
ENCODING 553
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR uni022A
ENCODING 554
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
00
6C
00
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni022B
ENCODING 555
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
6C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni022C
ENCODING 556
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
00
72
9C
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni022D
ENCODING 557
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
00
76
DC
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni022E
ENCODING 558
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni022F
ENCODING 559
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0230
ENCODING 560
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
00
30
00
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0231
ENCODING 561
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
30
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0232
ENCODING 562
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
3C
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0233
ENCODING 563
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni0250
ENCODING 592
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
7C
60
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0251
ENCODING 593
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
74
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0252
ENCODING 594
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
5C
00
00
00
00
ENDCHAR
STARTCHAR uni0253
ENCODING 595
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
60
78
6C
66
66
66
66
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0254
ENCODING 596
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0255
ENCODING 597
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
DC
E6
7C
80
00
00
00
ENDCHAR
STARTCHAR uni0256
ENCODING 598
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
7C
0C
0D
06
00
ENDCHAR
STARTCHAR uni0257
ENCODING 599
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
0D
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0258
ENCODING 600
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0259
ENCODING 601
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
06
FE
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni025A
ENCODING 602
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3B
6C
8E
16
26
6C
38
00
00
00
00
ENDCHAR
STARTCHAR uni025B
ENCODING 603
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
78
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni025C
ENCODING 604
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
3C
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni025D
ENCODING 605
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7A
CD
0D
38
0C
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni025E
ENCODING 606
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
DC
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni025F
ENCODING 607
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0E
06
06
1F
06
06
06
66
66
3C
00
ENDCHAR
STARTCHAR uni0260
ENCODING 608
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
06
0D
7C
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR uni0261
ENCODING 609
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR uni0262
ENCODING 610
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
CE
C6
C6
7A
00
00
00
00
ENDCHAR
STARTCHAR uni0263
ENCODING 611
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
46
6C
2C
2C
38
18
18
18
18
00
ENDCHAR
STARTCHAR uni0264
ENCODING 612
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C2
64
28
38
38
6C
38
00
00
00
00
ENDCHAR
STARTCHAR uni0265
ENCODING 613
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CE
CC
CC
CC
CC
DC
6C
0C
0C
0E
00
ENDCHAR
STARTCHAR uni0266
ENCODING 614
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni0267
ENCODING 615
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
60
6C
76
66
66
66
66
E6
06
06
1C
00
ENDCHAR
STARTCHAR uni0268
ENCODING 616
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
38
18
18
3C
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0269
ENCODING 617
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
18
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR uni026A
ENCODING 618
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni026B
ENCODING 619
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
7B
DE
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni026C
ENCODING 620
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
78
58
3E
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni026D
ENCODING 621
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
18
18
1B
0E
00
ENDCHAR
STARTCHAR uni026E
ENCODING 622
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
7F
63
66
6C
7E
63
F3
03
33
1E
00
ENDCHAR
STARTCHAR uni026F
ENCODING 623
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
D6
D6
D6
D6
FE
6E
00
00
00
00
ENDCHAR
STARTCHAR uni0270
ENCODING 624
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
D6
D6
D6
D6
FE
6E
06
06
06
00
ENDCHAR
STARTCHAR uni0271
ENCODING 625
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
EC
FE
D6
D6
D6
D6
C6
06
06
1C
00
ENDCHAR
STARTCHAR uni0272
ENCODING 626
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
60
60
C0
00
ENDCHAR
STARTCHAR uni0273
ENCODING 627
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
06
06
03
00
ENDCHAR
STARTCHAR uni0274
ENCODING 628
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
E6
F6
FE
DE
CE
C6
00
00
00
00
ENDCHAR
STARTCHAR uni0275
ENCODING 629
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
FE
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0276
ENCODING 630
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6E
D8
D8
DE
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR uni0277
ENCODING 631
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
C6
D6
D6
D6
D6
6C
00
00
00
00
ENDCHAR
STARTCHAR uni0278
ENCODING 632
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
10
7C
D6
D6
D6
D6
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR uni0279
ENCODING 633
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
1E
0C
0C
0C
CC
DC
76
00
00
00
00
ENDCHAR
STARTCHAR uni027A
ENCODING 634
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
0C
0C
0C
0C
0C
0C
CC
DC
76
00
00
00
00
ENDCHAR
STARTCHAR uni027B
ENCODING 635
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
1E
0C
0C
0C
CC
DC
6C
0C
0D
06
00
ENDCHAR
STARTCHAR uni027C
ENCODING 636
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
66
60
60
60
60
60
60
F0
00
ENDCHAR
STARTCHAR uni027D
ENCODING 637
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
66
60
60
60
60
60
6C
38
00
ENDCHAR
STARTCHAR uni027E
ENCODING 638
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni027F
ENCODING 639
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
CC
CC
0C
0C
0C
1E
00
00
00
00
ENDCHAR
STARTCHAR uni0280
ENCODING 640
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FC
66
66
7C
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni0281
ENCODING 641
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
E6
66
6C
7C
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni0282
ENCODING 642
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
60
38
0C
C6
FC
C0
D8
70
00
ENDCHAR
STARTCHAR uni0283
ENCODING 643
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
1B
19
18
18
18
18
18
18
18
98
D8
70
00
ENDCHAR
STARTCHAR uni0284
ENCODING 644
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
1B
19
18
18
18
18
18
18
3C
98
D8
70
00
ENDCHAR
STARTCHAR uni0285
ENCODING 645
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
D8
18
18
18
18
1B
0E
00
00
00
00
ENDCHAR
STARTCHAR uni0286
ENCODING 646
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0E
1B
18
18
18
18
18
18
7E
D8
70
00
ENDCHAR
STARTCHAR uni0287
ENCODING 647
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D8
18
18
18
18
7E
18
18
10
00
00
00
00
ENDCHAR
STARTCHAR uni0288
ENCODING 648
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
30
30
30
36
1C
00
ENDCHAR
STARTCHAR uni0289
ENCODING 649
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
FF
66
66
3B
00
00
00
00
ENDCHAR
STARTCHAR uni028A
ENCODING 650
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
EE
6C
6C
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni028B
ENCODING 651
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni028C
ENCODING 652
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
3C
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni028D
ENCODING 653
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
FE
D6
D6
D6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni028E
ENCODING 654
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
60
C0
FC
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni028F
ENCODING 655
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
3C
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0290
ENCODING 656
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
30
60
C6
FE
06
06
03
00
ENDCHAR
STARTCHAR uni0291
ENCODING 657
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
30
66
CB
FE
10
00
00
00
ENDCHAR
STARTCHAR uni0292
ENCODING 658
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
06
0C
18
3C
06
06
06
C6
7C
00
ENDCHAR
STARTCHAR uni0293
ENCODING 659
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
06
0C
18
3C
06
06
7E
C7
7C
00
ENDCHAR
STARTCHAR uni0294
ENCODING 660
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
06
1C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0295
ENCODING 661
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C0
70
30
30
30
30
78
00
00
00
00
ENDCHAR
STARTCHAR uni0296
ENCODING 662
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
1C
06
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0297
ENCODING 663
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C0
C0
C0
C6
7C
00
ENDCHAR
STARTCHAR uni0298
ENCODING 664
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C3
C3
DB
DB
C3
C3
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0299
ENCODING 665
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FC
66
66
7C
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni029A
ENCODING 666
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
76
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni029B
ENCODING 667
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
03
7E
C6
C0
CE
C6
C6
7A
00
00
00
00
ENDCHAR
STARTCHAR uni029C
ENCODING 668
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR j
ENCODING 669
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
0C
00
1C
0C
0C
0C
0C
0C
0C
7E
CC
78
00
ENDCHAR
STARTCHAR uni029D
ENCODING 670
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CE
CC
6C
3C
3C
6C
CC
0C
0C
0E
00
ENDCHAR
STARTCHAR uni029E
ENCODING 671
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F0
60
60
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni029F
ENCODING 672
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
06
0D
7C
CC
CC
CC
CC
CC
7C
0C
0C
1E
00
ENDCHAR
STARTCHAR uni02A0
ENCODING 673
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
06
1C
18
7E
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni02A1
ENCODING 674
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C0
70
30
FC
30
30
78
00
00
00
00
ENDCHAR
STARTCHAR uni02A2
ENCODING 675
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
7F
D9
DA
DA
DA
DC
6F
00
00
00
00
ENDCHAR
STARTCHAR uni02A3
ENCODING 676
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
7F
DB
DB
DE
DE
DB
6B
03
1B
0E
00
ENDCHAR
STARTCHAR uni02A4
ENCODING 677
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
7F
D9
DA
DA
DB
DD
6F
04
00
00
00
ENDCHAR
STARTCHAR uni02A5
ENCODING 678
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
60
60
F6
6D
6C
66
63
6B
36
00
00
00
00
ENDCHAR
STARTCHAR uni02A6
ENCODING 679
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
26
6D
6C
FC
6C
6C
6C
6C
6C
3C
0C
2C
18
00
ENDCHAR
STARTCHAR uni02A7
ENCODING 680
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
60
60
F6
6D
6C
6C
6E
6D
36
00
00
00
00
ENDCHAR
STARTCHAR uni02A8
ENCODING 681
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D8
C0
FE
DB
DB
DB
DB
DB
DB
03
03
0E
00
ENDCHAR
STARTCHAR uni02A9
ENCODING 682
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
66
6D
6C
66
63
6B
F6
00
00
00
00
ENDCHAR
STARTCHAR uni02AA
ENCODING 683
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
6F
6B
63
66
6C
6D
FF
00
00
00
00
ENDCHAR
STARTCHAR uni02AB
ENCODING 684
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
D6
7C
6C
28
C6
D6
7C
6C
28
00
00
00
00
ENDCHAR
STARTCHAR uni02AC
ENCODING 685
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
C6
C6
00
00
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni02B0
ENCODING 688
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
F0
D8
D8
D8
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B1
ENCODING 689
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
C0
F0
D8
D8
D8
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B2
ENCODING 690
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
00
38
18
18
D8
70
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B3
ENCODING 691
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
B0
D8
C0
C0
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B4
ENCODING 692
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
18
D8
68
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B5
ENCODING 693
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
18
D8
68
0C
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B6
ENCODING 694
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
D8
D8
F0
D8
D8
F0
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B7
ENCODING 695
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C6
D6
7C
6C
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B8
ENCODING 696
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
D8
D8
78
18
70
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02B9
ENCODING 697
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
60
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02BA
ENCODING 698
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
36
6C
D8
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02BB
ENCODING 699
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57929
ENCODING 700
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii64937
ENCODING 701
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
30
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02BE
ENCODING 702
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
0C
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02BF
ENCODING 703
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
60
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C0
ENCODING 704
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D8
18
30
30
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C1
ENCODING 705
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D8
C0
60
60
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C2
ENCODING 706
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
70
C0
70
18
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C3
ENCODING 707
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
70
18
70
C0
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C4
ENCODING 708
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
20
20
70
70
D8
D8
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C5
ENCODING 709
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
D8
D8
70
70
20
20
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR circumflex
ENCODING 710
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR caron
ENCODING 711
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02C8
ENCODING 712
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR macron
ENCODING 713
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02CA
ENCODING 714
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02CB
ENCODING 715
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02CC
ENCODING 716
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
18
18
00
ENDCHAR
STARTCHAR uni02CD
ENCODING 717
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
7C
00
00
ENDCHAR
STARTCHAR uni02CE
ENCODING 718
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
18
0C
00
ENDCHAR
STARTCHAR uni02CF
ENCODING 719
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
30
60
00
ENDCHAR
STARTCHAR breve
ENCODING 728
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR dotaccent
ENCODING 729
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR ring
ENCODING 730
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
38
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR ogonek
ENCODING 731
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
30
1C
00
ENDCHAR
STARTCHAR tilde
ENCODING 732
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR hungarumlaut
ENCODING 733
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
CC
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni02EE
ENCODING 750
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
6C
6C
48
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR gravecomb
ENCODING 768
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR acutecomb
ENCODING 769
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR tildecomb
ENCODING 771
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
34
58
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR hookabovecomb
ENCODING 777
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
18
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0312
ENCODING 786
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0313
ENCODING 787
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0314
ENCODING 788
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
30
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR dotbelowcomb
ENCODING 803
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
18
18
00
ENDCHAR
STARTCHAR uni0340
ENCODING 832
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
60
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0341
ENCODING 833
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
06
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0374
ENCODING 884
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
20
40
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0375
ENCODING 885
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
10
20
60
00
00
00
ENDCHAR
STARTCHAR uni037A
ENCODING 890
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
30
34
18
00
ENDCHAR
STARTCHAR uni037E
ENCODING 894
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
00
00
00
18
18
30
00
00
00
00
ENDCHAR
STARTCHAR tonos
ENCODING 900
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR dieresistonos
ENCODING 901
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
6C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR Alphatonos
ENCODING 902
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
10
38
6C
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR anoteleia
ENCODING 903
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
18
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR Epsilontonos
ENCODING 904
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
3E
32
30
34
3C
34
30
30
32
3E
00
00
00
00
ENDCHAR
STARTCHAR Etatonos
ENCODING 905
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
33
33
33
33
3F
33
33
33
33
33
00
00
00
00
ENDCHAR
STARTCHAR Iotatonos
ENCODING 906
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
3C
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Omicrontonos
ENCODING 908
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
3C
66
66
66
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR Upsilontonos
ENCODING 910
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
66
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Omegatonos
ENCODING 911
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
3E
63
63
63
63
63
36
36
36
77
00
00
00
00
ENDCHAR
STARTCHAR iotadieresistonos
ENCODING 912
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
6C
00
38
18
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR Alpha
ENCODING 913
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
6C
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Beta
ENCODING 914
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR Gamma
ENCODING 915
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
60
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR Delta
ENCODING 916
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
38
38
6C
6C
C6
C6
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR Epsilon
ENCODING 917
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR Zeta
ENCODING 918
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
86
0C
18
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR Eta
ENCODING 919
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Theta
ENCODING 920
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
FE
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Iota
ENCODING 921
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Kappa
ENCODING 922
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR Lambda
ENCODING 923
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
38
38
6C
6C
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Mu
ENCODING 924
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Nu
ENCODING 925
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Xi
ENCODING 926
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
82
44
7C
44
00
82
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR Omicron
ENCODING 927
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR Pi
ENCODING 928
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
C6
C6
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Rho
ENCODING 929
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR Sigma
ENCODING 931
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
62
30
18
18
30
62
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR Tau
ENCODING 932
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Upsilon
ENCODING 933
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Phi
ENCODING 934
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
7C
D6
D6
D6
D6
D6
7C
10
10
00
00
00
00
ENDCHAR
STARTCHAR Chi
ENCODING 935
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
6C
7C
38
38
7C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR Psi
ENCODING 936
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
92
D6
D6
D6
D6
D6
7C
10
10
00
00
00
00
ENDCHAR
STARTCHAR Omega
ENCODING 937
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
6C
6C
6C
EE
00
00
00
00
ENDCHAR
STARTCHAR Iotadieresis
ENCODING 938
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
66
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR Upsilondieresis
ENCODING 939
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
66
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR alphatonos
ENCODING 940
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR epsilontonos
ENCODING 941
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
C0
78
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR etatonos
ENCODING 942
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
DC
66
66
66
66
66
66
06
06
06
00
ENDCHAR
STARTCHAR iotatonos
ENCODING 943
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
38
18
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR upsilondieresistonos
ENCODING 944
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
6C
00
CC
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR alpha
ENCODING 945
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR beta
ENCODING 946
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
6C
66
66
66
66
6C
60
60
60
00
ENDCHAR
STARTCHAR gamma
ENCODING 947
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
46
6C
2C
2C
38
18
18
18
18
00
ENDCHAR
STARTCHAR delta
ENCODING 948
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
30
18
7C
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR epsilon
ENCODING 949
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
78
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR zeta
ENCODING 950
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
46
7C
18
30
60
60
C0
C0
C0
7C
06
06
1C
00
ENDCHAR
STARTCHAR eta
ENCODING 951
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
06
06
06
00
ENDCHAR
STARTCHAR theta
ENCODING 952
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
7E
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR iota
ENCODING 953
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
18
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR kappa
ENCODING 954
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
E6
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR lambda
ENCODING 955
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
20
30
10
38
38
6C
64
C6
C2
00
00
00
00
ENDCHAR
STARTCHAR mu
ENCODING 956
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
F6
C0
C0
C0
00
ENDCHAR
STARTCHAR nu
ENCODING 957
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
66
6C
3C
38
10
00
00
00
00
ENDCHAR
STARTCHAR xi
ENCODING 958
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
3C
30
60
3C
60
C0
C0
C0
7C
06
06
1C
00
ENDCHAR
STARTCHAR omicron
ENCODING 959
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR pi
ENCODING 960
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
6C
6C
6C
6C
6C
66
00
00
00
00
ENDCHAR
STARTCHAR rho
ENCODING 961
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
66
66
66
66
7C
60
60
60
00
ENDCHAR
STARTCHAR sigma1
ENCODING 962
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
7C
06
06
1C
00
00
ENDCHAR
STARTCHAR sigma
ENCODING 963
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR tau
ENCODING 964
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
18
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR upsilon
ENCODING 965
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR phi
ENCODING 966
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
D6
D6
D6
D6
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR chi
ENCODING 967
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
86
46
2C
2C
18
30
68
68
C4
C2
00
ENDCHAR
STARTCHAR psi
ENCODING 968
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
92
D6
D6
D6
D6
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR omega
ENCODING 969
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
C6
D6
D6
D6
D6
6C
00
00
00
00
ENDCHAR
STARTCHAR iotadieresis
ENCODING 970
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
00
38
18
18
18
18
18
0E
00
00
00
00
ENDCHAR
STARTCHAR upsilondieresis
ENCODING 971
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
CC
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR omicrontonos
ENCODING 972
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR upsilontonos
ENCODING 973
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
CC
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR omegatonos
ENCODING 974
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
6C
C6
D6
D6
D6
D6
6C
00
00
00
00
ENDCHAR
STARTCHAR uni03D0
ENCODING 976
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
6C
7C
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR theta1
ENCODING 977
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
36
1E
C6
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR Upsilon1
ENCODING 978
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C2
65
24
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni03D3
ENCODING 979
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
C0
21
32
12
1C
0C
0C
0C
0C
0C
1E
00
00
00
00
ENDCHAR
STARTCHAR uni03D4
ENCODING 980
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C2
65
24
38
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR phi1
ENCODING 981
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
10
7C
D6
D6
D6
D6
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR omega1
ENCODING 982
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
6C
C6
D6
D6
D6
6C
00
00
00
00
ENDCHAR
STARTCHAR uni03D7
ENCODING 983
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
46
A6
2C
38
68
CA
C4
0C
18
00
00
ENDCHAR
STARTCHAR uni03DA
ENCODING 986
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
60
3C
06
06
1C
00
00
ENDCHAR
STARTCHAR uni03DB
ENCODING 987
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
C0
C0
C0
C0
C0
7C
06
06
1C
00
ENDCHAR
STARTCHAR uni03DC
ENCODING 988
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
60
78
68
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni03DD
ENCODING 989
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
32
30
30
3C
34
30
30
30
30
00
ENDCHAR
STARTCHAR uni03DE
ENCODING 990
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
30
30
60
63
FF
C6
06
0C
0C
06
00
00
00
00
ENDCHAR
STARTCHAR uni03DF
ENCODING 991
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
60
60
FE
FE
0C
0C
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni03E0
ENCODING 992
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
AC
26
26
0B
0B
1B
1B
1B
1B
03
02
04
00
ENDCHAR
STARTCHAR uni03E1
ENCODING 993
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C0
60
30
18
28
4C
14
24
06
02
02
00
ENDCHAR
STARTCHAR uni03E2
ENCODING 994
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
DB
DB
DB
DB
DB
DB
DB
6D
03
3E
00
00
ENDCHAR
STARTCHAR uni03E3
ENCODING 995
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DB
DB
DB
DB
DB
DB
6D
03
7E
00
00
ENDCHAR
STARTCHAR uni03E4
ENCODING 996
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
D6
C6
C6
C6
7E
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni03E5
ENCODING 997
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
36
66
66
66
66
3E
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni03E6
ENCODING 998
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
C0
FC
C6
C6
C6
C6
C6
06
76
9C
00
ENDCHAR
STARTCHAR uni03E7
ENCODING 999
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
7C
D6
66
06
06
66
BC
00
00
00
00
ENDCHAR
STARTCHAR uni03E8
ENCODING 1000
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
06
3C
60
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni03E9
ENCODING 1001
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
26
1C
70
C0
C2
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni03EA
ENCODING 1002
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
68
38
30
38
38
4C
4C
86
FE
00
00
00
00
ENDCHAR
STARTCHAR uni03EB
ENCODING 1003
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
64
BA
30
38
28
4C
7C
00
00
00
00
ENDCHAR
STARTCHAR uni03EC
ENCODING 1004
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
C0
CC
D6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni03ED
ENCODING 1005
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
C0
DC
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni03EE
ENCODING 1006
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
7E
99
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni03EF
ENCODING 1007
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
1C
18
7E
58
18
18
18
38
18
00
00
00
00
ENDCHAR
STARTCHAR uni03F0
ENCODING 1008
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
46
A6
2C
38
68
CA
C4
00
00
00
00
ENDCHAR
STARTCHAR uni03F1
ENCODING 1009
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
FC
C0
60
3C
06
00
ENDCHAR
STARTCHAR uni03F2
ENCODING 1010
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni03F3
ENCODING 1011
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
06
00
0E
06
06
06
06
06
06
66
66
3C
00
ENDCHAR
STARTCHAR uni0400
ENCODING 1024
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
18
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR afii10023
ENCODING 1025
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR afii10051
ENCODING 1026
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
B2
30
3E
33
33
33
33
33
33
03
06
00
00
ENDCHAR
STARTCHAR afii10052
ENCODING 1027
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
FE
66
62
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR afii10053
ENCODING 1028
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
F8
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10054
ENCODING 1029
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
60
38
0C
06
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10055
ENCODING 1030
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10056
ENCODING 1031
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
66
00
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10057
ENCODING 1032
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
0C
0C
0C
0C
0C
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR afii10058
ENCODING 1033
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
D8
D8
D8
DE
DB
DB
DB
DB
DE
00
00
00
00
ENDCHAR
STARTCHAR afii10059
ENCODING 1034
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D8
D8
D8
D8
FE
DB
DB
DB
DB
DE
00
00
00
00
ENDCHAR
STARTCHAR afii10060
ENCODING 1035
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
B2
30
3E
33
33
33
33
33
33
00
00
00
00
ENDCHAR
STARTCHAR afii10061
ENCODING 1036
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
E6
66
66
6C
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni040D
ENCODING 1037
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
18
00
C6
C6
CE
DE
FE
F6
E6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10062
ENCODING 1038
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
C6
C6
C6
C6
7E
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10145
ENCODING 1039
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
C6
C6
FE
38
10
10
00
ENDCHAR
STARTCHAR afii10017
ENCODING 1040
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
6C
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10018
ENCODING 1041
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
60
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR afii10019
ENCODING 1042
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR afii10020
ENCODING 1043
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
60
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR afii10021
ENCODING 1044
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
6C
6C
6C
6C
6C
6C
6C
6C
FE
C6
82
00
00
ENDCHAR
STARTCHAR afii10022
ENCODING 1045
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR afii10024
ENCODING 1046
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D6
D6
D6
7C
38
7C
D6
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR afii10025
ENCODING 1047
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
86
06
3C
06
06
86
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10026
ENCODING 1048
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
CE
DE
FE
F6
E6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10027
ENCODING 1049
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
C6
C6
C6
CE
DE
FE
F6
E6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10028
ENCODING 1050
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR afii10029
ENCODING 1051
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
66
66
66
66
66
66
66
66
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10030
ENCODING 1052
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10031
ENCODING 1053
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10032
ENCODING 1054
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10033
ENCODING 1055
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
C6
C6
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10034
ENCODING 1056
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR afii10035
ENCODING 1057
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10036
ENCODING 1058
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10037
ENCODING 1059
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
7E
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10038
ENCODING 1060
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
7C
D6
D6
D6
D6
D6
7C
10
10
00
00
00
00
ENDCHAR
STARTCHAR afii10039
ENCODING 1061
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
6C
7C
38
38
7C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10040
ENCODING 1062
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
CC
CC
CC
CC
CC
CC
CC
CC
FE
06
02
00
00
ENDCHAR
STARTCHAR afii10041
ENCODING 1063
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
7E
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR afii10042
ENCODING 1064
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
D6
D6
D6
D6
D6
D6
D6
D6
FE
00
00
00
00
ENDCHAR
STARTCHAR afii10043
ENCODING 1065
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
D6
D6
D6
D6
D6
D6
D6
D6
FF
03
01
00
00
ENDCHAR
STARTCHAR afii10044
ENCODING 1066
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
B0
B0
30
3C
36
36
36
36
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10045
ENCODING 1067
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C3
C3
C3
C3
F3
DB
DB
DB
DB
F3
00
00
00
00
ENDCHAR
STARTCHAR afii10046
ENCODING 1068
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR afii10047
ENCODING 1069
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
86
06
3E
06
06
86
CC
78
00
00
00
00
ENDCHAR
STARTCHAR afii10048
ENCODING 1070
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
9C
B6
B6
B6
F6
B6
B6
B6
B6
9C
00
00
00
00
ENDCHAR
STARTCHAR afii10049
ENCODING 1071
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
CC
CC
CC
7C
6C
6C
6C
6C
CE
00
00
00
00
ENDCHAR
STARTCHAR afii10065
ENCODING 1072
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR afii10066
ENCODING 1073
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
7C
C0
C0
FC
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10067
ENCODING 1074
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FC
66
66
7C
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR afii10068
ENCODING 1075
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
66
62
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR afii10069
ENCODING 1076
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
6C
6C
6C
6C
6C
FE
C6
82
00
00
ENDCHAR
STARTCHAR afii10070
ENCODING 1077
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10072
ENCODING 1078
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D6
D6
D6
7C
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR afii10073
ENCODING 1079
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
3C
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10074
ENCODING 1080
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
CE
DE
FE
F6
E6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10075
ENCODING 1081
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
C6
CE
DE
FE
F6
E6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10076
ENCODING 1082
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
E6
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR afii10077
ENCODING 1083
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3E
66
66
66
66
66
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10078
ENCODING 1084
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
EE
FE
FE
D6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10079
ENCODING 1085
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10080
ENCODING 1086
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10081
ENCODING 1087
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10082
ENCODING 1088
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
7C
60
60
F0
00
ENDCHAR
STARTCHAR afii10083
ENCODING 1089
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10084
ENCODING 1090
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
5A
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10085
ENCODING 1091
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR afii10086
ENCODING 1092
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
7C
D6
D6
D6
D6
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR afii10087
ENCODING 1093
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
6C
38
38
38
6C
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10088
ENCODING 1094
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
FE
06
02
00
00
ENDCHAR
STARTCHAR afii10089
ENCODING 1095
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
7E
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR afii10090
ENCODING 1096
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
D6
D6
D6
D6
D6
FE
00
00
00
00
ENDCHAR
STARTCHAR afii10091
ENCODING 1097
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
D6
D6
D6
D6
D6
FF
03
01
00
00
ENDCHAR
STARTCHAR afii10092
ENCODING 1098
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F8
B0
30
3C
36
36
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10093
ENCODING 1099
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C3
C3
C3
F3
DB
DB
F3
00
00
00
00
ENDCHAR
STARTCHAR afii10094
ENCODING 1100
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F0
60
60
7C
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR afii10095
ENCODING 1101
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
3E
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10096
ENCODING 1102
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
9C
B6
B6
F6
B6
B6
9C
00
00
00
00
ENDCHAR
STARTCHAR afii10097
ENCODING 1103
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
CC
CC
7C
6C
6C
CE
00
00
00
00
ENDCHAR
STARTCHAR uni0450
ENCODING 1104
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10071
ENCODING 1105
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10099
ENCODING 1106
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
F8
60
6C
76
66
66
66
66
E6
06
06
1C
00
ENDCHAR
STARTCHAR afii10100
ENCODING 1107
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
FE
66
62
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR afii10101
ENCODING 1108
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
F8
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10102
ENCODING 1109
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10103
ENCODING 1110
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10104
ENCODING 1111
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR afii10105
ENCODING 1112
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
06
00
0E
06
06
06
06
06
06
66
66
3C
00
ENDCHAR
STARTCHAR afii10106
ENCODING 1113
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
D8
D8
DE
DB
DB
DE
00
00
00
00
ENDCHAR
STARTCHAR afii10107
ENCODING 1114
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D8
D8
D8
FE
DB
DB
DE
00
00
00
00
ENDCHAR
STARTCHAR afii10108
ENCODING 1115
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
F8
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR afii10109
ENCODING 1116
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
E6
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni045D
ENCODING 1117
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
C6
CE
DE
FE
F6
E6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii10110
ENCODING 1118
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR afii10193
ENCODING 1119
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
C6
C6
C6
FE
38
10
10
00
ENDCHAR
STARTCHAR uni0460
ENCODING 1120
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
C6
C6
D6
D6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni0461
ENCODING 1121
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR afii10146
ENCODING 1122
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
FC
B4
30
3C
36
36
36
36
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10194
ENCODING 1123
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
30
FC
B4
30
3C
36
36
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0464
ENCODING 1124
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CE
DB
D9
D8
FE
D8
D8
D9
DB
CE
00
00
00
00
ENDCHAR
STARTCHAR uni0465
ENCODING 1125
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CE
DB
D8
FE
D8
DB
CE
00
00
00
00
ENDCHAR
STARTCHAR uni0466
ENCODING 1126
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
38
6C
6C
6C
FE
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni0467
ENCODING 1127
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
38
38
6C
7C
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni0468
ENCODING 1128
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
88
8C
9C
96
F6
B6
BF
AB
EB
EB
00
00
00
00
ENDCHAR
STARTCHAR uni0469
ENCODING 1129
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
88
8C
9C
F6
BE
AB
EB
00
00
00
00
ENDCHAR
STARTCHAR uni046A
ENCODING 1130
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
6C
6C
38
7C
D6
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni046B
ENCODING 1131
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
C6
6C
7C
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni046C
ENCODING 1132
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
A3
B2
96
FC
9C
BE
AA
AB
EB
00
00
00
00
ENDCHAR
STARTCHAR uni046D
ENCODING 1133
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
BF
A3
96
FE
AB
AB
EB
00
00
00
00
ENDCHAR
STARTCHAR uni046E
ENCODING 1134
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
10
7C
C6
06
06
7C
06
06
06
7C
C0
7C
00
00
ENDCHAR
STARTCHAR uni046F
ENCODING 1135
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
6C
38
10
00
7C
86
06
7C
06
06
7C
C0
7C
00
00
ENDCHAR
STARTCHAR uni0470
ENCODING 1136
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
96
D6
D6
D6
D6
D6
7C
10
10
00
00
00
00
ENDCHAR
STARTCHAR uni0471
ENCODING 1137
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
10
96
D6
D6
D6
D6
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR afii10147
ENCODING 1138
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
FE
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10195
ENCODING 1139
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
FE
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10148
ENCODING 1140
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C2
C6
C6
C4
CC
6C
68
78
38
30
00
00
00
00
ENDCHAR
STARTCHAR afii10196
ENCODING 1141
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C2
C6
64
6C
38
38
10
00
00
00
00
ENDCHAR
STARTCHAR uni0476
ENCODING 1142
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
66
00
C2
C6
C4
C4
6C
68
78
38
30
00
00
00
00
ENDCHAR
STARTCHAR uni0477
ENCODING 1143
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
66
00
C2
C6
64
6C
38
38
10
00
00
00
00
ENDCHAR
STARTCHAR uni0478
ENCODING 1144
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D8
D8
DB
DB
DB
DB
DB
DB
6F
03
06
1C
00
ENDCHAR
STARTCHAR uni0479
ENCODING 1145
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
73
DB
DB
DB
DB
DB
6F
03
06
1C
00
ENDCHAR
STARTCHAR uni047A
ENCODING 1146
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
7C
D6
C6
C6
C6
C6
C6
C6
D6
7C
10
00
00
00
ENDCHAR
STARTCHAR uni047B
ENCODING 1147
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
7C
D6
C6
C6
C6
D6
7C
10
00
00
00
ENDCHAR
STARTCHAR uni047C
ENCODING 1148
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
7C
40
6C
C6
C6
D6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni047D
ENCODING 1149
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
04
7C
40
00
6C
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni047E
ENCODING 1150
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
54
00
6C
C6
C6
D6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni047F
ENCODING 1151
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
54
00
6C
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni0480
ENCODING 1152
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
C0
60
3C
0C
0C
0C
00
ENDCHAR
STARTCHAR uni0481
ENCODING 1153
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C0
78
18
18
00
00
ENDCHAR
STARTCHAR uni0482
ENCODING 1154
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
06
3C
0F
18
18
F0
3C
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni0483
ENCODING 1155
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
04
7C
40
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0484
ENCODING 1156
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
24
44
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0485
ENCODING 1157
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
40
7C
40
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0486
ENCODING 1158
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
04
7C
04
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0488
ENCODING 1160
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
66
00
C3
00
66
18
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0489
ENCODING 1161
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
50
46
00
82
41
00
62
0A
10
00
00
00
00
ENDCHAR
STARTCHAR uni048A
ENCODING 1162
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
C6
C6
C6
CE
DE
FE
F6
E6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni048B
ENCODING 1163
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
C6
CE
DE
FE
F6
E6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni048C
ENCODING 1164
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
F0
60
60
60
7C
66
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni048D
ENCODING 1165
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
60
F0
60
60
7C
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni048E
ENCODING 1166
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
6E
64
7A
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni048F
ENCODING 1167
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
6E
64
7A
60
60
F0
00
ENDCHAR
STARTCHAR afii10050
ENCODING 1168
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
02
06
FE
60
60
60
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR afii10098
ENCODING 1169
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
02
06
FE
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni0492
ENCODING 1170
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
60
F8
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni0493
ENCODING 1171
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
66
62
F8
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni0494
ENCODING 1172
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
60
7C
66
66
66
66
F6
06
16
0C
00
ENDCHAR
STARTCHAR uni0495
ENCODING 1173
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
66
62
78
6C
66
F6
06
16
0C
00
ENDCHAR
STARTCHAR uni0496
ENCODING 1174
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D6
D6
D6
7C
38
7C
D6
D6
D6
D7
03
01
00
00
ENDCHAR
STARTCHAR uni0497
ENCODING 1175
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D6
D6
D6
7C
D6
D6
D7
03
01
00
00
ENDCHAR
STARTCHAR uni0498
ENCODING 1176
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
86
06
3C
06
06
86
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uni0499
ENCODING 1177
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
3C
06
C6
7C
30
60
38
00
ENDCHAR
STARTCHAR uni049A
ENCODING 1178
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E7
03
01
00
00
ENDCHAR
STARTCHAR uni049B
ENCODING 1179
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
E6
6C
78
78
6C
66
E7
03
01
00
00
ENDCHAR
STARTCHAR uni049C
ENCODING 1180
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
D6
D6
DC
F8
DC
D6
D6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni049D
ENCODING 1181
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
D6
DC
F8
DC
D6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni049E
ENCODING 1182
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
F6
6C
78
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni049F
ENCODING 1183
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
F0
66
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni04A0
ENCODING 1184
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F3
B3
B3
36
3C
3C
36
33
33
73
00
00
00
00
ENDCHAR
STARTCHAR uni04A1
ENCODING 1185
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F3
B6
BC
3C
36
33
73
00
00
00
00
ENDCHAR
STARTCHAR uni04A2
ENCODING 1186
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04A3
ENCODING 1187
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
FE
C6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04A4
ENCODING 1188
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DF
DB
D9
D8
F8
D8
D8
D8
D8
D8
00
00
00
00
ENDCHAR
STARTCHAR uni04A5
ENCODING 1189
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DF
DB
D9
F8
D8
D8
D8
00
00
00
00
ENDCHAR
STARTCHAR uni04A6
ENCODING 1190
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
D8
D8
D8
DE
DB
DB
DB
DB
DB
03
0B
06
00
ENDCHAR
STARTCHAR uni04A7
ENCODING 1191
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D8
D8
D8
FE
DB
DB
DB
03
0B
06
00
ENDCHAR
STARTCHAR uni04A8
ENCODING 1192
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C2
CC
D6
D6
D6
D6
D6
CC
7A
00
00
00
00
ENDCHAR
STARTCHAR uni04A9
ENCODING 1193
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C2
CC
D6
D6
CC
7A
00
00
00
00
ENDCHAR
STARTCHAR uni04AA
ENCODING 1194
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
C2
66
3C
18
0C
38
00
ENDCHAR
STARTCHAR uni04AB
ENCODING 1195
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR uni04AC
ENCODING 1196
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
0C
04
00
00
ENDCHAR
STARTCHAR uni04AD
ENCODING 1197
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
5A
18
18
18
18
3C
0C
04
00
00
ENDCHAR
STARTCHAR uni04AE
ENCODING 1198
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni04AF
ENCODING 1199
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
66
66
3C
18
18
18
3C
00
ENDCHAR
STARTCHAR uni04B0
ENCODING 1200
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
3C
18
7E
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni04B1
ENCODING 1201
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
66
66
3C
18
7E
18
3C
00
ENDCHAR
STARTCHAR uni04B2
ENCODING 1202
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
6C
7C
38
38
7C
6C
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04B3
ENCODING 1203
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
6C
38
38
38
6C
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04B4
ENCODING 1204
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F6
66
66
66
66
66
66
66
66
7F
03
01
00
00
ENDCHAR
STARTCHAR uni04B5
ENCODING 1205
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F6
66
66
66
66
66
7F
03
01
00
00
ENDCHAR
STARTCHAR uni04B6
ENCODING 1206
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
7E
06
06
06
07
03
01
00
00
ENDCHAR
STARTCHAR uni04B7
ENCODING 1207
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
7E
06
06
07
03
01
00
00
ENDCHAR
STARTCHAR uni04B8
ENCODING 1208
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
D6
D6
7E
16
16
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni04B9
ENCODING 1209
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
D6
D6
7E
16
16
06
00
00
00
00
ENDCHAR
STARTCHAR uni04BA
ENCODING 1210
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
C0
FC
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04BB
ENCODING 1211
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C0
C0
C0
FC
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04BC
ENCODING 1212
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
33
B3
B3
7F
30
30
30
33
1E
00
00
00
00
ENDCHAR
STARTCHAR uni04BD
ENCODING 1213
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
9E
B3
7F
30
30
33
1E
00
00
00
00
ENDCHAR
STARTCHAR uni04BE
ENCODING 1214
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
33
B3
B3
7F
30
30
30
33
1E
0C
18
0E
00
ENDCHAR
STARTCHAR uni04BF
ENCODING 1215
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
9E
B3
7F
30
30
33
1E
0C
18
0E
00
ENDCHAR
STARTCHAR uni04C0
ENCODING 1216
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni04C1
ENCODING 1217
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
D6
D6
D6
7C
38
7C
D6
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni04C2
ENCODING 1218
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
D6
D6
D6
7C
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni04C3
ENCODING 1219
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
06
16
0C
00
ENDCHAR
STARTCHAR uni04C4
ENCODING 1220
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
E6
6C
78
78
6C
66
E6
06
16
0C
00
ENDCHAR
STARTCHAR uni04C5
ENCODING 1221
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
66
66
66
66
66
66
66
66
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04C6
ENCODING 1222
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3E
66
66
66
66
66
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04C7
ENCODING 1223
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
06
16
0C
00
ENDCHAR
STARTCHAR uni04C8
ENCODING 1224
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
FE
C6
C6
C6
06
16
0C
00
ENDCHAR
STARTCHAR uni04C9
ENCODING 1225
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04CA
ENCODING 1226
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
FE
C6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04CB
ENCODING 1227
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
7E
06
06
06
0E
0C
08
00
00
ENDCHAR
STARTCHAR uni04CC
ENCODING 1228
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
7E
06
06
0E
0C
08
00
00
ENDCHAR
STARTCHAR uni04CD
ENCODING 1229
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04CE
ENCODING 1230
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
EE
FE
FE
D6
C6
C7
03
01
00
00
ENDCHAR
STARTCHAR uni04D0
ENCODING 1232
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04D1
ENCODING 1233
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni04D2
ENCODING 1234
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04D3
ENCODING 1235
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni04D4
ENCODING 1236
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
6C
CC
CC
FE
CC
CC
CC
CC
CE
00
00
00
00
ENDCHAR
STARTCHAR uni04D5
ENCODING 1237
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
76
36
7E
D8
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR uni04D6
ENCODING 1238
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni04D7
ENCODING 1239
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04D8
ENCODING 1240
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
06
06
06
FE
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii10846
ENCODING 1241
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
06
FE
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04DA
ENCODING 1242
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
7C
C6
06
06
FE
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04DB
ENCODING 1243
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
06
06
FE
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04DC
ENCODING 1244
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
D6
D6
D6
7C
38
7C
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni04DD
ENCODING 1245
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
D6
D6
D6
7C
D6
D6
D6
00
00
00
00
ENDCHAR
STARTCHAR uni04DE
ENCODING 1246
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
7C
C6
86
06
3C
06
86
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04DF
ENCODING 1247
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
06
3C
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04E0
ENCODING 1248
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
06
0C
18
3C
06
06
86
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04E1
ENCODING 1249
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
06
0C
18
3C
06
06
06
C6
7C
00
ENDCHAR
STARTCHAR uni04E2
ENCODING 1250
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
C6
C6
CE
DE
FE
F6
E6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04E3
ENCODING 1251
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
C6
CE
DE
FE
F6
E6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04E4
ENCODING 1252
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
CE
DE
FE
F6
E6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04E5
ENCODING 1253
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C6
CE
DE
FE
F6
E6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni04E6
ENCODING 1254
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04E7
ENCODING 1255
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04E8
ENCODING 1256
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
FE
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04E9
ENCODING 1257
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
FE
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04EA
ENCODING 1258
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
7C
C6
C6
C6
FE
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04EB
ENCODING 1259
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
C6
FE
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04EC
ENCODING 1260
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
78
CC
86
06
3E
06
86
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni04ED
ENCODING 1261
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
7C
C6
06
3E
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04EE
ENCODING 1262
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
C6
C6
C6
C6
7E
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04EF
ENCODING 1263
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni04F0
ENCODING 1264
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
C6
C6
7E
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04F1
ENCODING 1265
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni04F2
ENCODING 1266
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
66
CC
00
C6
C6
C6
C6
7E
06
06
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni04F3
ENCODING 1267
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
CC
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni04F4
ENCODING 1268
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
C6
C6
7E
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni04F5
ENCODING 1269
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C6
C6
C6
7E
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni04F8
ENCODING 1272
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C3
C3
C3
F3
DB
DB
DB
DB
F3
00
00
00
00
ENDCHAR
STARTCHAR uni04F9
ENCODING 1273
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C3
C3
C3
F3
DB
DB
F3
00
00
00
00
ENDCHAR
STARTCHAR uni0500
ENCODING 1280
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
0C
0C
0C
7C
CC
CC
CC
CC
7E
00
00
00
00
ENDCHAR
STARTCHAR uni0501
ENCODING 1281
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni0502
ENCODING 1282
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
0C
0C
0C
7C
CD
CD
CD
CD
76
00
00
00
00
ENDCHAR
STARTCHAR uni0503
ENCODING 1283
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CD
CD
CD
76
00
00
00
00
ENDCHAR
STARTCHAR uni0504
ENCODING 1284
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
8C
0C
38
0D
0D
0D
0D
06
00
00
00
00
ENDCHAR
STARTCHAR uni0505
ENCODING 1285
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
CC
0C
39
0D
0D
06
00
00
00
00
ENDCHAR
STARTCHAR uni0506
ENCODING 1286
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
86
06
3C
06
06
06
06
07
03
01
00
00
ENDCHAR
STARTCHAR uni0507
ENCODING 1287
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
06
3C
06
06
07
03
01
00
00
ENDCHAR
STARTCHAR uni0508
ENCODING 1288
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
6C
6C
6C
6C
6D
6D
6D
6D
C6
00
00
00
00
ENDCHAR
STARTCHAR uni0509
ENCODING 1289
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
6C
6C
6D
6D
6D
C6
00
00
00
00
ENDCHAR
STARTCHAR uni050A
ENCODING 1290
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
CC
CC
CC
FC
CD
CD
CD
CD
C6
00
00
00
00
ENDCHAR
STARTCHAR uni050B
ENCODING 1291
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
FD
CD
CD
C6
00
00
00
00
ENDCHAR
STARTCHAR uni050C
ENCODING 1292
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
CE
C6
C6
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni050D
ENCODING 1293
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
CE
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni050E
ENCODING 1294
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
1B
1B
1B
1B
0E
00
00
00
00
ENDCHAR
STARTCHAR uni050F
ENCODING 1295
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7E
5A
18
1B
1B
1B
0E
00
00
00
00
ENDCHAR
STARTCHAR uni0530
ENCODING 1328
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
64
94
BA
52
4C
30
00
00
00
00
00
ENDCHAR
STARTCHAR uni0531
ENCODING 1329
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
CC
CC
CC
CC
CC
CC
CC
CF
7B
00
00
00
00
ENDCHAR
STARTCHAR uni0532
ENCODING 1330
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
60
60
7E
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni0533
ENCODING 1331
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
CC
CC
CC
7F
0C
0C
0C
0C
00
00
00
00
ENDCHAR
STARTCHAR uni0534
ENCODING 1332
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
CC
CC
CC
CF
0C
0C
0C
0C
00
00
00
00
ENDCHAR
STARTCHAR uni0535
ENCODING 1333
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
7E
60
60
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0536
ENCODING 1334
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
3E
06
0C
D8
FE
C3
00
00
00
ENDCHAR
STARTCHAR uni0537
ENCODING 1335
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
7E
60
60
60
60
60
60
7C
06
00
00
00
ENDCHAR
STARTCHAR uni0538
ENCODING 1336
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
66
60
60
60
7E
00
00
00
00
ENDCHAR
STARTCHAR uni0539
ENCODING 1337
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
CF
D6
D6
D6
D6
CC
C0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni053A
ENCODING 1338
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
0C
0C
0C
7F
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni053B
ENCODING 1339
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
7C
66
66
66
66
66
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni053C
ENCODING 1340
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
60
60
60
60
60
60
60
7C
06
00
00
00
ENDCHAR
STARTCHAR uni053D
ENCODING 1341
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
F6
D6
D6
D6
D6
CC
C0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni053E
ENCODING 1342
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
7F
24
66
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni053F
ENCODING 1343
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
66
66
66
66
66
3E
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni0540
ENCODING 1344
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
30
18
0C
18
30
60
F0
3C
0E
04
00
00
00
ENDCHAR
STARTCHAR uni0541
ENCODING 1345
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
06
06
06
6C
D8
6E
00
00
00
00
ENDCHAR
STARTCHAR uni0542
ENCODING 1346
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
CC
CC
CC
CC
0C
0C
0C
0F
00
00
00
00
ENDCHAR
STARTCHAR uni0543
ENCODING 1347
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
30
60
F8
6C
66
66
66
66
7E
00
00
00
00
ENDCHAR
STARTCHAR uni0544
ENCODING 1348
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CF
CC
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni0545
ENCODING 1349
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
06
06
7C
06
06
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0546
ENCODING 1350
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
60
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0547
ENCODING 1351
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
06
3E
66
60
60
60
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0548
ENCODING 1352
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni0549
ENCODING 1353
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
06
06
06
6C
38
0E
00
00
00
00
ENDCHAR
STARTCHAR uni054A
ENCODING 1354
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
D6
D6
D6
D6
D6
16
16
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni054B
ENCODING 1355
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
76
1E
0E
0C
D8
FE
C3
00
00
00
ENDCHAR
STARTCHAR uni054C
ENCODING 1356
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
CC
CC
CC
CF
CC
CC
CC
CC
00
00
00
00
ENDCHAR
STARTCHAR uni054D
ENCODING 1357
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni054E
ENCODING 1358
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
0C
CC
CC
CC
CC
7C
0C
0C
0F
00
00
00
00
ENDCHAR
STARTCHAR uni054F
ENCODING 1359
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
60
30
18
0C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0550
ENCODING 1360
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
66
60
60
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni0551
ENCODING 1361
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
3C
66
06
06
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0552
ENCODING 1362
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
7C
66
66
66
66
63
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni0553
ENCODING 1363
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
7C
D6
D6
D6
D6
D6
D6
7C
10
00
00
00
00
ENDCHAR
STARTCHAR uni0554
ENCODING 1364
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
7C
60
60
FE
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni0555
ENCODING 1365
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0556
ENCODING 1366
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D0
D0
D0
7C
16
16
16
D6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0559
ENCODING 1369
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
30
18
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni055A
ENCODING 1370
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
18
18
30
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni055B
ENCODING 1371
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
60
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni055C
ENCODING 1372
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
06
3C
60
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni055D
ENCODING 1373
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
18
0C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni055E
ENCODING 1374
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1C
36
6C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni055F
ENCODING 1375
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
60
3E
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0561
ENCODING 1377
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D6
D6
D6
D6
D6
D6
6A
00
00
00
00
ENDCHAR
STARTCHAR uni0562
ENCODING 1378
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
66
66
66
60
60
7E
60
60
60
00
ENDCHAR
STARTCHAR uni0563
ENCODING 1379
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
CC
CC
CC
CC
CC
7F
0C
0C
0C
00
ENDCHAR
STARTCHAR uni0564
ENCODING 1380
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F8
CC
CC
CC
CC
CC
CF
0C
0C
0C
00
ENDCHAR
STARTCHAR uni0565
ENCODING 1381
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
7E
60
60
66
66
66
66
3E
00
00
00
00
ENDCHAR
STARTCHAR uni0566
ENCODING 1382
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
CC
CC
CC
CC
CC
7C
0C
0C
0F
00
ENDCHAR
STARTCHAR uni0567
ENCODING 1383
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
60
7C
60
60
60
60
60
78
0C
18
00
00
ENDCHAR
STARTCHAR uni0568
ENCODING 1384
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
66
66
66
66
66
66
60
60
7E
00
ENDCHAR
STARTCHAR uni0569
ENCODING 1385
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FC
C6
C6
CF
D6
D6
CC
C0
C0
C0
00
ENDCHAR
STARTCHAR uni056A
ENCODING 1386
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
0C
0C
7F
CC
CC
CC
CC
CC
7C
00
00
00
00
ENDCHAR
STARTCHAR uni056B
ENCODING 1387
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
60
7C
66
66
66
66
66
66
60
60
60
00
ENDCHAR
STARTCHAR uni056C
ENCODING 1388
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
30
30
30
30
30
30
30
30
30
3E
00
ENDCHAR
STARTCHAR uni056D
ENCODING 1389
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
F6
D6
D6
D6
D6
D6
CA
C0
C0
C0
00
ENDCHAR
STARTCHAR uni056E
ENCODING 1390
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
38
0C
7F
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni056F
ENCODING 1391
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
60
66
66
66
66
66
66
3E
06
06
06
00
ENDCHAR
STARTCHAR uni0570
ENCODING 1392
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
60
7C
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni0571
ENCODING 1393
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
1C
0C
18
3C
64
66
62
63
3D
00
00
00
00
ENDCHAR
STARTCHAR uni0572
ENCODING 1394
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F8
CC
CC
CC
CC
CC
CC
0C
0C
0F
00
ENDCHAR
STARTCHAR uni0573
ENCODING 1395
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
18
30
F8
6C
66
66
66
66
3E
00
00
00
00
ENDCHAR
STARTCHAR uni0574
ENCODING 1396
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0F
0C
0C
CC
CC
CC
CC
CC
CC
7C
00
00
00
00
ENDCHAR
STARTCHAR uni0575
ENCODING 1397
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
0C
0C
0C
0C
0C
0C
0C
6C
38
00
ENDCHAR
STARTCHAR uni0576
ENCODING 1398
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
66
66
66
66
66
66
3E
00
00
00
00
ENDCHAR
STARTCHAR uni0577
ENCODING 1399
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
66
66
06
0C
18
30
60
3E
00
ENDCHAR
STARTCHAR uni0578
ENCODING 1400
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni0579
ENCODING 1401
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
18
18
0C
06
0C
18
30
60
3E
00
ENDCHAR
STARTCHAR uni057A
ENCODING 1402
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
D6
D6
D6
D6
D6
D6
7E
06
06
06
00
ENDCHAR
STARTCHAR uni057B
ENCODING 1403
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
66
66
76
1C
18
30
60
3E
00
ENDCHAR
STARTCHAR uni057C
ENCODING 1404
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
F8
CC
CC
CC
CC
CC
CF
00
00
00
00
ENDCHAR
STARTCHAR uni057D
ENCODING 1405
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
66
66
66
3E
00
00
00
00
ENDCHAR
STARTCHAR uni057E
ENCODING 1406
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
0C
0C
CC
CC
CC
CC
CC
CC
7C
0C
0C
0F
00
ENDCHAR
STARTCHAR uni057F
ENCODING 1407
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
D6
D6
D6
D6
D6
76
00
00
00
00
ENDCHAR
STARTCHAR uni0580
ENCODING 1408
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
66
66
66
66
66
66
60
60
60
00
ENDCHAR
STARTCHAR uni0581
ENCODING 1409
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3E
66
66
66
66
66
3E
06
66
3C
00
ENDCHAR
STARTCHAR uni0582
ENCODING 1410
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
30
30
30
30
30
30
3E
00
00
00
00
ENDCHAR
STARTCHAR uni0583
ENCODING 1411
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
10
DC
D6
D6
D6
D6
D6
76
10
10
10
00
ENDCHAR
STARTCHAR uni0584
ENCODING 1412
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
66
66
66
66
7C
60
FE
60
60
00
ENDCHAR
STARTCHAR uni0585
ENCODING 1413
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni0586
ENCODING 1414
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
D0
D0
7C
16
16
16
16
D6
7C
10
10
10
00
ENDCHAR
STARTCHAR uni0587
ENCODING 1415
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
C0
C0
CC
CC
CC
CC
77
00
00
00
00
ENDCHAR
STARTCHAR uni0589
ENCODING 1417
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
18
00
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni058A
ENCODING 1418
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C0
C6
7C
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0591
ENCODING 1425
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
10
10
38
6C
ENDCHAR
STARTCHAR uni0592
ENCODING 1426
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
00
66
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0593
ENCODING 1427
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
38
10
38
20
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0594
ENCODING 1428
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
00
18
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0595
ENCODING 1429
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
60
6C
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0596
ENCODING 1430
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
10
18
0C
00
ENDCHAR
STARTCHAR uni0597
ENCODING 1431
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
10
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0598
ENCODING 1432
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
74
D6
5C
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0599
ENCODING 1433
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
60
20
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni059A
ENCODING 1434
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
03
06
03
00
ENDCHAR
STARTCHAR uni059B
ENCODING 1435
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
28
18
30
00
ENDCHAR
STARTCHAR uni059C
ENCODING 1436
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
10
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni059D
ENCODING 1437
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
06
04
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni059E
ENCODING 1438
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1B
36
24
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni059F
ENCODING 1439
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
44
AA
6C
28
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05A0
ENCODING 1440
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
0A
0C
08
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05A1
ENCODING 1441
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
40
50
E0
80
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05A3
ENCODING 1443
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
0C
0C
3C
00
ENDCHAR
STARTCHAR uni05A4
ENCODING 1444
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
30
18
00
ENDCHAR
STARTCHAR uni05A5
ENCODING 1445
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
10
30
60
00
ENDCHAR
STARTCHAR uni05A6
ENCODING 1446
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
24
6C
D8
00
ENDCHAR
STARTCHAR uni05A7
ENCODING 1447
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
30
08
30
ENDCHAR
STARTCHAR uni05A8
ENCODING 1448
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
10
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05A9
ENCODING 1449
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
40
A0
60
20
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05AA
ENCODING 1450
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
6C
38
10
10
ENDCHAR
STARTCHAR uni05AB
ENCODING 1451
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
30
18
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05AC
ENCODING 1452
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
3C
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05AD
ENCODING 1453
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
04
06
03
00
ENDCHAR
STARTCHAR uni05AE
ENCODING 1454
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
48
A8
90
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05AF
ENCODING 1455
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
38
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57799
ENCODING 1456
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
00
18
00
ENDCHAR
STARTCHAR afii57801
ENCODING 1457
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
DB
00
33
00
ENDCHAR
STARTCHAR afii57800
ENCODING 1458
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
F6
00
06
00
ENDCHAR
STARTCHAR afii57802
ENCODING 1459
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
F6
60
66
00
ENDCHAR
STARTCHAR afii57793
ENCODING 1460
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
18
00
00
00
ENDCHAR
STARTCHAR afii57794
ENCODING 1461
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
66
00
00
00
ENDCHAR
STARTCHAR afii57795
ENCODING 1462
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
66
00
18
00
ENDCHAR
STARTCHAR afii57798
ENCODING 1463
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
7E
00
00
ENDCHAR
STARTCHAR afii57797
ENCODING 1464
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
7E
18
18
ENDCHAR
STARTCHAR afii57806
ENCODING 1465
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
60
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57796
ENCODING 1467
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
C0
18
03
00
ENDCHAR
STARTCHAR afii57807
ENCODING 1468
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
18
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57839
ENCODING 1469
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
18
18
18
ENDCHAR
STARTCHAR afii57645
ENCODING 1470
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7E
FC
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57841
ENCODING 1471
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57842
ENCODING 1472
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR afii57804
ENCODING 1473
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
06
06
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57803
ENCODING 1474
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57658
ENCODING 1475
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
00
00
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni05C4
ENCODING 1476
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57664
ENCODING 1488
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C6
C6
66
76
DC
CC
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii57665
ENCODING 1489
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
F8
0C
0C
0C
0C
0C
0C
FE
00
00
00
00
ENDCHAR
STARTCHAR afii57666
ENCODING 1490
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
0C
0C
0C
0C
1C
36
E6
00
00
00
00
ENDCHAR
STARTCHAR afii57667
ENCODING 1491
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
0C
0C
0C
0C
0C
0C
0C
00
00
00
00
ENDCHAR
STARTCHAR afii57668
ENCODING 1492
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
06
06
06
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii57669
ENCODING 1493
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR afii57670
ENCODING 1494
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
7E
18
18
18
0C
0C
18
30
00
00
00
00
ENDCHAR
STARTCHAR afii57671
ENCODING 1495
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
66
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR afii57672
ENCODING 1496
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
CC
D6
D6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii57673
ENCODING 1497
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
18
18
18
30
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57674
ENCODING 1498
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
06
06
06
0C
0C
0C
0C
0C
0C
0E
00
ENDCHAR
STARTCHAR afii57675
ENCODING 1499
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
06
06
06
06
06
06
FC
00
00
00
00
ENDCHAR
STARTCHAR afii57676
ENCODING 1500
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
FC
06
06
06
06
0C
18
18
00
00
00
00
ENDCHAR
STARTCHAR afii57677
ENCODING 1501
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
66
C6
C6
C6
C6
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR afii57678
ENCODING 1502
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
DC
76
66
C6
C6
C6
C6
DE
00
00
00
00
ENDCHAR
STARTCHAR afii57679
ENCODING 1503
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
0C
0C
18
18
18
18
18
18
18
1C
00
ENDCHAR
STARTCHAR afii57680
ENCODING 1504
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
0C
0C
0C
0C
0C
0C
7C
00
00
00
00
ENDCHAR
STARTCHAR afii57681
ENCODING 1505
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
66
C6
C6
C6
C6
CC
78
00
00
00
00
ENDCHAR
STARTCHAR afii57682
ENCODING 1506
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
EE
66
66
66
66
66
2C
F8
00
00
00
00
ENDCHAR
STARTCHAR afii57683
ENCODING 1507
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
F8
4C
CC
CC
EC
0C
0C
0C
0C
0C
0E
00
ENDCHAR
STARTCHAR afii57684
ENCODING 1508
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
46
C6
C6
E6
06
06
FE
00
00
00
00
ENDCHAR
STARTCHAR afii57685
ENCODING 1509
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
EE
66
66
6C
78
60
60
60
60
60
70
00
ENDCHAR
STARTCHAR afii57686
ENCODING 1510
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
EE
66
66
34
18
0C
06
FE
00
00
00
00
ENDCHAR
STARTCHAR afii57687
ENCODING 1511
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
06
06
66
64
6C
6E
60
60
60
60
00
ENDCHAR
STARTCHAR afii57688
ENCODING 1512
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
06
06
06
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR afii57689
ENCODING 1513
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
D6
D6
D6
D6
D6
F6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR afii57690
ENCODING 1514
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
66
66
66
66
66
E6
E6
00
00
00
00
ENDCHAR
STARTCHAR afii57716
ENCODING 1520
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
CC
66
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR afii57717
ENCODING 1521
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
CC
66
66
66
C6
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR afii57718
ENCODING 1522
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
CC
66
66
66
CC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05F3
ENCODING 1523
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni05F4
ENCODING 1524
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
CC
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57388
ENCODING 1548
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
10
18
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57403
ENCODING 1563
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
18
00
00
00
18
18
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57407
ENCODING 1567
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
22
20
10
08
08
00
08
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57409
ENCODING 1569
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
20
1E
20
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57410
ENCODING 1570
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
02
3C
40
10
10
10
10
10
10
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57411
ENCODING 1571
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
20
1C
20
08
08
08
08
08
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57412
ENCODING 1572
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1C
20
1C
20
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR afii57413
ENCODING 1573
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
08
08
08
08
00
18
20
1C
20
00
00
ENDCHAR
STARTCHAR afii57414
ENCODING 1574
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
40
38
40
07
08
88
86
81
82
7C
00
00
00
00
ENDCHAR
STARTCHAR afii57415
ENCODING 1575
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
08
08
08
08
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57416
ENCODING 1576
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR afii57417
ENCODING 1577
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
28
00
00
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57418
ENCODING 1578
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
14
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57419
ENCODING 1579
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57420
ENCODING 1580
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
80
88
80
41
3E
00
00
00
ENDCHAR
STARTCHAR afii57421
ENCODING 1581
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR afii57422
ENCODING 1582
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
20
00
00
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR afii57423
ENCODING 1583
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57424
ENCODING 1584
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57425
ENCODING 1585
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR afii57426
ENCODING 1586
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR afii57427
ENCODING 1587
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
01
15
88
84
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR afii57428
ENCODING 1588
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
01
15
88
84
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR afii57429
ENCODING 1589
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
09
31
9E
88
88
70
00
00
00
00
00
ENDCHAR
STARTCHAR afii57430
ENCODING 1590
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
09
31
9E
88
88
70
00
00
00
00
00
ENDCHAR
STARTCHAR afii57431
ENCODING 1591
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
20
20
2C
32
A2
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57432
ENCODING 1592
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
20
20
2C
32
A2
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57433
ENCODING 1593
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
80
8C
70
40
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR afii57434
ENCODING 1594
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
40
00
00
70
80
8C
70
40
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR afii57440
ENCODING 1600
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57441
ENCODING 1601
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57442
ENCODING 1602
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0A
00
06
09
09
47
81
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR afii57443
ENCODING 1603
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
19
21
19
21
01
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57444
ENCODING 1604
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
02
02
02
02
02
42
82
82
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR afii57445
ENCODING 1605
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0C
12
12
3C
40
40
40
40
40
40
00
00
ENDCHAR
STARTCHAR afii57446
ENCODING 1606
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR afii57470
ENCODING 1607
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
40
30
4E
49
39
E6
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57448
ENCODING 1608
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR afii57449
ENCODING 1609
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR afii57450
ENCODING 1610
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
81
7E
00
00
24
00
ENDCHAR
STARTCHAR afii57451
ENCODING 1611
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
0C
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57452
ENCODING 1612
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
12
CA
2C
70
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57453
ENCODING 1613
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
0C
30
0C
30
00
00
ENDCHAR
STARTCHAR afii57454
ENCODING 1614
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57455
ENCODING 1615
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
14
0C
08
10
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57456
ENCODING 1616
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
0C
30
00
00
ENDCHAR
STARTCHAR afii57457
ENCODING 1617
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0A
2A
2C
10
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57458
ENCODING 1618
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
24
18
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0653
ENCODING 1619
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
01
7E
80
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0654
ENCODING 1620
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
10
0C
10
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0655
ENCODING 1621
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
0C
10
0C
10
ENDCHAR
STARTCHAR afii57392
ENCODING 1632
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
30
78
30
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57393
ENCODING 1633
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
70
70
38
18
18
08
08
08
00
00
00
00
00
ENDCHAR
STARTCHAR afii57394
ENCODING 1634
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
44
FC
F8
60
30
30
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR afii57395
ENCODING 1635
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
4A
FE
F4
60
30
30
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR afii57396
ENCODING 1636
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
20
40
30
10
20
42
7C
38
00
00
00
00
00
ENDCHAR
STARTCHAR afii57397
ENCODING 1637
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
2C
44
42
82
82
FE
7C
00
00
00
00
00
ENDCHAR
STARTCHAR afii57398
ENCODING 1638
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
F8
78
08
08
08
0C
0E
06
00
00
00
00
00
ENDCHAR
STARTCHAR afii57399
ENCODING 1639
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
82
C6
C6
6C
28
38
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR afii57400
ENCODING 1640
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
10
38
28
6C
C6
C6
82
00
00
00
00
00
ENDCHAR
STARTCHAR afii57401
ENCODING 1641
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
F8
88
F8
78
08
0C
0E
06
00
00
00
00
00
ENDCHAR
STARTCHAR afii57381
ENCODING 1642
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
91
92
64
08
10
26
49
89
06
00
00
00
00
ENDCHAR
STARTCHAR uni066B
ENCODING 1643
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
18
18
30
30
60
60
00
00
ENDCHAR
STARTCHAR uni066C
ENCODING 1644
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
18
10
20
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii63167
ENCODING 1645
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
38
FE
7C
38
6C
44
00
00
00
00
00
ENDCHAR
STARTCHAR uni0670
ENCODING 1648
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
10
10
10
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0671
ENCODING 1649
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
06
29
5E
00
04
04
04
04
04
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0672
ENCODING 1650
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
06
28
5E
00
04
04
04
04
04
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0673
ENCODING 1651
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
04
04
04
04
04
00
06
28
5E
00
00
00
ENDCHAR
STARTCHAR uni0674
ENCODING 1652
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
07
08
07
08
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0675
ENCODING 1653
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
04
03
14
10
10
10
10
10
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0676
ENCODING 1654
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
04
03
04
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni0677
ENCODING 1655
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
23
54
33
24
40
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni0678
ENCODING 1656
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
04
03
04
00
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR afii57511
ENCODING 1657
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni067A
ENCODING 1658
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
08
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni067B
ENCODING 1659
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uni067C
ENCODING 1660
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
14
40
81
81
7E
08
14
08
00
00
00
00
ENDCHAR
STARTCHAR uni067D
ENCODING 1661
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
08
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57506
ENCODING 1662
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
00
14
00
08
00
00
ENDCHAR
STARTCHAR uni067F
ENCODING 1663
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
14
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0680
ENCODING 1664
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
00
14
00
14
00
00
ENDCHAR
STARTCHAR uni0681
ENCODING 1665
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
06
08
06
08
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uni0682
ENCODING 1666
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
08
00
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uni0683
ENCODING 1667
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
80
94
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uni0684
ENCODING 1668
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
88
80
88
41
3E
00
00
00
ENDCHAR
STARTCHAR uni0685
ENCODING 1669
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR afii57507
ENCODING 1670
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
94
80
88
41
3E
00
00
00
ENDCHAR
STARTCHAR uni0687
ENCODING 1671
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
94
80
94
41
3E
00
00
00
ENDCHAR
STARTCHAR afii57512
ENCODING 1672
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
38
28
70
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0689
ENCODING 1673
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
04
02
42
3C
08
14
08
00
00
00
00
ENDCHAR
STARTCHAR uni068A
ENCODING 1674
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
04
02
42
3C
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR uni068B
ENCODING 1675
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
38
28
70
08
04
02
42
3C
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR uni068C
ENCODING 1676
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni068D
ENCODING 1677
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
04
02
42
3C
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uni068E
ENCODING 1678
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni068F
ENCODING 1679
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
00
08
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni0690
ENCODING 1680
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
00
14
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57513
ENCODING 1681
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uni0692
ENCODING 1682
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
08
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uni0693
ENCODING 1683
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
02
02
04
1C
6A
04
00
00
00
00
ENDCHAR
STARTCHAR uni0694
ENCODING 1684
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
02
02
04
18
62
00
00
00
00
00
ENDCHAR
STARTCHAR uni0695
ENCODING 1685
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
02
02
04
18
60
00
14
08
00
00
ENDCHAR
STARTCHAR uni0696
ENCODING 1686
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
02
12
04
18
62
00
00
00
00
00
ENDCHAR
STARTCHAR uni0697
ENCODING 1687
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
14
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR afii57508
ENCODING 1688
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uni0699
ENCODING 1689
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
00
14
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uni069A
ENCODING 1690
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
00
01
15
88
88
8A
70
00
00
00
00
00
ENDCHAR
STARTCHAR uni069B
ENCODING 1691
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
01
15
88
88
90
65
00
02
00
00
00
ENDCHAR
STARTCHAR uni069C
ENCODING 1692
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
04
00
0A
00
01
15
88
88
90
65
00
02
00
00
00
ENDCHAR
STARTCHAR uni069D
ENCODING 1693
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
09
31
9E
88
90
65
00
00
00
00
00
ENDCHAR
STARTCHAR uni069E
ENCODING 1694
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
0A
00
06
09
31
9E
88
88
70
00
00
00
00
00
ENDCHAR
STARTCHAR uni069F
ENCODING 1695
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
2A
20
20
2C
32
A2
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06A0
ENCODING 1696
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
00
50
00
70
80
8C
70
40
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR uni06A1
ENCODING 1697
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06A2
ENCODING 1698
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
49
85
83
7E
00
02
00
00
00
00
00
ENDCHAR
STARTCHAR uni06A3
ENCODING 1699
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
49
85
83
7E
00
08
00
00
00
00
00
ENDCHAR
STARTCHAR afii57505
ENCODING 1700
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
0A
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06A5
ENCODING 1701
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
49
85
83
7E
00
0A
00
04
00
00
00
ENDCHAR
STARTCHAR uni06A6
ENCODING 1702
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0A
00
0A
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06A7
ENCODING 1703
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
09
09
47
81
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uni06A8
ENCODING 1704
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
0A
00
06
09
09
47
81
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uni06A9
ENCODING 1705
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
01
02
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06AA
ENCODING 1706
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
20
40
3E
01
81
7E
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06AB
ENCODING 1707
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
01
02
05
0B
48
84
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06AC
ENCODING 1708
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
19
21
19
21
01
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06AD
ENCODING 1709
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
00
29
01
19
21
19
A1
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06AE
ENCODING 1710
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
19
21
19
21
01
81
7E
00
14
00
08
00
00
00
ENDCHAR
STARTCHAR afii57509
ENCODING 1711
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B0
ENCODING 1712
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
05
0B
48
84
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B1
ENCODING 1713
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
A4
09
12
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B2
ENCODING 1714
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
44
82
82
7C
00
14
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B3
ENCODING 1715
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
44
82
82
7C
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uni06B4
ENCODING 1716
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
44
09
A2
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B5
ENCODING 1717
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
08
02
02
02
02
42
82
82
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B6
ENCODING 1718
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
02
02
02
02
02
42
82
82
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B7
ENCODING 1719
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
02
2A
02
02
02
42
82
82
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR uni06B8
ENCODING 1720
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
02
02
02
02
02
42
82
82
84
78
00
14
00
08
00
ENDCHAR
STARTCHAR uni06B9
ENCODING 1721
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
00
00
41
81
81
81
42
3C
00
00
04
00
00
ENDCHAR
STARTCHAR afii57514
ENCODING 1722
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uni06BB
ENCODING 1723
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uni06BC
ENCODING 1724
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
41
81
81
81
42
3C
08
14
08
00
00
ENDCHAR
STARTCHAR uni06BD
ENCODING 1725
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uni06BE
ENCODING 1726
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
38
4C
52
32
3C
40
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06BF
ENCODING 1727
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
00
70
8F
30
40
94
80
88
41
3E
00
00
00
ENDCHAR
STARTCHAR uni06C0
ENCODING 1728
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
40
38
40
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06C1
ENCODING 1729
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
0C
13
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06C2
ENCODING 1730
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
40
38
40
00
0C
13
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06C3
ENCODING 1731
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
14
00
00
00
0C
13
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06C4
ENCODING 1732
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
0E
12
2C
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06C5
ENCODING 1733
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
0E
02
3C
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06C6
ENCODING 1734
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
08
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06C7
ENCODING 1735
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
28
18
10
20
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06C8
ENCODING 1736
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
08
08
08
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06C9
ENCODING 1737
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
14
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06CA
ENCODING 1738
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
14
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06CB
ENCODING 1739
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06CC
ENCODING 1740
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR uni06CD
ENCODING 1741
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
20
47
88
08
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR uni06CE
ENCODING 1742
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
50
20
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR uni06CF
ENCODING 1743
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uni06D0
ENCODING 1744
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
82
7C
00
08
00
08
ENDCHAR
STARTCHAR uni06D1
ENCODING 1745
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
82
7C
00
14
00
08
ENDCHAR
STARTCHAR afii57519
ENCODING 1746
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
14
60
80
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni06D3
ENCODING 1747
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
80
60
80
08
14
60
80
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni06D4
ENCODING 1748
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
3C
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii57534
ENCODING 1749
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06D6
ENCODING 1750
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
40
40
43
55
7E
80
7C
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06D7
ENCODING 1751
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
2A
20
26
2A
7C
80
7C
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06D8
ENCODING 1752
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0E
1C
60
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06D9
ENCODING 1753
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
14
08
14
18
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06DA
ENCODING 1754
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
2C
10
28
22
1C
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06DB
ENCODING 1755
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06DC
ENCODING 1756
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
15
8A
90
60
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06DD
ENCODING 1757
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
5A
A5
66
5B
81
81
81
81
81
81
5A
66
A5
5A
00
ENDCHAR
STARTCHAR uni06DE
ENCODING 1758
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
66
42
42
81
99
99
81
42
42
66
18
00
00
ENDCHAR
STARTCHAR uni06DF
ENCODING 1759
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
1C
08
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E0
ENCODING 1760
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E1
ENCODING 1761
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
26
08
70
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E2
ENCODING 1762
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
10
10
10
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E3
ENCODING 1763
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
15
8A
90
60
ENDCHAR
STARTCHAR uni06E4
ENCODING 1764
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
32
2C
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E5
ENCODING 1765
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
14
0C
04
08
30
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E6
ENCODING 1766
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
10
30
40
3E
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E7
ENCODING 1767
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
30
40
3E
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E8
ENCODING 1768
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
22
22
1C
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06E9
ENCODING 1769
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
28
54
AA
92
54
54
54
54
54
54
54
82
FE
00
00
ENDCHAR
STARTCHAR uni06EA
ENCODING 1770
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
08
14
22
14
08
ENDCHAR
STARTCHAR uni06EB
ENCODING 1771
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
14
22
14
08
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06EC
ENCODING 1772
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
3C
3C
18
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06ED
ENCODING 1773
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
0C
0C
10
10
10
ENDCHAR
STARTCHAR uni06F0
ENCODING 1776
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
44
44
38
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F1
ENCODING 1777
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
70
70
38
18
18
08
08
08
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F2
ENCODING 1778
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
44
FC
F8
60
30
30
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F3
ENCODING 1779
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
4A
FE
F4
60
30
30
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F4
ENCODING 1780
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
4E
F0
FE
7C
30
30
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F5
ENCODING 1781
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
38
2C
44
42
82
92
FE
6C
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F6
ENCODING 1782
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
60
7E
3C
30
60
40
80
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F7
ENCODING 1783
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
82
C6
C6
6C
28
38
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F8
ENCODING 1784
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
10
38
28
6C
C6
C6
82
00
00
00
00
00
ENDCHAR
STARTCHAR uni06F9
ENCODING 1785
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
F8
88
F8
78
08
0C
0E
06
00
00
00
00
00
ENDCHAR
STARTCHAR uni06FA
ENCODING 1786
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
01
15
88
88
88
72
00
00
00
00
00
ENDCHAR
STARTCHAR uni06FB
ENCODING 1787
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
09
31
9E
88
88
72
00
00
00
00
00
ENDCHAR
STARTCHAR uni06FC
ENCODING 1788
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
40
00
00
70
80
8C
70
40
80
88
80
41
3E
00
00
ENDCHAR
STARTCHAR uni06FD
ENCODING 1789
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
20
1E
20
00
14
14
14
14
00
00
ENDCHAR
STARTCHAR uni06FE
ENCODING 1790
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0C
12
12
3C
40
54
54
54
54
40
00
00
ENDCHAR
STARTCHAR m
ENCODING 4307
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
92
92
92
92
92
4C
30
4C
02
00
ENDCHAR
STARTCHAR m
ENCODING 4311
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
92
92
92
92
92
64
00
00
00
00
ENDCHAR
STARTCHAR m
ENCODING 4314
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
54
AA
AA
AA
82
82
40
30
4C
02
00
ENDCHAR
STARTCHAR m
ENCODING 4317
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
92
92
92
82
82
44
00
00
00
00
ENDCHAR
STARTCHAR m
ENCODING 4326
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
92
92
92
82
82
40
30
4C
02
00
ENDCHAR
STARTCHAR uni1E00
ENCODING 7680
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
6C
C6
C6
FE
C6
C6
C6
C6
00
38
6C
38
ENDCHAR
STARTCHAR uni1E01
ENCODING 7681
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
0C
7C
CC
CC
CC
76
00
38
6C
38
ENDCHAR
STARTCHAR uni1E02
ENCODING 7682
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
FC
66
66
66
7C
66
66
66
FC
00
00
00
00
ENDCHAR
STARTCHAR uni1E03
ENCODING 7683
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
0C
EC
60
60
78
6C
66
66
66
66
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E04
ENCODING 7684
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
66
66
66
66
FC
00
18
18
00
ENDCHAR
STARTCHAR uni1E05
ENCODING 7685
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
78
6C
66
66
66
66
7C
00
18
18
00
ENDCHAR
STARTCHAR uni1E06
ENCODING 7686
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
66
66
66
66
FC
00
7C
00
00
ENDCHAR
STARTCHAR uni1E07
ENCODING 7687
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
78
6C
66
66
66
66
7C
00
7C
00
00
ENDCHAR
STARTCHAR uni1E08
ENCODING 7688
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
3C
66
C2
C0
C0
C0
C2
66
3C
18
0C
38
00
ENDCHAR
STARTCHAR uni1E09
ENCODING 7689
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
7C
C6
C0
C0
C0
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR uni1E0A
ENCODING 7690
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
F8
6C
66
66
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR uni1E0B
ENCODING 7691
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
60
0C
0C
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1E0C
ENCODING 7692
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
66
66
66
66
6C
F8
00
30
30
00
ENDCHAR
STARTCHAR uni1E0D
ENCODING 7693
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
00
30
30
00
ENDCHAR
STARTCHAR uni1E0E
ENCODING 7694
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
66
66
66
66
6C
F8
00
7C
00
00
ENDCHAR
STARTCHAR uni1E0F
ENCODING 7695
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
00
7C
00
00
ENDCHAR
STARTCHAR uni1E10
ENCODING 7696
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
66
66
66
66
6C
F8
30
18
70
00
ENDCHAR
STARTCHAR uni1E11
ENCODING 7697
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
30
18
70
00
ENDCHAR
STARTCHAR uni1E12
ENCODING 7698
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
66
66
66
66
6C
F8
10
38
6C
00
ENDCHAR
STARTCHAR uni1E13
ENCODING 7699
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
10
38
6C
00
ENDCHAR
STARTCHAR uni1E14
ENCODING 7700
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
7C
00
FE
62
68
78
68
62
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1E15
ENCODING 7701
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
7C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E16
ENCODING 7702
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
7C
00
FE
62
68
78
68
62
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1E17
ENCODING 7703
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
7C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E18
ENCODING 7704
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
10
38
6C
00
ENDCHAR
STARTCHAR uni1E19
ENCODING 7705
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
10
38
6C
00
ENDCHAR
STARTCHAR uni1E1A
ENCODING 7706
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
00
76
DC
00
ENDCHAR
STARTCHAR uni1E1B
ENCODING 7707
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
00
76
DC
00
ENDCHAR
STARTCHAR uni1E1C
ENCODING 7708
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
FE
66
62
68
78
68
62
66
FE
18
0C
38
00
ENDCHAR
STARTCHAR uni1E1D
ENCODING 7709
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
7C
C6
FE
C0
C0
C6
7C
18
0C
38
00
ENDCHAR
STARTCHAR uni1E1E
ENCODING 7710
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
FE
66
62
68
78
68
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni1E1F
ENCODING 7711
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
38
6C
64
F0
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni1E20
ENCODING 7712
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
3C
66
C2
C0
DE
C6
C6
66
3A
00
00
00
00
ENDCHAR
STARTCHAR uni1E21
ENCODING 7713
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
76
CC
CC
CC
CC
CC
7C
0C
CC
78
00
ENDCHAR
STARTCHAR uni1E22
ENCODING 7714
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E23
ENCODING 7715
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
E0
60
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni1E24
ENCODING 7716
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1E25
ENCODING 7717
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
6C
76
66
66
66
66
E6
00
18
18
00
ENDCHAR
STARTCHAR uni1E26
ENCODING 7718
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E27
ENCODING 7719
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
E0
60
6C
76
66
66
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni1E28
ENCODING 7720
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
60
30
E0
00
ENDCHAR
STARTCHAR uni1E29
ENCODING 7721
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
6C
76
66
66
66
66
E6
30
18
70
00
ENDCHAR
STARTCHAR uni1E2A
ENCODING 7722
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
FE
C6
C6
C6
C6
C6
00
6C
38
00
ENDCHAR
STARTCHAR uni1E2B
ENCODING 7723
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
6C
76
66
66
66
66
E6
00
6C
38
00
ENDCHAR
STARTCHAR uni1E2C
ENCODING 7724
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
76
DC
00
ENDCHAR
STARTCHAR uni1E2D
ENCODING 7725
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
38
18
18
18
18
18
3C
00
76
DC
00
ENDCHAR
STARTCHAR uni1E2E
ENCODING 7726
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
66
00
3C
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1E2F
ENCODING 7727
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
66
66
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1E30
ENCODING 7728
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
E6
66
66
6C
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni1E31
ENCODING 7729
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
0C
EC
60
60
66
6C
78
78
6C
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni1E32
ENCODING 7730
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
18
18
00
ENDCHAR
STARTCHAR uni1E33
ENCODING 7731
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
66
6C
78
78
6C
66
E6
00
18
18
00
ENDCHAR
STARTCHAR uni1E34
ENCODING 7732
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
7C
00
00
ENDCHAR
STARTCHAR uni1E35
ENCODING 7733
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
66
6C
78
78
6C
66
E6
00
7C
00
00
ENDCHAR
STARTCHAR uni1E36
ENCODING 7734
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
60
60
60
62
66
FE
00
18
18
00
ENDCHAR
STARTCHAR uni1E37
ENCODING 7735
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
3C
00
18
18
00
ENDCHAR
STARTCHAR uni1E38
ENCODING 7736
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
F0
60
60
60
60
60
62
66
FE
00
18
18
00
ENDCHAR
STARTCHAR uni1E39
ENCODING 7737
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
38
18
18
18
18
18
18
18
3C
00
18
18
00
ENDCHAR
STARTCHAR uni1E3A
ENCODING 7738
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
60
60
60
62
66
FE
00
7C
00
00
ENDCHAR
STARTCHAR uni1E3B
ENCODING 7739
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
3C
00
7E
00
00
ENDCHAR
STARTCHAR uni1E3C
ENCODING 7740
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
60
60
60
62
66
FE
10
38
6C
00
ENDCHAR
STARTCHAR uni1E3D
ENCODING 7741
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
3C
10
38
6C
00
ENDCHAR
STARTCHAR uni1E3E
ENCODING 7742
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E3F
ENCODING 7743
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
EC
FE
D6
D6
D6
D6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E40
ENCODING 7744
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E41
ENCODING 7745
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
EC
FE
D6
D6
D6
D6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E42
ENCODING 7746
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1E43
ENCODING 7747
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
EC
FE
D6
D6
D6
D6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1E44
ENCODING 7748
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E45
ENCODING 7749
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
DC
66
66
66
66
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni1E46
ENCODING 7750
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1E47
ENCODING 7751
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
00
18
18
00
ENDCHAR
STARTCHAR uni1E48
ENCODING 7752
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
00
7C
00
00
ENDCHAR
STARTCHAR uni1E49
ENCODING 7753
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
00
7C
00
00
ENDCHAR
STARTCHAR uni1E4A
ENCODING 7754
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
E6
F6
FE
DE
CE
C6
C6
C6
C6
10
38
6C
00
ENDCHAR
STARTCHAR uni1E4B
ENCODING 7755
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
66
66
66
66
66
66
10
38
6C
00
ENDCHAR
STARTCHAR uni1E4C
ENCODING 7756
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
72
9C
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E4D
ENCODING 7757
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
76
DC
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E4E
ENCODING 7758
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
00
72
9C
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E4F
ENCODING 7759
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
00
76
DC
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E50
ENCODING 7760
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
7C
00
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E51
ENCODING 7761
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
7C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E52
ENCODING 7762
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
7C
00
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E53
ENCODING 7763
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
7C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E54
ENCODING 7764
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
FC
66
66
66
7C
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni1E55
ENCODING 7765
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
DC
66
66
66
66
66
7C
60
60
F0
00
ENDCHAR
STARTCHAR uni1E56
ENCODING 7766
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
FC
66
66
66
7C
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni1E57
ENCODING 7767
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
DC
66
66
66
66
66
7C
60
60
F0
00
ENDCHAR
STARTCHAR uni1E58
ENCODING 7768
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
FC
66
66
66
7C
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni1E59
ENCODING 7769
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
DC
76
66
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni1E5A
ENCODING 7770
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
6C
66
66
66
E6
00
18
18
00
ENDCHAR
STARTCHAR uni1E5B
ENCODING 7771
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
66
60
60
60
F0
00
18
18
00
ENDCHAR
STARTCHAR uni1E5C
ENCODING 7772
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
00
FC
66
66
66
7C
6C
66
66
E6
00
18
18
00
ENDCHAR
STARTCHAR uni1E5D
ENCODING 7773
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
00
DC
76
66
60
60
60
F0
00
18
18
00
ENDCHAR
STARTCHAR uni1E5E
ENCODING 7774
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
6C
66
66
66
E6
00
7C
00
00
ENDCHAR
STARTCHAR uni1E5F
ENCODING 7775
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
66
60
60
60
F0
00
7C
00
00
ENDCHAR
STARTCHAR uni1E60
ENCODING 7776
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
7C
C6
C6
60
38
0C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E61
ENCODING 7777
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E62
ENCODING 7778
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
60
38
0C
06
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1E63
ENCODING 7779
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
60
38
0C
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1E64
ENCODING 7780
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
6C
18
00
7C
C6
C6
70
1C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E65
ENCODING 7781
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
60
0C
18
00
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E66
ENCODING 7782
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
44
38
10
7C
C6
C6
70
1C
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E67
ENCODING 7783
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
44
38
10
7C
C6
60
38
0C
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E68
ENCODING 7784
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
7C
C6
C6
60
38
0C
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1E69
ENCODING 7785
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
7C
C6
60
38
0C
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1E6A
ENCODING 7786
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
7E
7E
5A
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1E6B
ENCODING 7787
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
06
16
30
30
FC
30
30
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR uni1E6C
ENCODING 7788
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
00
18
18
00
ENDCHAR
STARTCHAR uni1E6D
ENCODING 7789
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
00
18
18
00
ENDCHAR
STARTCHAR uni1E6E
ENCODING 7790
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
00
7E
00
00
ENDCHAR
STARTCHAR uni1E6F
ENCODING 7791
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
00
7E
00
00
ENDCHAR
STARTCHAR uni1E70
ENCODING 7792
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
18
18
18
18
18
3C
10
38
6C
00
ENDCHAR
STARTCHAR uni1E71
ENCODING 7793
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
30
30
FC
30
30
30
30
36
1C
08
1C
36
00
ENDCHAR
STARTCHAR uni1E72
ENCODING 7794
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
6C
6C
00
ENDCHAR
STARTCHAR uni1E73
ENCODING 7795
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
76
00
6C
6C
00
ENDCHAR
STARTCHAR uni1E74
ENCODING 7796
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
76
DC
00
ENDCHAR
STARTCHAR uni1E75
ENCODING 7797
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
76
00
76
DC
00
ENDCHAR
STARTCHAR uni1E76
ENCODING 7798
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
C6
C6
7C
10
38
6C
00
ENDCHAR
STARTCHAR uni1E77
ENCODING 7799
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
76
10
38
6C
00
ENDCHAR
STARTCHAR uni1E78
ENCODING 7800
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
72
9C
00
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E79
ENCODING 7801
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
76
DC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1E7A
ENCODING 7802
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
00
7C
00
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1E7B
ENCODING 7803
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
CC
CC
00
FC
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1E7C
ENCODING 7804
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
C6
C6
C6
C6
C6
C6
6C
38
10
00
00
00
00
ENDCHAR
STARTCHAR uni1E7D
ENCODING 7805
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
66
66
66
66
66
3C
18
00
00
00
00
ENDCHAR
STARTCHAR uni1E7E
ENCODING 7806
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
6C
38
10
00
30
30
00
ENDCHAR
STARTCHAR uni1E7F
ENCODING 7807
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
66
66
3C
18
00
18
18
00
ENDCHAR
STARTCHAR Wgrave
ENCODING 7808
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
00
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
00
00
00
ENDCHAR
STARTCHAR wgrave
ENCODING 7809
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR Wacute
ENCODING 7810
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
00
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
00
00
00
ENDCHAR
STARTCHAR wacute
ENCODING 7811
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
18
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR Wdieresis
ENCODING 7812
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
00
00
00
ENDCHAR
STARTCHAR wdieresis
ENCODING 7813
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni1E86
ENCODING 7814
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni1E87
ENCODING 7815
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni1E88
ENCODING 7816
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
D6
D6
D6
FE
EE
6C
00
30
30
00
ENDCHAR
STARTCHAR uni1E89
ENCODING 7817
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
D6
D6
D6
FE
6C
00
30
30
00
ENDCHAR
STARTCHAR uni1E8A
ENCODING 7818
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
C6
C6
6C
7C
38
7C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E8B
ENCODING 7819
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
C6
6C
38
38
38
6C
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E8C
ENCODING 7820
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
C6
C6
6C
7C
38
7C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E8D
ENCODING 7821
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
C6
6C
38
38
38
6C
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1E8E
ENCODING 7822
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1E8F
ENCODING 7823
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni1E90
ENCODING 7824
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
FE
C6
8C
18
30
60
C2
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1E91
ENCODING 7825
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
FE
CC
18
30
60
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1E92
ENCODING 7826
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
86
0C
18
30
60
C2
C6
FE
00
30
30
00
ENDCHAR
STARTCHAR uni1E93
ENCODING 7827
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
30
60
C6
FE
00
30
30
00
ENDCHAR
STARTCHAR uni1E94
ENCODING 7828
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
86
0C
18
30
60
C2
C6
FE
00
7C
00
00
ENDCHAR
STARTCHAR uni1E95
ENCODING 7829
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
CC
18
30
60
C6
FE
00
7C
00
00
ENDCHAR
STARTCHAR uni1E96
ENCODING 7830
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
60
60
6C
76
66
66
66
66
E6
00
7C
00
00
ENDCHAR
STARTCHAR uni1E97
ENCODING 7831
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
6C
00
10
30
FC
30
30
30
30
36
1C
00
00
00
00
ENDCHAR
STARTCHAR uni1E98
ENCODING 7832
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
38
00
C6
C6
D6
D6
D6
FE
6C
00
00
00
00
ENDCHAR
STARTCHAR uni1E99
ENCODING 7833
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
6C
38
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni1E9A
ENCODING 7834
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
0C
18
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1E9B
ENCODING 7835
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
00
38
6C
64
60
60
60
60
60
F0
00
00
00
00
ENDCHAR
STARTCHAR uni1EA0
ENCODING 7840
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
6C
C6
C6
FE
C6
C6
C6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1EA1
ENCODING 7841
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
78
0C
7C
CC
CC
CC
76
00
30
30
00
ENDCHAR
STARTCHAR uni1EA2
ENCODING 7842
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
0C
18
10
38
6C
C6
C6
FE
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EA3
ENCODING 7843
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
0C
18
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EA4
ENCODING 7844
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
16
38
6C
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EA5
ENCODING 7845
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
16
38
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EA6
ENCODING 7846
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
68
1C
36
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EA7
ENCODING 7847
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
68
1C
36
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EA8
ENCODING 7848
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
13
3A
6C
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EA9
ENCODING 7849
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
13
3A
6C
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EAA
ENCODING 7850
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
10
28
54
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EAB
ENCODING 7851
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
10
38
44
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EAC
ENCODING 7852
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
6C
10
38
6C
C6
C6
FE
C6
C6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1EAD
ENCODING 7853
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
78
0C
7C
CC
CC
CC
76
00
30
30
00
ENDCHAR
STARTCHAR uni1EAE
ENCODING 7854
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
44
38
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EAF
ENCODING 7855
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
18
44
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EB0
ENCODING 7856
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
44
38
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EB1
ENCODING 7857
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
30
44
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EB2
ENCODING 7858
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
08
54
38
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EB3
ENCODING 7859
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
08
54
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EB4
ENCODING 7860
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
72
9C
44
38
10
38
6C
C6
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni1EB5
ENCODING 7861
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
72
9C
44
38
00
78
0C
7C
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EB6
ENCODING 7862
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
6C
38
00
10
38
6C
C6
C6
FE
C6
C6
C6
00
30
30
00
ENDCHAR
STARTCHAR uni1EB7
ENCODING 7863
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
38
00
78
0C
7C
CC
CC
CC
76
00
30
30
00
ENDCHAR
STARTCHAR uni1EB8
ENCODING 7864
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
66
62
68
78
68
60
62
66
FE
00
18
18
00
ENDCHAR
STARTCHAR uni1EB9
ENCODING 7865
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
FE
C0
C0
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1EBA
ENCODING 7866
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
0C
18
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1EBB
ENCODING 7867
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
0C
18
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EBC
ENCODING 7868
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
00
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1EBD
ENCODING 7869
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EBE
ENCODING 7870
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
23
76
88
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1EBF
ENCODING 7871
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
26
70
D8
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EC0
ENCODING 7872
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C4
6E
11
FE
66
62
68
78
68
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1EC1
ENCODING 7873
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
64
0E
1B
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EC2
ENCODING 7874
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
13
3A
6C
00
FE
62
68
78
68
62
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1EC3
ENCODING 7875
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
13
3A
6C
00
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EC4
ENCODING 7876
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
10
38
44
FE
62
68
78
68
62
FE
00
00
00
00
ENDCHAR
STARTCHAR uni1EC5
ENCODING 7877
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
10
38
44
7C
C6
FE
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EC6
ENCODING 7878
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
FE
66
62
68
78
68
62
66
FE
00
18
18
00
ENDCHAR
STARTCHAR uni1EC7
ENCODING 7879
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
7C
C6
FE
C0
C0
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1EC8
ENCODING 7880
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
0C
18
3C
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1EC9
ENCODING 7881
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
0C
18
00
38
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1ECA
ENCODING 7882
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
18
18
00
ENDCHAR
STARTCHAR uni1ECB
ENCODING 7883
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
38
18
18
18
18
18
3C
00
18
18
00
ENDCHAR
STARTCHAR uni1ECC
ENCODING 7884
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1ECD
ENCODING 7885
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C6
C6
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1ECE
ENCODING 7886
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
0C
18
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ECF
ENCODING 7887
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
0C
18
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED0
ENCODING 7888
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
23
76
88
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED1
ENCODING 7889
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
26
70
D8
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED2
ENCODING 7890
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C4
6E
11
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED3
ENCODING 7891
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
64
0E
1B
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED4
ENCODING 7892
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
13
3A
44
7C
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED5
ENCODING 7893
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
13
3A
6C
00
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED6
ENCODING 7894
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
10
28
44
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED7
ENCODING 7895
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
76
DC
10
38
44
7C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1ED8
ENCODING 7896
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
38
44
7C
C6
C6
C6
C6
C6
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1ED9
ENCODING 7897
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
38
6C
00
7C
C6
C6
C6
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1EDA
ENCODING 7898
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
33
03
7A
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EDB
ENCODING 7899
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1B
33
06
78
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EDC
ENCODING 7900
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
33
03
7A
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EDD
ENCODING 7901
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
63
33
06
78
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EDE
ENCODING 7902
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
70
1B
33
7A
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EDF
ENCODING 7903
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
1B
33
06
78
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EE0
ENCODING 7904
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
68
B3
03
7A
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EE1
ENCODING 7905
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
68
B3
03
06
78
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EE2
ENCODING 7906
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
03
7A
CC
CC
CC
CC
CC
CC
CC
CC
78
00
30
30
00
ENDCHAR
STARTCHAR uni1EE3
ENCODING 7907
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
06
78
CC
CC
CC
CC
CC
78
00
30
30
00
ENDCHAR
STARTCHAR uni1EE4
ENCODING 7908
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
30
30
00
ENDCHAR
STARTCHAR uni1EE5
ENCODING 7909
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
CC
CC
CC
CC
CC
76
00
30
30
00
ENDCHAR
STARTCHAR uni1EE6
ENCODING 7910
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
0C
18
C6
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni1EE7
ENCODING 7911
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
18
30
00
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EE8
ENCODING 7912
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
33
03
CE
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EE9
ENCODING 7913
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1B
33
06
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EEA
ENCODING 7914
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
33
03
CE
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EEB
ENCODING 7915
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
63
33
06
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EEC
ENCODING 7916
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
70
1B
33
CE
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EED
ENCODING 7917
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
1B
33
06
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EEE
ENCODING 7918
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
68
B3
03
CE
CC
CC
CC
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni1EEF
ENCODING 7919
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
68
B3
03
06
CC
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1EF0
ENCODING 7920
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
03
CE
CC
CC
CC
CC
CC
CC
CC
CC
78
00
30
30
00
ENDCHAR
STARTCHAR uni1EF1
ENCODING 7921
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
06
CC
CC
CC
CC
CC
CC
76
00
30
30
00
ENDCHAR
STARTCHAR Ygrave
ENCODING 7922
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
18
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR ygrave
ENCODING 7923
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
30
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni1EF4
ENCODING 7924
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
3C
18
18
18
18
3C
00
18
18
00
ENDCHAR
STARTCHAR uni1EF5
ENCODING 7925
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
C6
C6
C6
C6
7E
0C
18
F6
06
00
ENDCHAR
STARTCHAR uni1EF6
ENCODING 7926
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
0C
18
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1EF7
ENCODING 7927
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
0C
18
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni1EF8
ENCODING 7928
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
3A
5C
00
66
66
66
3C
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni1EF9
ENCODING 7929
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
76
DC
00
C6
C6
C6
C6
C6
C6
7E
06
0C
F8
00
ENDCHAR
STARTCHAR uni1F00
ENCODING 7936
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
30
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F01
ENCODING 7937
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
30
18
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F02
ENCODING 7938
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
6C
C6
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F03
ENCODING 7939
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
CC
66
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F04
ENCODING 7940
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
66
CC
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F05
ENCODING 7941
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C6
6C
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F06
ENCODING 7942
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
34
58
0C
18
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni1F07
ENCODING 7943
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
34
58
30
18
00
76
CC
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8192
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
A4
AA
EA
EA
A6
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8193
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
A4
EA
AA
AA
A6
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8194
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
EA
8A
CE
8E
EA
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8195
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
EA
8E
CA
8A
EA
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8196
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
CA
2E
4A
2A
CA
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8197
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
AA
AE
EA
2A
2A
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8198
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
6A
8E
CA
AA
4A
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8199
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
38
20
30
20
20
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8200
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
30
28
30
20
20
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8201
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
EA
4A
4E
4A
4A
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8202
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
28
28
38
28
28
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8203
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
EA
2A
4E
8E
EE
00
6C
8A
4C
28
C8
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8204
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
EA
2A
4E
8E
EE
00
A2
A2
E2
EA
A4
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8205
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
EA
2A
4E
8E
EE
00
08
08
08
28
10
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8206
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
80
80
80
F0
28
30
28
0A
0E
0E
0A
00
FE
00
ENDCHAR
STARTCHAR uni2409
ENCODING 8207
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
00
C0
A0
C0
A0
20
20
38
0A
0E
0E
0A
00
FE
00
ENDCHAR
STARTCHAR uni2010
ENCODING 8208
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7C
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2011
ENCODING 8209
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
9C
D2
BC
92
9C
00
3C
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR figuredash
ENCODING 8210
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7E
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR endash
ENCODING 8211
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7E
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR emdash
ENCODING 8212
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR afii00208
ENCODING 8213
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2016
ENCODING 8214
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
6C
6C
6C
6C
6C
6C
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR underscoredbl
ENCODING 8215
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
FE
00
FE
00
ENDCHAR
STARTCHAR quoteleft
ENCODING 8216
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
30
30
30
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR quoteright
ENCODING 8217
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
18
18
30
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR quotesinglbase
ENCODING 8218
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
18
18
18
30
00
00
ENDCHAR
STARTCHAR quotereversed
ENCODING 8219
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
30
30
18
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR quotedblleft
ENCODING 8220
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
66
CC
CC
CC
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR quotedblright
ENCODING 8221
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
66
66
66
CC
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR quotedblbase
ENCODING 8222
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
66
66
66
CC
00
00
ENDCHAR
STARTCHAR uni201F
ENCODING 8223
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
CC
CC
CC
66
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR dagger
ENCODING 8224
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
7E
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR daggerdbl
ENCODING 8225
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
7E
18
18
7E
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR bullet
ENCODING 8226
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
18
3C
3C
18
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2023
ENCODING 8227
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
20
30
38
3C
38
30
20
00
00
00
00
00
ENDCHAR
STARTCHAR onedotenleader
ENCODING 8228
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR twodotenleader
ENCODING 8229
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
66
66
00
00
00
00
ENDCHAR
STARTCHAR ellipsis
ENCODING 8230
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
DB
DB
00
00
00
00
ENDCHAR
STARTCHAR uni2027
ENCODING 8231
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
18
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR perthousand
ENCODING 8240
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C6
0C
18
30
60
C0
36
36
00
00
00
00
ENDCHAR
STARTCHAR uni2031
ENCODING 8241
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C6
0C
18
30
60
C0
6B
6B
00
00
00
00
ENDCHAR
STARTCHAR minute
ENCODING 8242
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
10
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR second
ENCODING 8243
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
48
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2034
ENCODING 8244
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
92
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2035
ENCODING 8245
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
08
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2036
ENCODING 8246
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
24
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2037
ENCODING 8247
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
49
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2038
ENCODING 8248
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
10
38
6C
C6
00
ENDCHAR
STARTCHAR guilsinglleft
ENCODING 8249
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0C
18
30
60
30
18
0C
00
00
00
00
00
ENDCHAR
STARTCHAR guilsinglright
ENCODING 8250
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
60
30
18
0C
18
30
60
00
00
00
00
00
ENDCHAR
STARTCHAR uni203B
ENCODING 8251
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
92
44
28
92
28
44
92
00
00
00
00
00
ENDCHAR
STARTCHAR exclamdbl
ENCODING 8252
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
66
66
66
66
66
00
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni203D
ENCODING 8253
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
C3
DB
1B
1E
1C
18
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni203E
ENCODING 8254
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
FE
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni203F
ENCODING 8255
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
82
7C
00
00
ENDCHAR
STARTCHAR uni2040
ENCODING 8256
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
7C
82
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2041
ENCODING 8257
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
06
0C
18
38
6C
00
ENDCHAR
STARTCHAR uni2042
ENCODING 8258
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
38
28
00
00
44
EE
AA
00
00
00
00
00
ENDCHAR
STARTCHAR uni2043
ENCODING 8259
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
3C
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR fraction
ENCODING 8260
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
06
0C
0C
18
18
30
30
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni2045
ENCODING 8261
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
30
30
30
3C
30
30
30
30
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2046
ENCODING 8262
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
0C
0C
0C
3C
0C
0C
0C
0C
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2048
ENCODING 8264
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7B
CF
CF
1B
33
33
33
00
33
33
00
00
00
00
ENDCHAR
STARTCHAR uni2049
ENCODING 8265
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DE
F3
F3
C6
CC
CC
CC
00
CC
CC
00
00
00
00
ENDCHAR
STARTCHAR uni204A
ENCODING 8266
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7E
7E
06
06
0C
0C
00
00
00
ENDCHAR
STARTCHAR uni204B
ENCODING 8267
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
DB
DB
DB
DE
D8
D8
D8
D8
D8
00
00
00
00
ENDCHAR
STARTCHAR uni204C
ENCODING 8268
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
3E
72
F2
F2
F2
72
3E
00
00
00
00
00
ENDCHAR
STARTCHAR uni204D
ENCODING 8269
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
F8
9C
9E
9E
9E
9C
F8
00
00
00
00
00
ENDCHAR
STARTCHAR zerosuperior
ENCODING 8304
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D8
D8
D8
D8
70
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR foursuperior
ENCODING 8308
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
18
38
78
D8
FC
18
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR fivesuperior
ENCODING 8309
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
F8
C0
F0
18
D8
70
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR sixsuperior
ENCODING 8310
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
78
C0
F0
D8
D8
70
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR sevensuperior
ENCODING 8311
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
F8
D8
30
30
60
60
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR eightsuperior
ENCODING 8312
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D8
70
D8
D8
70
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR ninesuperior
ENCODING 8313
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D8
D8
78
18
F0
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni207A
ENCODING 8314
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
30
FC
30
30
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni207B
ENCODING 8315
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FC
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni207C
ENCODING 8316
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
00
FC
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR parenleftsuperior
ENCODING 8317
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
60
60
60
60
30
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR parenrightsuperior
ENCODING 8318
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
60
30
30
30
30
60
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR nsuperior
ENCODING 8319
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
B0
D8
D8
D8
D8
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR zeroinferior
ENCODING 8320
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
70
D8
D8
D8
D8
70
00
00
00
ENDCHAR
STARTCHAR oneinferior
ENCODING 8321
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
30
70
30
30
30
78
00
00
00
ENDCHAR
STARTCHAR twoinferior
ENCODING 8322
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
70
D8
30
60
C8
F8
00
00
00
ENDCHAR
STARTCHAR threeinferior
ENCODING 8323
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
70
D8
30
18
D8
70
00
00
00
ENDCHAR
STARTCHAR fourinferior
ENCODING 8324
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
18
38
78
D8
FC
18
00
00
00
ENDCHAR
STARTCHAR fiveinferior
ENCODING 8325
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
F8
C0
F0
18
D8
70
00
00
00
ENDCHAR
STARTCHAR sixinferior
ENCODING 8326
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
78
C0
F0
D8
D8
70
00
00
00
ENDCHAR
STARTCHAR seveninferior
ENCODING 8327
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
F8
D8
30
30
60
60
00
00
00
ENDCHAR
STARTCHAR eightinferior
ENCODING 8328
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
70
D8
70
D8
D8
70
00
00
00
ENDCHAR
STARTCHAR nineinferior
ENCODING 8329
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
70
D8
D8
78
18
F0
00
00
00
ENDCHAR
STARTCHAR uni208A
ENCODING 8330
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
30
30
FC
30
30
00
00
00
00
ENDCHAR
STARTCHAR uni208B
ENCODING 8331
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
FC
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni208C
ENCODING 8332
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
FC
00
FC
00
00
00
00
00
ENDCHAR
STARTCHAR parenleftinferior
ENCODING 8333
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
30
60
60
60
60
30
00
00
00
ENDCHAR
STARTCHAR parenrightinferior
ENCODING 8334
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
60
30
30
30
30
60
00
00
00
ENDCHAR
STARTCHAR uni208F
ENCODING 8335
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
B0
D8
D8
D8
D8
00
00
00
ENDCHAR
STARTCHAR uni20A0
ENCODING 8352
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
C0
CF
CC
CC
7F
0C
0C
0F
00
00
00
00
ENDCHAR
STARTCHAR colonmonetary
ENCODING 8353
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
04
7C
CE
C8
C8
D0
D0
D0
E0
E6
7C
40
40
00
00
ENDCHAR
STARTCHAR uni20A2
ENCODING 8354
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C0
C0
D6
D8
D8
D8
DE
7C
00
00
00
00
ENDCHAR
STARTCHAR franc
ENCODING 8355
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
C0
C0
C0
F0
CD
CE
CC
CC
CC
00
00
00
00
ENDCHAR
STARTCHAR lira
ENCODING 8356
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
60
F8
60
F8
60
60
E6
FC
00
00
00
00
ENDCHAR
STARTCHAR uni20A5
ENCODING 8357
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
02
EC
D6
DE
D6
D6
F6
D6
40
00
00
00
ENDCHAR
STARTCHAR uni20A6
ENCODING 8358
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
66
76
FF
76
6E
FF
6E
66
66
00
00
00
00
ENDCHAR
STARTCHAR peseta
ENCODING 8359
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
7C
62
66
6F
66
66
F3
00
00
00
00
ENDCHAR
STARTCHAR uni20A8
ENCODING 8360
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
CC
CC
CC
F8
E0
F3
D6
DB
CE
00
00
00
00
ENDCHAR
STARTCHAR uni20A9
ENCODING 8361
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
81
81
81
5A
FF
5A
FF
24
24
24
00
00
00
00
ENDCHAR
STARTCHAR afii57636
ENCODING 8362
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
F2
8A
AA
AA
AA
AA
A2
BC
00
00
00
00
ENDCHAR
STARTCHAR dong
ENCODING 8363
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
3E
0C
3C
6C
CC
CC
CC
CC
76
00
7C
00
00
ENDCHAR
STARTCHAR Euro
ENCODING 8364
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
36
60
FC
60
F8
60
60
36
1C
00
00
00
00
ENDCHAR
STARTCHAR uni20AD
ENCODING 8365
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
6C
78
FE
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni20AE
ENCODING 8366
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
7E
5A
18
1E
78
1E
78
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni20AF
ENCODING 8367
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
7C
B6
36
33
33
33
63
66
F6
DC
00
00
00
00
ENDCHAR
STARTCHAR uni2100
ENCODING 8448
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D0
D2
D6
7C
18
30
6E
D8
98
18
0E
00
00
00
ENDCHAR
STARTCHAR uni2101
ENCODING 8449
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
D0
D2
D6
7C
18
30
6E
D8
8C
06
1C
00
00
00
ENDCHAR
STARTCHAR uni2102
ENCODING 8450
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
62
A0
A0
A0
A0
A0
A0
62
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2103
ENCODING 8451
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
4E
B9
58
18
18
18
18
18
19
0E
00
00
00
00
ENDCHAR
STARTCHAR uni2104
ENCODING 8452
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
7C
DA
D8
D8
DA
7C
19
3F
00
00
00
00
ENDCHAR
STARTCHAR afii61248
ENCODING 8453
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
C0
C2
C6
7C
18
30
6E
DB
9B
1B
0E
00
00
00
ENDCHAR
STARTCHAR uni2106
ENCODING 8454
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
70
C0
C2
C6
7C
18
30
7B
DB
9B
1B
0D
00
00
00
ENDCHAR
STARTCHAR uni2107
ENCODING 8455
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C2
C0
78
C0
C0
C2
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni2108
ENCODING 8456
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
86
26
3E
26
06
86
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni2109
ENCODING 8457
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7F
B9
58
1A
1E
1A
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni210A
ENCODING 8458
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
1A
66
46
87
8C
8C
7C
98
98
70
00
ENDCHAR
STARTCHAR uni210B
ENCODING 8459
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
52
B5
15
16
2C
34
68
A9
AA
4C
00
00
00
00
ENDCHAR
STARTCHAR uni210C
ENCODING 8460
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
48
B0
80
48
7C
66
26
26
A6
46
06
34
48
00
ENDCHAR
STARTCHAR uni210D
ENCODING 8461
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E2
A2
A2
A2
BE
A2
A2
A2
A2
E2
00
00
00
00
ENDCHAR
STARTCHAR uni210E
ENCODING 8462
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
36
3B
3B
33
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni210F
ENCODING 8463
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
1E
18
76
3B
3B
33
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni2110
ENCODING 8464
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
33
4E
06
06
0C
0C
1F
6C
88
70
00
00
00
00
ENDCHAR
STARTCHAR Ifraktur
ENCODING 8465
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
71
8E
04
0C
06
03
63
C3
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2112
ENCODING 8466
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
46
49
39
1E
18
30
70
B1
BA
6C
00
00
00
00
ENDCHAR
STARTCHAR afii61289
ENCODING 8467
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
19
31
32
64
68
70
E1
66
38
00
00
00
00
ENDCHAR
STARTCHAR uni2114
ENCODING 8468
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D8
FF
D8
DE
DB
DB
DB
DB
DB
DE
00
00
00
00
ENDCHAR
STARTCHAR uni2115
ENCODING 8469
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E2
A2
B2
B2
AA
AA
A6
A6
A2
E2
00
00
00
00
ENDCHAR
STARTCHAR afii61352
ENCODING 8470
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
CC
CF
ED
FF
FC
DF
CC
CC
CC
CC
00
00
00
00
ENDCHAR
STARTCHAR uni2117
ENCODING 8471
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
B9
A5
A5
B9
A1
A1
42
3C
00
00
00
00
ENDCHAR
STARTCHAR weierstrass
ENCODING 8472
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
40
8E
93
A3
63
4B
6A
A4
B0
B0
60
00
ENDCHAR
STARTCHAR uni2119
ENCODING 8473
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
A2
A2
A2
A2
BC
A0
A0
A0
E0
00
00
00
00
ENDCHAR
STARTCHAR uni211A
ENCODING 8474
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
A2
A2
A2
A2
A2
A2
AA
A6
7E
01
00
00
00
ENDCHAR
STARTCHAR uni211B
ENCODING 8475
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
4D
4D
19
1E
1C
34
34
B5
62
00
00
00
00
ENDCHAR
STARTCHAR Rfraktur
ENCODING 8476
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
58
A6
A3
6C
B8
26
26
26
A7
C2
00
00
00
00
ENDCHAR
STARTCHAR uni211D
ENCODING 8477
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
A2
A2
A2
A2
BC
B0
A8
A4
E2
00
00
00
00
ENDCHAR
STARTCHAR prescription
ENCODING 8478
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FC
66
66
66
7C
6C
6D
67
66
EE
08
00
00
00
ENDCHAR
STARTCHAR uni211F
ENCODING 8479
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
0C
FC
C6
C6
C6
FC
D8
DC
DC
E6
E6
20
00
00
00
ENDCHAR
STARTCHAR uni2120
ENCODING 8480
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
71
DB
35
D1
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2121
ENCODING 8481
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FE
52
5A
52
5F
00
00
00
00
ENDCHAR
STARTCHAR trademark
ENCODING 8482
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F1
5B
55
51
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2123
ENCODING 8483
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
18
CE
D6
D6
D6
D6
D6
E6
6C
38
50
40
00
00
00
ENDCHAR
STARTCHAR uni2124
ENCODING 8484
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
0A
14
14
28
28
50
50
A0
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2125
ENCODING 8485
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
9C
30
FE
0C
18
38
0C
06
06
C6
C6
7C
00
ENDCHAR
STARTCHAR Omega
ENCODING 8486
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
C6
C6
C6
C6
C6
6C
6C
6C
EE
00
00
00
00
ENDCHAR
STARTCHAR uni2127
ENCODING 8487
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
EE
6C
6C
6C
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni2128
ENCODING 8488
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
26
03
13
0C
13
03
03
66
98
00
00
00
00
ENDCHAR
STARTCHAR uni2129
ENCODING 8489
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
18
18
18
18
1C
18
00
00
00
00
ENDCHAR
STARTCHAR uni212A
ENCODING 8490
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E6
66
66
6C
78
78
6C
66
66
E6
00
00
00
00
ENDCHAR
STARTCHAR uni212B
ENCODING 8491
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
6C
38
10
38
38
6C
6C
C6
FE
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni212C
ENCODING 8492
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
2D
2D
1A
1E
1B
31
31
B2
6C
00
00
00
00
ENDCHAR
STARTCHAR uni212D
ENCODING 8493
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
14
6B
C8
CC
C6
C6
CC
C0
63
1C
00
00
00
00
ENDCHAR
STARTCHAR estimated
ENCODING 8494
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
E7
FF
E0
67
3E
00
00
00
00
ENDCHAR
STARTCHAR uni212F
ENCODING 8495
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
1C
26
44
F8
C0
C8
70
00
00
00
00
ENDCHAR
STARTCHAR uni2130
ENCODING 8496
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
4C
52
3C
10
3C
60
C0
C3
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni2131
ENCODING 8497
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
73
CE
18
3A
5C
18
30
30
B0
60
00
00
00
00
ENDCHAR
STARTCHAR uni2132
ENCODING 8498
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
0C
0C
0C
2C
3C
2C
8C
CC
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2133
ENCODING 8499
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
12
12
12
16
36
3E
3A
5A
52
91
00
00
00
00
ENDCHAR
STARTCHAR uni2134
ENCODING 8500
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
1C
26
46
C6
C4
C8
70
00
00
00
00
ENDCHAR
STARTCHAR aleph
ENCODING 8501
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
42
C6
E7
7A
38
5C
CE
E7
63
E2
00
00
00
00
ENDCHAR
STARTCHAR uni2136
ENCODING 8502
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
FC
7E
06
06
06
06
0C
7E
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2137
ENCODING 8503
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
40
78
3C
0C
0C
0C
0C
1E
7E
F2
00
00
00
00
ENDCHAR
STARTCHAR uni2138
ENCODING 8504
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
FE
7E
0C
0C
0C
0C
0C
1C
18
00
00
00
00
ENDCHAR
STARTCHAR uni2139
ENCODING 8505
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
38
00
78
38
38
38
38
38
7C
00
00
00
00
ENDCHAR
STARTCHAR uni213A
ENCODING 8506
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7D
FF
83
86
82
FE
7C
00
00
00
00
ENDCHAR
STARTCHAR onethird
ENCODING 8531
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
60
DC
86
1C
06
1C
00
00
ENDCHAR
STARTCHAR twothirds
ENCODING 8532
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
30
62
C6
FC
18
30
60
DC
86
1C
06
1C
00
00
ENDCHAR
STARTCHAR uni2155
ENCODING 8533
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
60
DE
98
1C
06
1C
00
00
ENDCHAR
STARTCHAR uni2156
ENCODING 8534
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
30
62
C6
FC
18
30
60
DE
98
1C
06
1C
00
00
ENDCHAR
STARTCHAR uni2157
ENCODING 8535
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
30
62
36
EC
18
30
60
DE
98
1C
06
1C
00
00
ENDCHAR
STARTCHAR uni2158
ENCODING 8536
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
70
B2
F6
3C
18
30
60
DE
98
1C
06
1C
00
00
ENDCHAR
STARTCHAR uni2159
ENCODING 8537
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
60
DC
B0
3C
36
1C
00
00
ENDCHAR
STARTCHAR uni215A
ENCODING 8538
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
F0
C0
E2
36
EC
18
30
60
DC
B0
3C
36
1C
00
00
ENDCHAR
STARTCHAR oneeighth
ENCODING 8539
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
60
DC
B6
1C
36
1C
00
00
ENDCHAR
STARTCHAR threeeighths
ENCODING 8540
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
30
62
36
EC
18
30
60
DC
B6
1C
36
1C
00
00
ENDCHAR
STARTCHAR fiveeighths
ENCODING 8541
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
F0
80
E2
36
EC
18
30
60
DC
B6
1C
36
1C
00
00
ENDCHAR
STARTCHAR seveneighths
ENCODING 8542
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
F0
30
62
66
6C
18
30
60
DC
B6
1C
36
1C
00
00
ENDCHAR
STARTCHAR uni215F
ENCODING 8543
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
C2
C6
CC
18
30
60
C0
80
00
00
00
00
00
ENDCHAR
STARTCHAR uni2160
ENCODING 8544
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2161
ENCODING 8545
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
6C
6C
6C
6C
6C
6C
6C
6C
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2162
ENCODING 8546
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
DB
DB
DB
DB
DB
DB
DB
DB
FF
00
00
00
00
ENDCHAR
STARTCHAR uni2163
ENCODING 8547
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
DB
DB
DB
DB
DB
CE
CE
C4
00
00
00
00
ENDCHAR
STARTCHAR uni2164
ENCODING 8548
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
C6
C6
C6
C6
C6
6C
38
10
00
00
00
00
ENDCHAR
STARTCHAR uni2165
ENCODING 8549
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
DB
DB
DB
DB
DB
73
73
23
00
00
00
00
ENDCHAR
STARTCHAR uni2166
ENCODING 8550
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
95
95
95
95
95
95
95
65
65
65
00
00
00
00
ENDCHAR
STARTCHAR uni2167
ENCODING 8551
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
B5
B5
B5
B5
B5
B5
55
55
55
55
00
00
00
00
ENDCHAR
STARTCHAR uni2168
ENCODING 8552
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
DB
CE
CE
CE
DB
DB
DB
DB
00
00
00
00
ENDCHAR
STARTCHAR uni2169
ENCODING 8553
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
6C
7C
38
38
7C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni216A
ENCODING 8554
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
DB
73
73
73
DB
DB
DB
DB
00
00
00
00
ENDCHAR
STARTCHAR uni216B
ENCODING 8555
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
95
95
95
65
65
65
95
95
95
95
00
00
00
00
ENDCHAR
STARTCHAR uni216C
ENCODING 8556
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
60
60
60
60
60
60
62
66
FE
00
00
00
00
ENDCHAR
STARTCHAR uni216D
ENCODING 8557
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
C2
C0
C0
C0
C0
C2
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni216E
ENCODING 8558
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
6C
66
66
66
66
66
66
6C
F8
00
00
00
00
ENDCHAR
STARTCHAR uni216F
ENCODING 8559
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
EE
FE
FE
D6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni2170
ENCODING 8560
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2171
ENCODING 8561
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
00
6C
6C
6C
6C
6C
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR uni2172
ENCODING 8562
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
DB
DB
00
DB
DB
DB
DB
DB
DB
DB
00
00
00
00
ENDCHAR
STARTCHAR uni2173
ENCODING 8563
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
00
DB
DB
DB
DB
DB
CE
C4
00
00
00
00
ENDCHAR
STARTCHAR uni2174
ENCODING 8564
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
66
66
66
3C
18
00
00
00
00
ENDCHAR
STARTCHAR uni2175
ENCODING 8565
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
00
DB
DB
DB
DB
DB
73
23
00
00
00
00
ENDCHAR
STARTCHAR uni2176
ENCODING 8566
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
05
05
00
95
95
95
95
95
65
65
00
00
00
00
ENDCHAR
STARTCHAR uni2177
ENCODING 8567
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
15
15
00
B5
B5
B5
B5
55
55
55
00
00
00
00
ENDCHAR
STARTCHAR uni2178
ENCODING 8568
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
00
DB
DB
CE
CE
CE
DB
DB
00
00
00
00
ENDCHAR
STARTCHAR uni2179
ENCODING 8569
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
6C
38
38
38
6C
C6
00
00
00
00
ENDCHAR
STARTCHAR uni217A
ENCODING 8570
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
00
DB
DB
73
73
73
DB
DB
00
00
00
00
ENDCHAR
STARTCHAR uni217B
ENCODING 8571
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
05
05
00
95
95
65
65
95
95
95
00
00
00
00
ENDCHAR
STARTCHAR uni217C
ENCODING 8572
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
18
18
18
18
18
18
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni217D
ENCODING 8573
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
7C
C6
C0
C0
C0
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR uni217E
ENCODING 8574
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
0C
0C
3C
6C
CC
CC
CC
CC
76
00
00
00
00
ENDCHAR
STARTCHAR uni217F
ENCODING 8575
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
EC
FE
D6
D6
D6
D6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni2180
ENCODING 8576
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
5A
DB
DB
DB
DB
DB
DB
5A
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2181
ENCODING 8577
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
CC
E6
D6
D6
D6
D6
E6
CC
F8
00
00
00
00
ENDCHAR
STARTCHAR uni2182
ENCODING 8578
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
5A
99
BD
DB
DB
BD
99
5A
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2183
ENCODING 8579
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
CC
86
06
06
06
06
86
CC
78
00
00
00
00
ENDCHAR
STARTCHAR arrowleft
ENCODING 8592
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
30
60
FF
60
30
00
00
00
00
00
00
ENDCHAR
STARTCHAR arrowup
ENCODING 8593
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
7E
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR arrowright
ENCODING 8594
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
06
FF
06
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR arrowdown
ENCODING 8595
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
7E
3C
18
00
00
00
00
ENDCHAR
STARTCHAR arrowboth
ENCODING 8596
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
24
66
FF
66
24
00
00
00
00
00
00
ENDCHAR
STARTCHAR arrowupdn
ENCODING 8597
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
7E
18
18
18
7E
3C
18
00
00
00
00
00
ENDCHAR
STARTCHAR uni2196
ENCODING 8598
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
F0
E0
B0
18
0C
06
03
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2197
ENCODING 8599
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
0F
07
0D
18
30
60
C0
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2198
ENCODING 8600
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C0
60
30
18
0D
07
0F
00
00
00
00
00
ENDCHAR
STARTCHAR uni2199
ENCODING 8601
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
03
06
0C
18
B0
E0
F0
00
00
00
00
00
ENDCHAR
STARTCHAR uni219A
ENCODING 8602
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
32
62
FF
64
34
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni219B
ENCODING 8603
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
2C
26
FF
46
4C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni219C
ENCODING 8604
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
E0
CE
BB
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni219D
ENCODING 8605
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
07
73
DD
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni219E
ENCODING 8606
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
36
6C
FF
6C
36
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni219F
ENCODING 8607
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
7E
18
3C
7E
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni21A0
ENCODING 8608
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
6C
36
FF
36
6C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21A1
ENCODING 8609
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
7E
3C
18
7E
3C
18
00
00
00
00
ENDCHAR
STARTCHAR uni21A2
ENCODING 8610
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
33
66
FC
66
33
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21A3
ENCODING 8611
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
66
3F
66
CC
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21A4
ENCODING 8612
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
33
63
FF
63
33
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21A5
ENCODING 8613
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
7E
18
18
18
18
18
18
7E
00
00
00
00
ENDCHAR
STARTCHAR uni21A6
ENCODING 8614
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
CC
C6
FF
C6
CC
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21A7
ENCODING 8615
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
18
18
18
18
18
18
7E
3C
18
00
00
00
00
ENDCHAR
STARTCHAR arrowupdnbse
ENCODING 8616
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
7E
18
18
18
7E
3C
18
7E
00
00
00
00
ENDCHAR
STARTCHAR uni21A9
ENCODING 8617
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
33
63
FE
60
30
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21AA
ENCODING 8618
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
60
CC
C6
7F
06
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21AB
ENCODING 8619
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
3B
6B
FE
68
30
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21AC
ENCODING 8620
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
60
DC
D6
7F
16
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21AD
ENCODING 8621
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
24
5A
FF
66
24
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21AE
ENCODING 8622
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
2C
6E
FF
76
34
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21AF
ENCODING 8623
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
30
60
63
FF
C6
16
1C
1C
1E
00
00
00
00
ENDCHAR
STARTCHAR uni21B0
ENCODING 8624
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
30
60
FE
66
36
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni21B1
ENCODING 8625
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
0C
FE
CC
D8
C0
C0
C0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni21B2
ENCODING 8626
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
06
06
06
06
36
66
FE
60
30
00
00
00
00
ENDCHAR
STARTCHAR uni21B3
ENCODING 8627
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C0
C0
C0
D8
CC
FE
0C
18
00
00
00
00
ENDCHAR
STARTCHAR uni21B4
ENCODING 8628
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FC
0C
0C
3F
1E
0C
00
00
00
ENDCHAR
STARTCHAR carriagereturn
ENCODING 8629
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
06
36
66
FE
60
30
00
00
00
00
ENDCHAR
STARTCHAR uni21B6
ENCODING 8630
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
1E
33
33
33
30
FC
78
30
00
00
00
00
ENDCHAR
STARTCHAR uni21B7
ENCODING 8631
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
78
CC
CC
CC
0C
3F
1E
0C
00
00
00
00
ENDCHAR
STARTCHAR uni21B8
ENCODING 8632
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
00
F0
E0
B0
18
0C
06
03
00
00
00
00
00
ENDCHAR
STARTCHAR uni21B9
ENCODING 8633
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
98
B0
FF
B0
98
19
0D
FF
0D
19
00
00
00
00
ENDCHAR
STARTCHAR uni21BA
ENCODING 8634
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
1E
1C
16
03
C3
C3
C3
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni21BB
ENCODING 8635
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
78
38
68
C0
C3
C3
C3
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni21BC
ENCODING 8636
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
30
60
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21BD
ENCODING 8637
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
60
30
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21BE
ENCODING 8638
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
1C
1E
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni21BF
ENCODING 8639
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
38
78
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni21C0
ENCODING 8640
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
06
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21C1
ENCODING 8641
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
06
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21C2
ENCODING 8642
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
1E
1C
18
00
00
00
00
ENDCHAR
STARTCHAR uni21C3
ENCODING 8643
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
78
38
18
00
00
00
00
ENDCHAR
STARTCHAR uni21C4
ENCODING 8644
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
06
FF
06
0C
30
60
FF
60
30
00
00
00
00
ENDCHAR
STARTCHAR uni21C5
ENCODING 8645
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
2E
3F
24
24
24
24
FC
74
24
00
00
00
00
ENDCHAR
STARTCHAR uni21C6
ENCODING 8646
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
60
FF
60
30
0C
06
FF
06
0C
00
00
00
00
ENDCHAR
STARTCHAR uni21C7
ENCODING 8647
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
60
FE
60
30
00
30
60
FE
60
30
00
00
00
ENDCHAR
STARTCHAR uni21C8
ENCODING 8648
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
7E
FF
24
24
24
24
24
24
24
00
00
00
00
ENDCHAR
STARTCHAR uni21C9
ENCODING 8649
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
0C
FE
0C
18
00
18
0C
FE
0C
18
00
00
00
ENDCHAR
STARTCHAR uni21CA
ENCODING 8650
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
24
24
24
24
24
24
FF
7E
24
00
00
00
00
ENDCHAR
STARTCHAR uni21CB
ENCODING 8651
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
30
60
FF
00
FF
06
0C
00
00
00
00
00
ENDCHAR
STARTCHAR uni21CC
ENCODING 8652
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0C
06
FF
00
FF
60
30
00
00
00
00
00
ENDCHAR
STARTCHAR uni21CD
ENCODING 8653
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
22
7F
C4
7F
24
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21CE
ENCODING 8654
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
2C
7E
CB
7E
34
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21CF
ENCODING 8655
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
24
FE
23
FE
44
00
00
00
00
00
00
ENDCHAR
STARTCHAR arrowdblleft
ENCODING 8656
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
20
7F
C0
7F
20
00
00
00
00
00
00
ENDCHAR
STARTCHAR arrowdblup
ENCODING 8657
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
7C
EE
6C
6C
6C
6C
6C
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR arrowdblright
ENCODING 8658
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
FE
03
FE
04
00
00
00
00
00
00
ENDCHAR
STARTCHAR arrowdbldown
ENCODING 8659
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
6C
6C
6C
6C
6C
EE
7C
38
00
00
00
00
ENDCHAR
STARTCHAR arrowdblboth
ENCODING 8660
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
24
7E
C3
7E
24
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21D5
ENCODING 8661
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
7C
EE
6C
6C
6C
6C
EE
7C
38
00
00
00
00
ENDCHAR
STARTCHAR uni21D6
ENCODING 8662
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
F0
E0
B0
D8
EC
B6
1B
0C
04
00
00
00
00
ENDCHAR
STARTCHAR uni21D7
ENCODING 8663
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
0F
07
0D
1B
37
6D
D8
30
20
00
00
00
00
ENDCHAR
STARTCHAR uni21D8
ENCODING 8664
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
20
30
D8
6D
37
1B
0D
07
0F
00
00
00
00
ENDCHAR
STARTCHAR uni21D9
ENCODING 8665
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
0C
1B
B6
EC
D8
B0
E0
F0
00
00
00
00
ENDCHAR
STARTCHAR uni21DA
ENCODING 8666
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
3F
60
FF
60
3F
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni21DB
ENCODING 8667
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
FC
06
FF
06
FC
08
00
00
00
00
00
ENDCHAR
STARTCHAR uni21DC
ENCODING 8668
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
30
6A
FF
65
30
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21DD
ENCODING 8669
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
A6
FF
56
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21DE
ENCODING 8670
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
7E
18
18
3C
18
3C
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni21DF
ENCODING 8671
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
3C
18
3C
18
18
7E
3C
18
00
00
00
00
ENDCHAR
STARTCHAR uni21E0
ENCODING 8672
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
30
60
D5
60
30
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21E1
ENCODING 8673
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
66
18
00
18
00
18
00
18
00
00
00
00
ENDCHAR
STARTCHAR uni21E2
ENCODING 8674
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
06
AB
06
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21E3
ENCODING 8675
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
00
18
00
18
00
18
66
3C
18
00
00
00
00
ENDCHAR
STARTCHAR uni21E4
ENCODING 8676
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
98
B0
FF
B0
98
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21E5
ENCODING 8677
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
19
0D
FF
0D
19
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni21E6
ENCODING 8678
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
3F
41
81
41
3F
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni21E7
ENCODING 8679
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
C6
44
44
44
44
44
7C
00
00
00
00
ENDCHAR
STARTCHAR uni21E8
ENCODING 8680
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
FC
82
81
82
FC
08
00
00
00
00
00
ENDCHAR
STARTCHAR uni21E9
ENCODING 8681
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
44
44
44
44
44
C6
44
28
10
00
00
00
00
ENDCHAR
STARTCHAR uni21EA
ENCODING 8682
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
C6
44
44
7C
00
7C
44
7C
00
00
00
ENDCHAR
STARTCHAR uni21EB
ENCODING 8683
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
C6
44
44
44
C6
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni21EC
ENCODING 8684
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
7C
C6
44
44
44
C6
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni21ED
ENCODING 8685
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
54
D6
54
54
54
D6
92
FE
00
00
00
00
ENDCHAR
STARTCHAR uni21EE
ENCODING 8686
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
28
54
EE
44
C6
44
44
44
44
7C
00
00
00
00
ENDCHAR
STARTCHAR uni21EF
ENCODING 8687
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
28
54
EE
44
C6
44
44
C6
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni21F0
ENCODING 8688
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
E8
BC
82
81
82
BC
E8
00
00
00
00
00
ENDCHAR
STARTCHAR uni21F1
ENCODING 8689
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
80
BC
B8
AC
86
83
81
80
00
00
00
00
00
ENDCHAR
STARTCHAR uni21F2
ENCODING 8690
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
01
81
C1
61
35
1D
3D
01
FF
00
00
00
00
ENDCHAR
STARTCHAR uni21F3
ENCODING 8691
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
C6
44
44
44
C6
44
28
10
00
00
00
ENDCHAR
STARTCHAR universal
ENCODING 8704
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
FE
C6
6C
6C
38
38
10
10
00
00
00
00
ENDCHAR
STARTCHAR uni2201
ENCODING 8705
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
60
60
60
60
60
66
3C
00
00
ENDCHAR
STARTCHAR partialdiff
ENCODING 8706
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
06
06
3E
66
C6
C6
CC
78
00
00
00
00
ENDCHAR
STARTCHAR existential
ENCODING 8707
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
06
06
06
7E
06
06
06
06
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2204
ENCODING 8708
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
FE
16
16
16
7E
16
26
26
26
FE
40
00
00
00
ENDCHAR
STARTCHAR emptyset
ENCODING 8709
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
3E
66
CF
DB
DB
F3
66
7C
C0
00
00
00
00
ENDCHAR
STARTCHAR Delta
ENCODING 8710
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
38
38
6C
6C
C6
C6
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR gradient
ENCODING 8711
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
C6
C6
6C
6C
38
38
10
10
00
00
00
00
ENDCHAR
STARTCHAR element
ENCODING 8712
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
3E
60
C0
C0
FE
C0
C0
60
3E
00
00
00
00
ENDCHAR
STARTCHAR notelement
ENCODING 8713
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
3E
64
C8
C8
FE
C8
D0
70
3E
20
00
00
00
ENDCHAR
STARTCHAR uni220A
ENCODING 8714
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
3E
60
C0
FE
C0
60
3E
00
00
00
00
00
ENDCHAR
STARTCHAR suchthat
ENCODING 8715
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
F8
0C
06
06
FE
06
06
0C
F8
00
00
00
00
ENDCHAR
STARTCHAR uni220C
ENCODING 8716
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
F8
1C
16
26
FE
26
26
4C
F8
40
00
00
00
ENDCHAR
STARTCHAR uni220D
ENCODING 8717
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
F8
0C
06
FE
06
0C
F8
00
00
00
00
00
ENDCHAR
STARTCHAR uni220E
ENCODING 8718
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
7E
7E
7E
7E
7E
7E
7E
00
00
00
00
00
ENDCHAR
STARTCHAR product
ENCODING 8719
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
66
66
66
66
66
66
66
66
66
66
E7
00
00
ENDCHAR
STARTCHAR uni2210
ENCODING 8720
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E7
66
66
66
66
66
66
66
66
66
66
FF
00
00
ENDCHAR
STARTCHAR summation
ENCODING 8721
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
C1
60
30
18
0C
0C
18
30
60
C1
FF
00
00
ENDCHAR
STARTCHAR minus
ENCODING 8722
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7E
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2213
ENCODING 8723
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
7E
00
18
18
7E
18
18
00
00
00
00
00
ENDCHAR
STARTCHAR uni2214
ENCODING 8724
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
18
00
18
18
7E
18
18
00
00
00
00
00
ENDCHAR
STARTCHAR fraction
ENCODING 8725
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
06
06
0C
0C
18
18
30
30
60
60
C0
C0
00
00
00
ENDCHAR
STARTCHAR uni2216
ENCODING 8726
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
C0
60
60
30
30
18
18
0C
0C
06
06
00
00
00
ENDCHAR
STARTCHAR asteriskmath
ENCODING 8727
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
24
18
7E
18
24
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2218
ENCODING 8728
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
24
24
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR periodcentered
ENCODING 8729
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
3C
3C
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR radical
ENCODING 8730
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
06
06
06
0C
CC
6C
38
18
00
00
00
00
ENDCHAR
STARTCHAR uni221B
ENCODING 8731
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E3
33
66
36
E6
0C
CC
6C
38
18
00
00
00
00
ENDCHAR
STARTCHAR uni221C
ENCODING 8732
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
33
73
B6
F6
36
0C
CC
6C
38
18
00
00
00
00
ENDCHAR
STARTCHAR proportional
ENCODING 8733
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
D8
D8
6E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR infinity
ENCODING 8734
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
DB
DB
6E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR orthogonal
ENCODING 8735
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
C0
C0
C0
C0
C0
FE
00
00
00
00
ENDCHAR
STARTCHAR angle
ENCODING 8736
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
02
06
0C
18
30
60
FF
00
00
00
00
ENDCHAR
STARTCHAR uni2221
ENCODING 8737
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
02
16
0C
1C
34
62
FF
02
00
00
00
ENDCHAR
STARTCHAR uni2222
ENCODING 8738
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
0E
38
E8
38
0E
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni2223
ENCODING 8739
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2224
ENCODING 8740
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
1A
1C
38
58
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2225
ENCODING 8741
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
6C
6C
6C
6C
6C
6C
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR uni2226
ENCODING 8742
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6C
6C
6C
6E
7C
EC
6C
6C
6C
6C
00
00
00
00
ENDCHAR
STARTCHAR logicaland
ENCODING 8743
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
10
38
38
6C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR logicalor
ENCODING 8744
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C6
C6
6C
6C
38
38
10
10
00
00
00
00
ENDCHAR
STARTCHAR intersection
ENCODING 8745
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
7C
C6
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR union
ENCODING 8746
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C6
C6
C6
C6
C6
C6
C6
7C
00
00
00
00
ENDCHAR
STARTCHAR integral
ENCODING 8747
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
1A
18
18
18
18
18
18
18
18
18
18
58
30
00
00
ENDCHAR
STARTCHAR uni222C
ENCODING 8748
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
33
66
66
66
66
66
66
66
66
66
66
66
66
CC
00
00
ENDCHAR
STARTCHAR uni222D
ENCODING 8749
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
2A
54
54
54
54
54
54
54
54
54
54
54
54
A8
00
00
ENDCHAR
STARTCHAR uni222E
ENCODING 8750
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
1A
18
18
3C
5A
99
99
5A
3C
18
18
58
30
00
00
ENDCHAR
STARTCHAR uni222F
ENCODING 8751
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
33
66
66
66
7E
E7
E7
E7
E7
7E
66
66
66
CC
00
00
ENDCHAR
STARTCHAR uni2230
ENCODING 8752
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
2A
54
54
54
7C
D6
D6
D6
D6
7C
54
54
54
A8
00
00
ENDCHAR
STARTCHAR uni2231
ENCODING 8753
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
34
30
30
38
35
33
37
30
30
30
30
B0
60
00
00
ENDCHAR
STARTCHAR uni2232
ENCODING 8754
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
1A
18
18
3C
5A
FA
5A
5A
3C
18
18
58
30
00
00
ENDCHAR
STARTCHAR uni2233
ENCODING 8755
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
1A
18
18
3C
5A
5F
5A
5A
3C
18
18
58
30
00
00
ENDCHAR
STARTCHAR therefore
ENCODING 8756
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
18
00
00
00
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni2235
ENCODING 8757
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
00
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2236
ENCODING 8758
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
18
00
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2237
ENCODING 8759
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
66
66
00
00
00
66
66
00
00
00
00
ENDCHAR
STARTCHAR uni2238
ENCODING 8760
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
18
00
7E
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2239
ENCODING 8761
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
03
03
00
FC
00
03
03
00
00
00
00
00
ENDCHAR
STARTCHAR uni223A
ENCODING 8762
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
66
66
00
7E
00
66
66
00
00
00
00
00
ENDCHAR
STARTCHAR uni223B
ENCODING 8763
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
18
00
76
DC
00
30
30
00
00
00
00
00
ENDCHAR
STARTCHAR similar
ENCODING 8764
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
76
DC
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni223D
ENCODING 8765
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
DC
76
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni223E
ENCODING 8766
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
72
DB
DB
4E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni223F
ENCODING 8767
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
D8
DB
DB
1B
0E
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2240
ENCODING 8768
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
1C
30
30
30
18
0C
0C
0C
38
00
00
00
00
ENDCHAR
STARTCHAR uni2241
ENCODING 8769
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
10
76
DC
10
20
20
00
00
00
00
00
ENDCHAR
STARTCHAR uni2242
ENCODING 8770
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FE
00
76
DC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2243
ENCODING 8771
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
DC
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2244
ENCODING 8772
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
76
DC
10
FE
20
20
00
00
00
00
00
ENDCHAR
STARTCHAR congruent
ENCODING 8773
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
76
DC
00
FE
00
FE
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2246
ENCODING 8774
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
76
DC
08
FE
10
FE
20
00
00
00
00
00
ENDCHAR
STARTCHAR uni2247
ENCODING 8775
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
08
76
DC
10
FE
20
FE
40
40
00
00
00
00
ENDCHAR
STARTCHAR approxequal
ENCODING 8776
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
76
DC
00
76
DC
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2249
ENCODING 8777
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
76
DC
10
76
DC
20
20
00
00
00
00
ENDCHAR
STARTCHAR uni224A
ENCODING 8778
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
76
DC
00
76
DC
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni224B
ENCODING 8779
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
76
DC
00
76
DC
00
76
DC
00
00
00
00
00
ENDCHAR
STARTCHAR uni224C
ENCODING 8780
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
DC
76
00
FE
00
FE
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni224D
ENCODING 8781
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C6
7C
00
7C
C6
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni224E
ENCODING 8782
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
66
00
00
66
18
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni224F
ENCODING 8783
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
66
00
00
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2250
ENCODING 8784
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
7E
00
00
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2251
ENCODING 8785
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
7E
00
00
7E
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2252
ENCODING 8786
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
60
00
7E
00
00
7E
00
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni2253
ENCODING 8787
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
06
00
7E
00
00
7E
00
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni2254
ENCODING 8788
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C0
DF
00
00
DF
C0
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2255
ENCODING 8789
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
03
FB
00
00
FB
03
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2256
ENCODING 8790
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FE
28
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2257
ENCODING 8791
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
10
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2258
ENCODING 8792
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
44
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2259
ENCODING 8793
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni225A
ENCODING 8794
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
44
28
10
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni225B
ENCODING 8795
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
10
7C
28
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni225C
ENCODING 8796
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
10
28
44
7C
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni225D
ENCODING 8797
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
26
7C
B4
6C
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni225E
ENCODING 8798
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
68
54
54
00
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni225F
ENCODING 8799
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
08
10
00
10
FE
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR notequal
ENCODING 8800
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
08
7E
08
10
7E
10
20
00
00
00
00
00
ENDCHAR
STARTCHAR equivalence
ENCODING 8801
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
00
00
FE
00
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni2262
ENCODING 8802
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
08
FE
08
10
FE
10
20
FE
20
40
00
00
00
ENDCHAR
STARTCHAR uni2263
ENCODING 8803
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
00
00
FE
00
00
FE
00
00
FE
00
00
00
00
ENDCHAR
STARTCHAR lessequal
ENCODING 8804
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0E
38
E0
38
0E
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR greaterequal
ENCODING 8805
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
E0
38
0E
38
E0
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni2266
ENCODING 8806
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
0E
38
E0
38
0E
00
FE
00
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2267
ENCODING 8807
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
E0
38
0E
38
E0
00
FE
00
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2268
ENCODING 8808
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
0E
38
E0
38
0E
08
FE
10
FE
20
00
00
00
ENDCHAR
STARTCHAR uni2269
ENCODING 8809
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
E0
38
0E
38
E0
08
FE
10
FE
20
00
00
00
ENDCHAR
STARTCHAR uni226A
ENCODING 8810
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
1B
36
6C
D8
6C
36
1B
00
00
00
00
00
ENDCHAR
STARTCHAR uni226B
ENCODING 8811
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
D8
6C
36
1B
36
6C
D8
00
00
00
00
00
ENDCHAR
STARTCHAR uni226C
ENCODING 8812
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
66
18
3C
66
66
66
66
3C
18
66
00
00
00
00
ENDCHAR
STARTCHAR uni226D
ENCODING 8813
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
CE
7C
10
7C
E6
20
00
00
00
00
00
ENDCHAR
STARTCHAR uni226E
ENCODING 8814
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
04
0E
38
E8
38
0E
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni226F
ENCODING 8815
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
E0
38
2E
38
E0
40
40
00
00
00
00
00
ENDCHAR
STARTCHAR uni2270
ENCODING 8816
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
04
0E
38
E8
38
0E
10
FE
10
00
00
00
00
ENDCHAR
STARTCHAR uni2271
ENCODING 8817
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
E0
38
2E
38
E0
40
FE
40
00
00
00
00
ENDCHAR
STARTCHAR uni2272
ENCODING 8818
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0E
38
E0
38
0E
00
76
DC
00
00
00
00
ENDCHAR
STARTCHAR uni2273
ENCODING 8819
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
E0
38
0E
38
E0
00
76
DC
00
00
00
00
ENDCHAR
STARTCHAR uni2274
ENCODING 8820
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
04
0E
38
E8
38
0E
10
76
DC
20
20
00
00
ENDCHAR
STARTCHAR uni2275
ENCODING 8821
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
E0
38
2E
38
E0
40
76
DC
80
00
00
00
ENDCHAR
STARTCHAR uni2276
ENCODING 8822
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
38
E0
38
0E
E0
38
0E
38
E0
00
00
00
00
ENDCHAR
STARTCHAR uni2277
ENCODING 8823
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
E0
38
0E
38
E0
0E
38
E0
38
0E
00
00
00
00
ENDCHAR
STARTCHAR uni2278
ENCODING 8824
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
0E
38
E8
38
1E
F0
38
2E
38
E0
20
00
00
00
ENDCHAR
STARTCHAR uni2279
ENCODING 8825
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
E8
38
0E
38
F0
1E
38
E0
38
2E
20
00
00
00
ENDCHAR
STARTCHAR uni227A
ENCODING 8826
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
02
06
1C
F0
1C
06
02
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni227B
ENCODING 8827
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
80
C0
70
1E
70
C0
80
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni227C
ENCODING 8828
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
02
06
1C
F0
1C
06
F2
1C
06
02
00
00
00
00
ENDCHAR
STARTCHAR uni227D
ENCODING 8829
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
C0
70
1E
70
C0
9E
70
C0
80
00
00
00
00
ENDCHAR
STARTCHAR uni227E
ENCODING 8830
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
02
06
1C
F0
1C
06
02
00
76
DC
00
00
00
00
ENDCHAR
STARTCHAR uni227F
ENCODING 8831
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
C0
70
1E
70
C0
80
00
76
DC
00
00
00
00
ENDCHAR
STARTCHAR uni2280
ENCODING 8832
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
06
0C
38
E8
38
1C
16
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni2281
ENCODING 8833
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
D0
70
38
2E
38
60
C0
40
00
00
00
00
00
ENDCHAR
STARTCHAR propersubset
ENCODING 8834
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
7E
C0
C0
C0
C0
7E
00
00
00
00
00
00
ENDCHAR
STARTCHAR propersuperset
ENCODING 8835
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FC
06
06
06
06
FC
00
00
00
00
00
00
ENDCHAR
STARTCHAR notsubset
ENCODING 8836
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
7E
C8
C8
D0
D0
7E
20
00
00
00
00
00
ENDCHAR
STARTCHAR uni2285
ENCODING 8837
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
FC
16
16
26
26
FC
40
00
00
00
00
00
ENDCHAR
STARTCHAR reflexsubset
ENCODING 8838
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7E
C0
C0
C0
C0
7E
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR reflexsuperset
ENCODING 8839
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FC
06
06
06
06
FC
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni2288
ENCODING 8840
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
7E
C8
C8
D0
D0
7E
20
FE
40
00
00
00
00
ENDCHAR
STARTCHAR uni2289
ENCODING 8841
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
FC
16
16
26
26
FC
40
FE
80
00
00
00
00
ENDCHAR
STARTCHAR uni228A
ENCODING 8842
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7E
C0
C0
C0
C0
7E
08
FE
10
00
00
00
00
ENDCHAR
STARTCHAR uni228B
ENCODING 8843
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FC
06
06
06
06
FC
10
FE
20
00
00
00
00
ENDCHAR
STARTCHAR uni228C
ENCODING 8844
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
82
92
A2
FA
A2
92
44
38
00
00
00
00
ENDCHAR
STARTCHAR uni228D
ENCODING 8845
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
82
82
92
BA
BA
92
44
38
00
00
00
00
ENDCHAR
STARTCHAR uni228E
ENCODING 8846
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
82
82
92
BA
92
82
44
38
00
00
00
00
ENDCHAR
STARTCHAR uni228F
ENCODING 8847
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
C0
C0
C0
C0
FE
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2290
ENCODING 8848
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
06
06
06
06
FE
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2291
ENCODING 8849
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
C0
C0
C0
C0
FE
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni2292
ENCODING 8850
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
06
06
06
06
FE
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni2293
ENCODING 8851
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
C6
C6
C6
C6
C6
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni2294
ENCODING 8852
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C6
C6
C6
C6
C6
C6
C6
FE
00
00
00
00
ENDCHAR
STARTCHAR circleplus
ENCODING 8853
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
54
92
FE
92
54
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni2296
ENCODING 8854
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
82
FE
82
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR circlemultiply
ENCODING 8855
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
AA
92
AA
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni2298
ENCODING 8856
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
8A
92
A2
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni2299
ENCODING 8857
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
92
BA
92
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni229A
ENCODING 8858
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
92
AA
92
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni229B
ENCODING 8859
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
54
D6
BA
D6
54
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni229C
ENCODING 8860
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
BA
82
BA
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni229D
ENCODING 8861
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
82
BA
82
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni229E
ENCODING 8862
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
92
92
FE
92
92
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni229F
ENCODING 8863
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
82
82
FE
82
82
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni22A0
ENCODING 8864
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
C6
AA
92
AA
C6
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni22A1
ENCODING 8865
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
82
92
BA
92
82
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni22A2
ENCODING 8866
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C0
C0
C0
FF
C0
C0
C0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni22A3
ENCODING 8867
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
03
03
03
03
FF
03
03
03
03
00
00
00
00
ENDCHAR
STARTCHAR uni22A4
ENCODING 8868
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
18
18
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR perpendicular
ENCODING 8869
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
18
18
FF
00
00
00
00
ENDCHAR
STARTCHAR uni22A6
ENCODING 8870
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
60
60
60
60
7E
60
60
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni22A7
ENCODING 8871
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
60
60
60
7E
60
7E
60
60
60
00
00
00
00
ENDCHAR
STARTCHAR uni22A8
ENCODING 8872
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C0
C0
FF
C0
FF
C0
C0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni22A9
ENCODING 8873
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
D8
D8
D8
D8
DF
D8
D8
D8
D8
00
00
00
00
ENDCHAR
STARTCHAR uni22AA
ENCODING 8874
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
A8
A8
A8
A8
AF
A8
A8
A8
A8
00
00
00
00
ENDCHAR
STARTCHAR uni22AB
ENCODING 8875
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
D8
D8
D8
DF
D8
DF
D8
D8
D8
00
00
00
00
ENDCHAR
STARTCHAR uni22AC
ENCODING 8876
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C2
C4
C4
FF
C8
C8
D0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni22AD
ENCODING 8877
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
C4
C4
FF
C8
FF
D0
D0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni22AE
ENCODING 8878
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
D8
D9
DA
DA
DF
DA
DA
DC
D8
00
00
00
00
ENDCHAR
STARTCHAR uni22AF
ENCODING 8879
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
D8
D9
DA
DF
DA
DF
DA
DC
D8
00
00
00
00
ENDCHAR
STARTCHAR uni22B0
ENCODING 8880
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
0C
06
1C
F0
1C
06
0C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B1
ENCODING 8881
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
60
C0
70
1E
70
C0
60
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B2
ENCODING 8882
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
06
1E
76
C6
76
1E
06
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B3
ENCODING 8883
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C0
F0
DC
C6
DC
F0
C0
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B4
ENCODING 8884
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
1E
76
C6
76
1E
06
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B5
ENCODING 8885
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
F0
DC
C6
DC
F0
C0
00
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B6
ENCODING 8886
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
42
BF
42
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B7
ENCODING 8887
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
42
FD
42
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B8
ENCODING 8888
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
02
7D
02
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22B9
ENCODING 8889
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
10
00
C6
00
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni22BA
ENCODING 8890
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
18
18
18
18
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni22BB
ENCODING 8891
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C6
C6
6C
6C
38
38
10
10
00
FE
00
00
00
00
ENDCHAR
STARTCHAR uni22BC
ENCODING 8892
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
00
10
10
38
38
6C
6C
C6
C6
00
00
00
00
ENDCHAR
STARTCHAR uni22BD
ENCODING 8893
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
00
C6
C6
6C
6C
38
38
10
10
00
00
00
00
ENDCHAR
STARTCHAR uni22BE
ENCODING 8894
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
C0
C0
C0
F0
C8
C4
C4
FF
00
00
00
00
ENDCHAR
STARTCHAR uni22BF
ENCODING 8895
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
03
07
0B
13
23
43
83
FF
00
00
00
00
ENDCHAR
STARTCHAR uni22C0
ENCODING 8896
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
38
38
6C
6C
C6
C6
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C1
ENCODING 8897
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C6
C6
6C
6C
38
38
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C2
ENCODING 8898
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
6C
C6
C6
C6
C6
C6
C6
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C3
ENCODING 8899
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C6
C6
C6
C6
C6
C6
6C
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C4
ENCODING 8900
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
38
6C
38
10
00
00
00
00
00
00
ENDCHAR
STARTCHAR dotmath
ENCODING 8901
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
18
18
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C6
ENCODING 8902
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
10
7C
38
28
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C7
ENCODING 8903
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
92
44
28
92
28
44
92
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C8
ENCODING 8904
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
82
C6
AA
92
AA
C6
82
00
00
00
00
00
ENDCHAR
STARTCHAR uni22C9
ENCODING 8905
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
82
C4
A8
90
A8
C4
82
00
00
00
00
00
ENDCHAR
STARTCHAR uni22CA
ENCODING 8906
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
82
46
2A
12
2A
46
82
00
00
00
00
00
ENDCHAR
STARTCHAR uni22CB
ENCODING 8907
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
80
40
20
10
28
44
82
00
00
00
00
00
ENDCHAR
STARTCHAR uni22CC
ENCODING 8908
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
02
04
08
10
28
44
82
00
00
00
00
00
ENDCHAR
STARTCHAR uni22CD
ENCODING 8909
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
DC
76
00
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22CE
ENCODING 8910
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
10
38
38
6C
6C
C6
00
00
00
00
00
ENDCHAR
STARTCHAR uni22CF
ENCODING 8911
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C6
6C
6C
38
38
10
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D0
ENCODING 8912
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
3E
60
CE
D8
D8
CE
60
3E
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D1
ENCODING 8913
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
F8
0C
E6
36
36
E6
0C
F8
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D2
ENCODING 8914
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
44
92
AA
AA
AA
AA
AA
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D3
ENCODING 8915
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
AA
AA
AA
AA
AA
92
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D4
ENCODING 8916
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
10
38
54
92
92
92
92
92
92
00
00
00
00
ENDCHAR
STARTCHAR uni22D5
ENCODING 8917
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
7E
18
18
7E
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni22D6
ENCODING 8918
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
30
64
CE
64
30
18
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D7
ENCODING 8919
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
30
18
4C
E6
4C
18
30
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D8
ENCODING 8920
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
15
2A
54
A8
54
2A
15
00
00
00
00
00
ENDCHAR
STARTCHAR uni22D9
ENCODING 8921
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
A8
54
2A
15
2A
54
A8
00
00
00
00
00
ENDCHAR
STARTCHAR uni22DA
ENCODING 8922
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
0E
38
E0
38
0E
00
FE
00
E0
38
0E
38
E0
00
00
ENDCHAR
STARTCHAR uni22DB
ENCODING 8923
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
38
0E
38
E0
00
FE
00
0E
38
E0
38
0E
00
00
ENDCHAR
STARTCHAR uni22DC
ENCODING 8924
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
00
0E
38
E0
38
0E
00
00
00
00
00
ENDCHAR
STARTCHAR uni22DD
ENCODING 8925
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
00
E0
38
0E
38
E0
00
00
00
00
00
ENDCHAR
STARTCHAR uni22DE
ENCODING 8926
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
02
06
1C
F2
06
1C
F0
1C
06
02
00
00
00
00
ENDCHAR
STARTCHAR uni22DF
ENCODING 8927
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
C0
70
9E
C0
70
1E
70
C0
80
00
00
00
00
ENDCHAR
STARTCHAR uni22E0
ENCODING 8928
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0A
0E
1C
F0
1C
16
F2
1C
26
22
00
00
00
00
ENDCHAR
STARTCHAR uni22E1
ENCODING 8929
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
88
C8
70
1E
70
D0
9E
70
E0
A0
00
00
00
00
ENDCHAR
STARTCHAR uni22E2
ENCODING 8930
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
FE
C8
C8
D0
D0
FE
20
FE
40
00
00
00
00
ENDCHAR
STARTCHAR uni22E3
ENCODING 8931
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
FE
16
16
26
26
FE
40
FE
80
00
00
00
00
ENDCHAR
STARTCHAR uni22E4
ENCODING 8932
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
C0
C0
C0
C0
FE
08
FE
10
00
00
00
00
ENDCHAR
STARTCHAR uni22E5
ENCODING 8933
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
06
06
06
06
FE
10
FE
20
00
00
00
00
ENDCHAR
STARTCHAR uni22E6
ENCODING 8934
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0E
38
E0
38
0E
10
76
DC
10
00
00
00
ENDCHAR
STARTCHAR uni22E7
ENCODING 8935
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
E0
38
0E
38
E0
10
76
DC
10
00
00
00
ENDCHAR
STARTCHAR uni22E8
ENCODING 8936
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
02
06
1C
F0
1C
06
02
10
76
DC
10
00
00
00
ENDCHAR
STARTCHAR uni22E9
ENCODING 8937
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
80
C0
70
1E
70
C0
80
10
76
DC
10
00
00
00
ENDCHAR
STARTCHAR uni22EA
ENCODING 8938
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
0E
1E
76
D6
76
1E
26
20
00
00
00
00
00
ENDCHAR
STARTCHAR uni22EB
ENCODING 8939
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
C8
F0
DC
D6
DC
F0
E0
20
00
00
00
00
00
ENDCHAR
STARTCHAR uni22EC
ENCODING 8940
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
0E
1E
76
D6
76
1E
26
20
FE
40
00
00
00
00
ENDCHAR
STARTCHAR uni22ED
ENCODING 8941
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
C8
F0
DC
D6
DC
F0
E0
20
FE
40
00
00
00
00
ENDCHAR
STARTCHAR uni22EE
ENCODING 8942
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
00
00
18
18
00
00
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni22EF
ENCODING 8943
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
DB
DB
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni22F0
ENCODING 8944
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
03
03
00
00
18
18
00
00
C0
C0
00
00
00
00
ENDCHAR
STARTCHAR uni22F1
ENCODING 8945
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
00
00
18
18
00
00
03
03
00
00
00
00
ENDCHAR
STARTCHAR emptyset
ENCODING 8960
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
3D
66
C7
CB
D3
E3
66
BC
00
00
00
00
ENDCHAR
STARTCHAR house
ENCODING 8962
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
38
6C
C6
C6
C6
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uni2308
ENCODING 8968
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2309
ENCODING 8969
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni230A
ENCODING 8970
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
1E
00
00
00
00
ENDCHAR
STARTCHAR uni230B
ENCODING 8971
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
78
00
00
00
00
ENDCHAR
STARTCHAR revlogicalnot
ENCODING 8976
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FE
C0
C0
C0
C0
00
00
00
00
00
ENDCHAR
STARTCHAR uni2318
ENCODING 8984
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
42
A5
7E
24
24
7E
A5
42
00
00
00
00
00
ENDCHAR
STARTCHAR circleplus
ENCODING 8986
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
38
54
8A
F6
82
54
38
38
00
00
00
00
ENDCHAR
STARTCHAR H
ENCODING 8987
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
FE
FE
44
44
28
10
28
44
44
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR integraltp
ENCODING 8992
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0E
1B
1B
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR integralbt
ENCODING 8993
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
D8
D8
D8
70
00
00
00
00
ENDCHAR
STARTCHAR angleleft
ENCODING 9001
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
18
18
30
30
60
60
30
30
18
18
0C
0C
00
00
ENDCHAR
STARTCHAR angleright
ENCODING 9002
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
60
30
30
18
18
0C
0C
18
18
30
30
60
60
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9115
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
03
06
0C
0C
18
18
18
30
30
30
30
30
30
30
30
ENDCHAR
STARTCHAR SF110000
ENCODING 9116
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
30
30
30
30
30
30
30
30
30
30
30
30
30
30
ENDCHAR
STARTCHAR SF110000
ENCODING 9117
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
30
30
30
30
30
18
18
18
0C
0C
06
03
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9118
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
C0
60
30
30
18
18
18
0C
0C
0C
0C
0C
0C
0C
0C
ENDCHAR
STARTCHAR SF110000
ENCODING 9119
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
ENDCHAR
STARTCHAR SF110000
ENCODING 9120
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
0C
0C
0C
0C
0C
18
18
18
30
30
60
C0
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9121
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
3F
30
30
30
30
30
30
30
30
30
30
30
30
30
30
ENDCHAR
STARTCHAR SF110000
ENCODING 9122
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
30
30
30
30
30
30
30
30
30
30
30
30
30
30
ENDCHAR
STARTCHAR SF110000
ENCODING 9123
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
30
30
30
30
30
30
30
30
30
30
30
30
3F
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9124
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
FC
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
ENDCHAR
STARTCHAR SF110000
ENCODING 9125
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
ENDCHAR
STARTCHAR SF110000
ENCODING 9126
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
0C
FC
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9127
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
07
0C
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF110000
ENCODING 9128
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
30
E0
30
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF110000
ENCODING 9129
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
18
0C
07
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9130
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF110000
ENCODING 9131
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
E0
30
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF110000
ENCODING 9132
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
0C
07
0C
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF110000
ENCODING 9133
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
18
30
E0
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9134
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF100000
ENCODING 9135
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9136
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
07
0C
18
18
18
18
18
18
18
18
18
18
18
18
30
E0
ENDCHAR
STARTCHAR SF110000
ENCODING 9137
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
E0
30
18
18
18
18
18
18
18
18
18
18
18
18
0C
07
ENDCHAR
STARTCHAR summation
ENCODING 9138
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
C1
C0
60
60
60
60
30
30
30
30
18
18
18
ENDCHAR
STARTCHAR summation
ENCODING 9139
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
30
30
30
30
60
60
60
60
C0
C1
FF
00
00
ENDCHAR
STARTCHAR uni2423
ENCODING 9140
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
C3
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2423
ENCODING 9141
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
C3
FF
00
00
00
00
ENDCHAR
STARTCHAR uni2423
ENCODING 9142
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
C3
FF
00
FF
C3
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9143
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
D8
D8
78
78
38
38
18
18
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9144
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
ENDCHAR
STARTCHAR SF110000
ENCODING 9145
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
03
03
03
03
03
03
03
03
03
03
03
03
03
03
03
03
ENDCHAR
STARTCHAR SF100000
ENCODING 9146
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FF
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF100000
ENCODING 9147
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
FF
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF100000
ENCODING 9148
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
FF
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF100000
ENCODING 9149
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
FF
00
00
00
00
ENDCHAR
STARTCHAR carriagereturn
ENCODING 9166
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
07
05
05
05
05
25
79
C2
7C
20
00
00
00
00
ENDCHAR
STARTCHAR uni2409
ENCODING 9225
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D8
D8
F8
D8
D8
0F
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni240A
ENCODING 9226
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
C0
F0
0F
0C
0E
0C
0C
00
00
00
00
ENDCHAR
STARTCHAR uni240B
ENCODING 9227
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D8
D8
F8
70
20
0F
06
06
06
06
00
00
00
00
ENDCHAR
STARTCHAR uni240C
ENCODING 9228
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F0
C0
E0
C0
C0
0F
0C
0E
0C
0C
00
00
00
00
ENDCHAR
STARTCHAR uni240D
ENCODING 9229
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
C0
C0
C0
70
1E
1B
1E
1B
1B
00
00
00
00
ENDCHAR
STARTCHAR uni2423
ENCODING 9251
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2424
ENCODING 9252
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
98
D8
F8
D8
D8
0C
0C
0C
0C
0F
00
00
00
00
ENDCHAR
STARTCHAR question
ENCODING 9254
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7C
FE
C6
C6
60
30
30
00
30
30
00
00
00
00
ENDCHAR
STARTCHAR SF100000
ENCODING 9472
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2501
ENCODING 9473
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF110000
ENCODING 9474
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2503
ENCODING 9475
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2504
ENCODING 9476
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
6D
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2505
ENCODING 9477
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
6D
6D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2506
ENCODING 9478
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
00
18
18
18
18
18
00
18
18
18
18
00
ENDCHAR
STARTCHAR uni2507
ENCODING 9479
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
00
1C
1C
1C
1C
1C
00
1C
1C
1C
1C
00
ENDCHAR
STARTCHAR uni2508
ENCODING 9480
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
AA
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2509
ENCODING 9481
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
AA
AA
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni250A
ENCODING 9482
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
00
18
18
18
00
18
18
18
00
18
18
18
00
ENDCHAR
STARTCHAR uni250B
ENCODING 9483
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
00
1C
1C
1C
00
1C
1C
1C
00
1C
1C
1C
00
ENDCHAR
STARTCHAR SF010000
ENCODING 9484
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1F
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni250D
ENCODING 9485
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1F
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni250E
ENCODING 9486
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1F
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni250F
ENCODING 9487
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1F
1F
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR SF030000
ENCODING 9488
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
F8
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2511
ENCODING 9489
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
F8
F8
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2512
ENCODING 9490
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FC
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2513
ENCODING 9491
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FC
FC
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR SF020000
ENCODING 9492
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1F
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2515
ENCODING 9493
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1F
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2516
ENCODING 9494
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1F
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2517
ENCODING 9495
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1F
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF040000
ENCODING 9496
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
F8
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2519
ENCODING 9497
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
F8
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni251A
ENCODING 9498
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FC
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni251B
ENCODING 9499
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FC
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF080000
ENCODING 9500
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1F
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni251D
ENCODING 9501
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1F
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni251E
ENCODING 9502
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1F
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni251F
ENCODING 9503
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1F
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2520
ENCODING 9504
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1F
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2521
ENCODING 9505
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1F
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2522
ENCODING 9506
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1F
1F
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2523
ENCODING 9507
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1F
1F
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR SF090000
ENCODING 9508
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
F8
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2525
ENCODING 9509
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
F8
F8
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2526
ENCODING 9510
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FC
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2527
ENCODING 9511
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FC
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2528
ENCODING 9512
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FC
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2529
ENCODING 9513
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FC
FC
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni252A
ENCODING 9514
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FC
FC
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni252B
ENCODING 9515
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FC
FC
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR SF060000
ENCODING 9516
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni252D
ENCODING 9517
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
F8
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni252E
ENCODING 9518
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni252F
ENCODING 9519
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
FF
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2530
ENCODING 9520
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2531
ENCODING 9521
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
FC
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2532
ENCODING 9522
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
1F
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2533
ENCODING 9523
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
FF
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR SF070000
ENCODING 9524
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2535
ENCODING 9525
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2536
ENCODING 9526
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2537
ENCODING 9527
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2538
ENCODING 9528
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2539
ENCODING 9529
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni253A
ENCODING 9530
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni253B
ENCODING 9531
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF050000
ENCODING 9532
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni253D
ENCODING 9533
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
F8
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni253E
ENCODING 9534
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni253F
ENCODING 9535
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
FF
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2540
ENCODING 9536
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2541
ENCODING 9537
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2542
ENCODING 9538
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2543
ENCODING 9539
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
FC
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2544
ENCODING 9540
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2545
ENCODING 9541
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
FC
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2546
ENCODING 9542
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
1F
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2547
ENCODING 9543
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
FF
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2548
ENCODING 9544
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
FF
FF
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni2549
ENCODING 9545
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
FC
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni254A
ENCODING 9546
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
1F
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni254B
ENCODING 9547
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
FF
FF
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni254C
ENCODING 9548
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
EE
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni254D
ENCODING 9549
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
EE
EE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni254E
ENCODING 9550
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
00
18
18
18
18
18
18
18
00
ENDCHAR
STARTCHAR uni254F
ENCODING 9551
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
00
1C
1C
1C
1C
1C
1C
1C
00
ENDCHAR
STARTCHAR SF430000
ENCODING 9552
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FF
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF240000
ENCODING 9553
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
36
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF510000
ENCODING 9554
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
1F
18
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF520000
ENCODING 9555
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
3F
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF390000
ENCODING 9556
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
3F
30
37
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF220000
ENCODING 9557
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
F8
18
F8
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF210000
ENCODING 9558
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FE
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF250000
ENCODING 9559
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FE
06
F6
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF500000
ENCODING 9560
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
1F
18
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF490000
ENCODING 9561
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
3F
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF380000
ENCODING 9562
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
37
30
3F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF280000
ENCODING 9563
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
F8
18
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF270000
ENCODING 9564
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
FE
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF260000
ENCODING 9565
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
F6
06
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF360000
ENCODING 9566
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
1F
18
1F
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF370000
ENCODING 9567
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
37
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF420000
ENCODING 9568
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
37
30
37
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF190000
ENCODING 9569
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
F8
18
F8
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF200000
ENCODING 9570
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
F6
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF230000
ENCODING 9571
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
F6
06
F6
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF470000
ENCODING 9572
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FF
00
FF
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF480000
ENCODING 9573
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF410000
ENCODING 9574
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FF
00
F7
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF450000
ENCODING 9575
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
FF
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF460000
ENCODING 9576
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF400000
ENCODING 9577
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
F7
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR SF540000
ENCODING 9578
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
FF
18
FF
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR SF530000
ENCODING 9579
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
36
FF
36
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR SF440000
ENCODING 9580
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
36
36
36
36
36
36
F7
00
F7
36
36
36
36
36
36
36
ENDCHAR
STARTCHAR uni256D
ENCODING 9581
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
03
0E
0C
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni256E
ENCODING 9582
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
C0
70
30
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni256F
ENCODING 9583
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
30
70
C0
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2570
ENCODING 9584
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
0C
0E
03
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2571
ENCODING 9585
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
01
01
02
02
04
04
08
08
10
10
20
20
40
40
80
80
ENDCHAR
STARTCHAR uni2572
ENCODING 9586
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
80
80
40
40
20
20
10
10
08
08
04
04
02
02
01
01
ENDCHAR
STARTCHAR uni2573
ENCODING 9587
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
81
81
42
42
24
24
18
18
18
18
24
24
42
42
81
81
ENDCHAR
STARTCHAR uni2574
ENCODING 9588
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
F8
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2575
ENCODING 9589
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
18
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2576
ENCODING 9590
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1F
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2577
ENCODING 9591
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
18
18
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR uni2578
ENCODING 9592
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FC
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2579
ENCODING 9593
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1C
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni257A
ENCODING 9594
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1F
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni257B
ENCODING 9595
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
1C
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni257C
ENCODING 9596
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
1F
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni257D
ENCODING 9597
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
18
18
18
18
18
18
1C
1C
1C
1C
1C
1C
1C
1C
1C
ENDCHAR
STARTCHAR uni257E
ENCODING 9598
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FF
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni257F
ENCODING 9599
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
1C
1C
1C
1C
1C
1C
1C
1C
1C
18
18
18
18
18
18
18
ENDCHAR
STARTCHAR upblock
ENCODING 9600
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
FF
FF
FF
FF
FF
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2581
ENCODING 9601
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
00
00
FF
FF
ENDCHAR
STARTCHAR uni2582
ENCODING 9602
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni2583
ENCODING 9603
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR dnblock
ENCODING 9604
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
FF
FF
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni2585
ENCODING 9605
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni2586
ENCODING 9606
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni2587
ENCODING 9607
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR block
ENCODING 9608
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni2589
ENCODING 9609
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
ENDCHAR
STARTCHAR uni258A
ENCODING 9610
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
FC
ENDCHAR
STARTCHAR uni258B
ENCODING 9611
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
F8
ENDCHAR
STARTCHAR lfblock
ENCODING 9612
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
F0
ENDCHAR
STARTCHAR uni258D
ENCODING 9613
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
E0
ENDCHAR
STARTCHAR uni258E
ENCODING 9614
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
C0
ENDCHAR
STARTCHAR uni258F
ENCODING 9615
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
80
80
80
80
80
80
80
80
80
80
80
80
80
80
80
80
ENDCHAR
STARTCHAR rtblock
ENCODING 9616
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
0F
ENDCHAR
STARTCHAR ltshade
ENCODING 9617
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
11
44
11
44
11
44
11
44
11
44
11
44
11
44
11
44
ENDCHAR
STARTCHAR shade
ENCODING 9618
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
55
AA
55
AA
55
AA
55
AA
55
AA
55
AA
55
AA
55
AA
ENDCHAR
STARTCHAR dkshade
ENCODING 9619
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
DD
77
DD
77
DD
77
DD
77
DD
77
DD
77
DD
77
DD
77
ENDCHAR
STARTCHAR uni2594
ENCODING 9620
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2595
ENCODING 9621
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
01
ENDCHAR
STARTCHAR filledbox
ENCODING 9632
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
FE
FE
FE
FE
FE
FE
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR H22073
ENCODING 9633
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
82
82
82
82
82
82
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A2
ENCODING 9634
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
7C
82
82
82
82
82
82
82
7C
00
00
00
00
ENDCHAR
STARTCHAR uni25A3
ENCODING 9635
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
82
BA
BA
BA
BA
BA
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A4
ENCODING 9636
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
82
FE
82
FE
82
FE
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A5
ENCODING 9637
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
AA
AA
AA
AA
AA
AA
AA
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A6
ENCODING 9638
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
AA
FE
AA
FE
AA
FE
AA
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A7
ENCODING 9639
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
8A
C6
A2
92
8A
C6
A2
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A8
ENCODING 9640
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
A2
C6
8A
92
A2
C6
8A
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25A9
ENCODING 9641
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
AA
C6
AA
92
AA
C6
AA
FE
00
00
00
00
ENDCHAR
STARTCHAR H18543
ENCODING 9642
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7C
7C
7C
7C
7C
00
00
00
00
ENDCHAR
STARTCHAR H18551
ENCODING 9643
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7C
44
44
44
7C
00
00
00
00
ENDCHAR
STARTCHAR filledrect
ENCODING 9644
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FE
FE
FE
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25AD
ENCODING 9645
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
FE
82
82
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25AE
ENCODING 9646
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
FE
00
00
ENDCHAR
STARTCHAR uni25AF
ENCODING 9647
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
82
82
82
82
82
82
82
82
82
82
FE
00
00
ENDCHAR
STARTCHAR uni25B0
ENCODING 9648
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
7E
7E
7E
FC
FC
FC
00
00
00
00
ENDCHAR
STARTCHAR uni25B1
ENCODING 9649
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
7E
42
42
84
84
FC
00
00
00
00
ENDCHAR
STARTCHAR triagup
ENCODING 9650
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
38
38
7C
7C
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25B3
ENCODING 9651
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
28
28
44
44
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25B4
ENCODING 9652
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
10
38
38
7C
00
00
00
00
ENDCHAR
STARTCHAR uni25B5
ENCODING 9653
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
10
28
28
7C
00
00
00
00
ENDCHAR
STARTCHAR uni25B6
ENCODING 9654
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
80
C0
E0
F0
F8
FC
F8
F0
E0
C0
80
00
00
00
00
ENDCHAR
STARTCHAR uni25B7
ENCODING 9655
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
80
C0
A0
90
88
84
88
90
A0
C0
80
00
00
00
00
ENDCHAR
STARTCHAR uni25B8
ENCODING 9656
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
40
70
78
70
40
00
00
00
00
ENDCHAR
STARTCHAR uni25B9
ENCODING 9657
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
40
70
48
70
40
00
00
00
00
ENDCHAR
STARTCHAR triagrt
ENCODING 9658
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
80
E0
F8
FE
F8
E0
80
00
00
00
00
00
ENDCHAR
STARTCHAR uni25BB
ENCODING 9659
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
80
E0
98
86
98
E0
80
00
00
00
00
00
ENDCHAR
STARTCHAR triagdn
ENCODING 9660
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
FE
7C
7C
38
38
10
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni25BD
ENCODING 9661
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
82
44
44
28
28
10
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni25BE
ENCODING 9662
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
7C
38
38
10
00
00
00
00
ENDCHAR
STARTCHAR uni25BF
ENCODING 9663
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
7C
28
28
10
00
00
00
00
ENDCHAR
STARTCHAR uni25C0
ENCODING 9664
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
02
06
0E
1E
3E
7E
3E
1E
0E
06
02
00
00
00
00
ENDCHAR
STARTCHAR uni25C1
ENCODING 9665
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
02
06
0A
12
22
42
22
12
0A
06
02
00
00
00
00
ENDCHAR
STARTCHAR uni25C2
ENCODING 9666
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
08
38
78
38
08
00
00
00
00
ENDCHAR
STARTCHAR uni25C3
ENCODING 9667
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
08
38
48
38
08
00
00
00
00
ENDCHAR
STARTCHAR triaglf
ENCODING 9668
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
02
0E
3E
FE
3E
0E
02
00
00
00
00
00
ENDCHAR
STARTCHAR uni25C5
ENCODING 9669
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
02
0E
32
C2
32
0E
02
00
00
00
00
00
ENDCHAR
STARTCHAR uni25C6
ENCODING 9670
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
38
7C
7C
FE
FE
7C
7C
38
10
00
00
00
00
ENDCHAR
STARTCHAR uni25C7
ENCODING 9671
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
44
82
82
44
44
28
10
00
00
00
00
ENDCHAR
STARTCHAR uni25C8
ENCODING 9672
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
44
54
BA
BA
54
44
28
10
00
00
00
00
ENDCHAR
STARTCHAR uni25C9
ENCODING 9673
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
99
BD
BD
BD
BD
99
42
3C
00
00
00
00
ENDCHAR
STARTCHAR lozenge
ENCODING 9674
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
28
28
44
82
82
44
28
28
10
00
00
00
00
ENDCHAR
STARTCHAR circle
ENCODING 9675
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
81
81
81
81
81
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25CC
ENCODING 9676
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
14
40
01
80
01
80
01
80
02
28
00
00
00
00
ENDCHAR
STARTCHAR uni25CD
ENCODING 9677
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
A5
A5
A5
A5
A5
A5
66
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25CE
ENCODING 9678
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
99
A5
A5
A5
A5
99
42
3C
00
00
00
00
ENDCHAR
STARTCHAR H18533
ENCODING 9679
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
7E
FF
FF
FF
FF
FF
FF
7E
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D0
ENCODING 9680
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
72
F1
F1
F1
F1
F1
F1
72
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D1
ENCODING 9681
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
4E
8F
8F
8F
8F
8F
8F
4E
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D2
ENCODING 9682
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
81
81
FF
FF
FF
7E
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D3
ENCODING 9683
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
7E
FF
FF
FF
81
81
81
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D4
ENCODING 9684
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
4E
8F
8F
8F
81
81
81
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D5
ENCODING 9685
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
4E
8F
8F
8F
FF
FF
FF
7E
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25D6
ENCODING 9686
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
70
F0
F0
F0
F0
F0
F0
70
30
00
00
00
00
ENDCHAR
STARTCHAR uni25D7
ENCODING 9687
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
0E
0F
0F
0F
0F
0F
0F
0E
0C
00
00
00
00
ENDCHAR
STARTCHAR invbullet
ENCODING 9688
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
FF
FF
FF
FF
E7
C3
C3
E7
FF
FF
FF
FF
FF
FF
ENDCHAR
STARTCHAR invcircle
ENCODING 9689
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
C3
BD
7E
7E
7E
7E
7E
7E
BD
C3
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni25DA
ENCODING 9690
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
C3
BD
7E
7E
7E
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni25DB
ENCODING 9691
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
7E
7E
7E
BD
C3
FF
FF
FF
FF
ENDCHAR
STARTCHAR uni25DC
ENCODING 9692
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
40
80
80
80
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni25DD
ENCODING 9693
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0C
02
01
01
01
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni25DE
ENCODING 9694
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
01
01
01
02
0C
00
00
00
00
ENDCHAR
STARTCHAR uni25DF
ENCODING 9695
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
80
80
80
40
30
00
00
00
00
ENDCHAR
STARTCHAR uni25E0
ENCODING 9696
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
81
81
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni25E1
ENCODING 9697
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
81
81
81
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25E2
ENCODING 9698
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
01
01
03
03
07
07
0F
0F
1F
1F
3F
3F
7F
7F
FF
FF
ENDCHAR
STARTCHAR uni25E3
ENCODING 9699
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
80
80
C0
C0
E0
E0
F0
F0
F8
F8
FC
FC
FE
FE
FF
FF
ENDCHAR
STARTCHAR uni25E4
ENCODING 9700
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
FE
FE
FC
FC
F8
F8
F0
F0
E0
E0
C0
C0
80
80
ENDCHAR
STARTCHAR uni25E5
ENCODING 9701
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
FF
FF
7F
7F
3F
3F
1F
1F
0F
0F
07
07
03
03
01
01
ENDCHAR
STARTCHAR openbullet
ENCODING 9702
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
3C
66
42
42
66
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uni25E7
ENCODING 9703
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
F1
F1
F1
F1
F1
F1
F1
F1
FF
00
00
00
00
ENDCHAR
STARTCHAR uni25E8
ENCODING 9704
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
8F
8F
8F
8F
8F
8F
8F
8F
FF
00
00
00
00
ENDCHAR
STARTCHAR uni25E9
ENCODING 9705
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
FF
FD
F9
F1
F1
E1
C1
81
FF
00
00
00
00
ENDCHAR
STARTCHAR uni25EA
ENCODING 9706
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
81
83
87
8F
8F
9F
BF
FF
FF
00
00
00
00
ENDCHAR
STARTCHAR uni25EB
ENCODING 9707
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FF
99
99
99
99
99
99
99
99
FF
00
00
00
00
ENDCHAR
STARTCHAR uni25EC
ENCODING 9708
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
28
28
44
44
92
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25ED
ENCODING 9709
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
38
38
74
74
F2
F2
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25EE
ENCODING 9710
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
38
38
5C
5C
9E
9E
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25EF
ENCODING 9711
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
81
81
81
81
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uni25F0
ENCODING 9712
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
92
92
92
F2
82
82
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25F1
ENCODING 9713
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
82
82
82
F2
92
92
92
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25F2
ENCODING 9714
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
82
82
82
9E
92
92
92
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25F3
ENCODING 9715
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
FE
92
92
92
9E
82
82
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni25F4
ENCODING 9716
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
4A
89
89
89
F9
81
81
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25F5
ENCODING 9717
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
81
F9
89
89
89
4A
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25F6
ENCODING 9718
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
81
9F
91
91
91
52
3C
00
00
00
00
ENDCHAR
STARTCHAR uni25F7
ENCODING 9719
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
52
91
91
91
9F
81
81
42
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2600
ENCODING 9728
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
54
38
FE
38
54
10
10
00
00
00
00
ENDCHAR
STARTCHAR uni2602
ENCODING 9729
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
30
7C
FE
FF
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2601
ENCODING 9730
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
7C
FE
10
10
10
10
14
08
00
00
00
00
ENDCHAR
STARTCHAR uni2605
ENCODING 9733
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
38
FE
7C
38
6C
44
00
00
00
00
00
ENDCHAR
STARTCHAR uni2606
ENCODING 9734
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
28
EE
44
54
6C
44
00
00
00
00
00
ENDCHAR
STARTCHAR uni2607
ENCODING 9735
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
18
30
60
C0
60
34
1C
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uni2608
ENCODING 9736
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
C6
CC
D8
F0
D8
CD
C7
CF
00
00
00
00
00
ENDCHAR
STARTCHAR uni2609
ENCODING 9737
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
38
44
82
92
82
44
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni260A
ENCODING 9738
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
42
42
42
A5
A5
42
00
00
00
00
ENDCHAR
STARTCHAR uni260B
ENCODING 9739
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
42
A5
A5
42
42
42
24
18
00
00
00
00
ENDCHAR
STARTCHAR uni260C
ENCODING 9740
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
06
0C
78
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni260D
ENCODING 9741
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
36
36
1C
18
30
70
D8
D8
70
00
00
00
00
ENDCHAR
STARTCHAR uni2610
ENCODING 9744
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
82
82
82
82
82
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2611
ENCODING 9745
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
82
86
8A
BA
92
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2612
ENCODING 9746
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
FE
82
EE
BA
BA
EE
82
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2613
ENCODING 9747
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
82
C6
6C
7C
38
7C
6C
C6
82
00
00
00
00
ENDCHAR
STARTCHAR uni2620
ENCODING 9760
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
7C
82
AA
82
44
7C
44
38
00
44
C6
38
C6
44
00
ENDCHAR
STARTCHAR uni2622
ENCODING 9762
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
44
EE
FE
92
BA
7C
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni2626
ENCODING 9766
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
7E
18
18
FF
18
1E
78
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2628
ENCODING 9768
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
7E
18
18
FF
18
18
18
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2629
ENCODING 9769
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
38
10
10
92
FE
92
10
10
38
00
00
00
00
ENDCHAR
STARTCHAR uni262A
ENCODING 9770
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
72
E0
C4
DF
CE
CA
E0
72
3C
00
00
00
00
ENDCHAR
STARTCHAR uni262B
ENCODING 9771
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
54
28
54
AA
AA
AA
AA
54
38
00
00
00
00
00
ENDCHAR
STARTCHAR uni262E
ENCODING 9774
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
5A
99
99
99
BD
FF
DB
5A
3C
00
00
00
00
ENDCHAR
STARTCHAR uni262F
ENCODING 9775
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
42
81
85
B1
F9
FF
DF
7E
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2630
ENCODING 9776
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
FE
00
00
FE
FE
00
00
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2631
ENCODING 9777
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
EE
EE
00
00
FE
FE
00
00
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2632
ENCODING 9778
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
FE
00
00
EE
EE
00
00
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2633
ENCODING 9779
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
EE
EE
00
00
EE
EE
00
00
FE
FE
00
00
00
00
ENDCHAR
STARTCHAR uni2634
ENCODING 9780
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
FE
00
00
FE
FE
00
00
EE
EE
00
00
00
00
ENDCHAR
STARTCHAR uni2635
ENCODING 9781
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
EE
EE
00
00
FE
FE
00
00
EE
EE
00
00
00
00
ENDCHAR
STARTCHAR uni2636
ENCODING 9782
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
FE
FE
00
00
EE
EE
00
00
EE
EE
00
00
00
00
ENDCHAR
STARTCHAR uni2637
ENCODING 9783
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
EE
EE
00
00
EE
EE
00
00
EE
EE
00
00
00
00
ENDCHAR
STARTCHAR uni2639
ENCODING 9785
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
81
A5
81
81
81
99
A5
81
7E
00
00
00
00
ENDCHAR
STARTCHAR smileface
ENCODING 9786
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
81
A5
81
81
A5
99
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR invsmileface
ENCODING 9787
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
FF
DB
FF
FF
DB
E7
FF
FF
7E
00
00
00
00
ENDCHAR
STARTCHAR sun
ENCODING 9788
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
54
28
C6
28
54
10
10
00
00
00
00
ENDCHAR
STARTCHAR uni263D
ENCODING 9789
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
78
14
0A
0A
0A
0A
0A
0A
14
78
00
00
00
00
ENDCHAR
STARTCHAR uni263E
ENCODING 9790
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
28
50
50
50
50
50
50
28
1E
00
00
00
00
ENDCHAR
STARTCHAR uni263F
ENCODING 9791
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
66
66
3C
66
66
66
66
3C
18
7E
18
18
00
00
00
ENDCHAR
STARTCHAR female
ENCODING 9792
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
3C
18
7E
18
18
00
00
00
00
ENDCHAR
STARTCHAR uni2641
ENCODING 9793
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
7E
18
3C
66
66
66
66
3C
00
00
00
00
ENDCHAR
STARTCHAR male
ENCODING 9794
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
06
0E
1A
78
CC
CC
CC
CC
78
00
00
00
00
ENDCHAR
STARTCHAR uni2643
ENCODING 9795
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
03
03
7B
CF
CF
CF
0F
1B
33
FF
03
03
03
00
00
ENDCHAR
STARTCHAR uni2644
ENCODING 9796
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
60
F0
60
6E
73
63
63
66
66
63
00
00
00
00
ENDCHAR
STARTCHAR uni2645
ENCODING 9797
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
D6
54
54
7C
54
54
D6
38
44
44
38
00
00
00
ENDCHAR
STARTCHAR uni2646
ENCODING 9798
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
3C
DB
DB
DB
DB
7E
3C
18
3C
18
18
00
00
ENDCHAR
STARTCHAR uni2647
ENCODING 9799
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
F8
CC
CC
CC
CC
F8
C0
C0
C0
C0
FE
00
00
00
ENDCHAR
STARTCHAR uni2648
ENCODING 9800
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
42
A5
A5
3C
3C
18
18
18
18
18
18
00
00
00
ENDCHAR
STARTCHAR uni2649
ENCODING 9801
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
C3
66
66
66
66
3C
66
66
66
66
3C
00
00
ENDCHAR
STARTCHAR uni264A
ENCODING 9802
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C3
7E
66
66
66
66
66
66
7E
C3
00
00
00
00
ENDCHAR
STARTCHAR uni264B
ENCODING 9803
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7E
DB
D8
70
00
00
0E
1B
DB
7E
00
00
00
00
ENDCHAR
STARTCHAR uni264C
ENCODING 9804
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1E
33
33
33
33
1B
7B
DB
DB
73
03
01
00
00
ENDCHAR
STARTCHAR uni264D
ENCODING 9805
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
94
7C
55
57
55
55
55
55
55
55
06
0B
00
00
ENDCHAR
STARTCHAR uni264E
ENCODING 9806
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
66
66
66
66
24
E7
00
FF
00
00
00
00
00
ENDCHAR
STARTCHAR uni264F
ENCODING 9807
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
94
7C
54
54
54
54
54
54
54
54
04
03
00
00
ENDCHAR
STARTCHAR uni2650
ENCODING 9808
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1F
07
8F
DB
73
70
D8
88
00
00
00
00
00
00
ENDCHAR
STARTCHAR uni2651
ENCODING 9809
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
90
50
70
68
48
48
4E
49
09
0E
10
20
00
00
ENDCHAR
STARTCHAR uni2652
ENCODING 9810
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
2A
7E
AA
00
00
2A
7E
AA
00
00
00
00
00
ENDCHAR
STARTCHAR uni2653
ENCODING 9811
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C3
66
66
66
66
FF
66
66
66
66
C3
00
00
00
ENDCHAR
STARTCHAR spade
ENCODING 9824
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
3C
7E
FF
FF
7E
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2661
ENCODING 9825
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
6C
92
82
82
82
44
28
10
00
00
00
00
ENDCHAR
STARTCHAR uni2662
ENCODING 9826
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
28
44
82
44
28
10
00
00
00
00
00
ENDCHAR
STARTCHAR club
ENCODING 9827
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
3C
3C
E7
E7
E7
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2664
ENCODING 9828
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
24
42
81
81
66
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR heart
ENCODING 9829
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
6C
FE
FE
FE
FE
7C
38
10
00
00
00
00
ENDCHAR
STARTCHAR diamond
ENCODING 9830
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
38
7C
FE
7C
38
10
00
00
00
00
00
ENDCHAR
STARTCHAR uni2667
ENCODING 9831
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
18
24
3C
E7
A5
E7
18
18
3C
00
00
00
00
ENDCHAR
STARTCHAR uni2669
ENCODING 9833
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
18
18
18
18
18
18
18
38
78
70
00
00
00
00
ENDCHAR
STARTCHAR musicalnote
ENCODING 9834
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
30
3C
3E
32
30
30
30
70
F0
E0
00
00
00
00
ENDCHAR
STARTCHAR musicalnotedbl
ENCODING 9835
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
7F
6F
63
63
63
63
E3
E7
C7
06
00
00
00
ENDCHAR
STARTCHAR uni266C
ENCODING 9836
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
7F
63
7F
63
63
63
63
63
E7
E7
C6
00
00
00
ENDCHAR
STARTCHAR uni266D
ENCODING 9837
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
C0
C0
C0
C0
CC
DE
E6
C4
D8
E0
00
00
00
00
ENDCHAR
STARTCHAR uni266E
ENCODING 9838
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
40
40
44
5C
74
44
44
5C
74
44
04
04
00
00
ENDCHAR
STARTCHAR uni266F
ENCODING 9839
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
04
46
5C
74
C4
46
5C
74
C4
40
40
00
00
ENDCHAR
STARTCHAR ff
ENCODING 64256
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3B
66
66
66
FF
66
66
66
66
FF
00
00
00
00
ENDCHAR
STARTCHAR fi
ENCODING 64257
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3C
6E
66
60
FE
66
66
66
66
FF
00
00
00
00
ENDCHAR
STARTCHAR fl
ENCODING 64258
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
3E
6E
66
66
FE
66
66
66
66
FF
00
00
00
00
ENDCHAR
STARTCHAR ffi
ENCODING 64259
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6E
DB
DB
D8
FF
DB
DB
DB
DB
FF
00
00
00
00
ENDCHAR
STARTCHAR ffl
ENCODING 64260
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
6F
DB
DB
DB
FF
DB
DB
DB
DB
FF
00
00
00
00
ENDCHAR
STARTCHAR uniFB05
ENCODING 64261
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
38
6C
6C
6F
6C
6C
6C
6C
6D
F6
00
00
00
00
ENDCHAR
STARTCHAR uniFB50
ENCODING 64336
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
06
29
5E
00
04
04
04
04
04
04
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB51
ENCODING 64337
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
06
29
5E
00
04
04
04
04
04
03
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB52
ENCODING 64338
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB53
ENCODING 64339
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
80
81
7E
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB54
ENCODING 64340
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB55
ENCODING 64341
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB56
ENCODING 64342
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
14
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB57
ENCODING 64343
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
80
81
7E
00
14
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB58
ENCODING 64344
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
14
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB59
ENCODING 64345
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
14
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB5A
ENCODING 64346
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
14
00
14
00
00
00
ENDCHAR
STARTCHAR uniFB5B
ENCODING 64347
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
80
81
7E
00
14
00
14
00
00
00
ENDCHAR
STARTCHAR uniFB5C
ENCODING 64348
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
14
00
14
00
00
00
ENDCHAR
STARTCHAR uniFB5D
ENCODING 64349
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
14
00
14
00
00
00
ENDCHAR
STARTCHAR uniFB5E
ENCODING 64350
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
08
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB5F
ENCODING 64351
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
08
00
40
80
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB60
ENCODING 64352
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
08
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB61
ENCODING 64353
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
08
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB62
ENCODING 64354
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
14
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB63
ENCODING 64355
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
14
00
40
80
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB64
ENCODING 64356
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
14
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB65
ENCODING 64357
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
14
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB66
ENCODING 64358
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB67
ENCODING 64359
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
40
80
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB68
ENCODING 64360
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB69
ENCODING 64361
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB6A
ENCODING 64362
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
0A
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB6B
ENCODING 64363
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
00
0A
00
06
49
89
86
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB6C
ENCODING 64364
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
0C
12
0A
06
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB6D
ENCODING 64365
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
0C
12
12
0C
F3
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB6E
ENCODING 64366
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0A
00
0A
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB6F
ENCODING 64367
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0A
00
0A
00
06
49
89
86
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB70
ENCODING 64368
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
00
14
00
0C
12
0A
06
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB71
ENCODING 64369
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
14
00
14
00
0C
12
12
0C
F3
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB72
ENCODING 64370
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
88
80
88
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFB73
ENCODING 64371
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
41
88
80
88
40
3E
00
00
ENDCHAR
STARTCHAR uniFB74
ENCODING 64372
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
47
18
E0
00
04
00
04
00
00
00
ENDCHAR
STARTCHAR uniFB75
ENCODING 64373
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
C1
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB76
ENCODING 64374
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
80
94
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFB77
ENCODING 64375
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
41
80
94
80
40
3E
00
00
ENDCHAR
STARTCHAR uniFB78
ENCODING 64376
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
47
18
E0
00
00
0A
00
00
00
00
ENDCHAR
STARTCHAR uniFB79
ENCODING 64377
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
C1
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFB7A
ENCODING 64378
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
94
80
88
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFB7B
ENCODING 64379
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
41
94
80
88
40
3E
00
00
ENDCHAR
STARTCHAR uniFB7C
ENCODING 64380
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
47
18
E0
00
0A
00
04
00
00
00
ENDCHAR
STARTCHAR uniFB7D
ENCODING 64381
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
C1
00
14
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB7E
ENCODING 64382
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
94
80
94
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFB7F
ENCODING 64383
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
41
94
80
94
40
3E
00
00
ENDCHAR
STARTCHAR uniFB80
ENCODING 64384
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
47
18
E0
00
0A
00
0A
00
00
00
ENDCHAR
STARTCHAR uniFB81
ENCODING 64385
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
C1
00
14
00
14
00
00
00
ENDCHAR
STARTCHAR uniFB82
ENCODING 64386
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
04
02
42
3C
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFB83
ENCODING 64387
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
08
04
46
39
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFB84
ENCODING 64388
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
28
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB85
ENCODING 64389
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
28
00
08
08
04
46
39
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB86
ENCODING 64390
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
00
28
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB87
ENCODING 64391
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
00
28
00
08
08
04
46
39
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB88
ENCODING 64392
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
38
28
70
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB89
ENCODING 64393
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
38
28
70
08
08
04
46
39
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB8A
ENCODING 64394
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
00
14
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB8B
ENCODING 64395
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
14
00
00
04
07
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFB8C
ENCODING 64396
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB8D
ENCODING 64397
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
00
00
04
07
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFB8E
ENCODING 64398
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
01
02
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB8F
ENCODING 64399
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
01
02
04
08
48
84
82
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB90
ENCODING 64400
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
18
20
10
08
08
F0
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB91
ENCODING 64401
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
18
20
20
10
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB92
ENCODING 64402
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB93
ENCODING 64403
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
48
84
82
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB94
ENCODING 64404
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
46
18
20
10
08
08
F0
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB95
ENCODING 64405
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
46
18
20
20
10
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB96
ENCODING 64406
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
44
82
82
7C
00
10
00
10
00
00
00
ENDCHAR
STARTCHAR uniFB97
ENCODING 64407
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
09
12
04
08
48
84
82
7D
00
10
00
10
00
00
00
ENDCHAR
STARTCHAR uniFB98
ENCODING 64408
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
46
18
20
10
08
08
F0
00
10
00
10
00
00
00
ENDCHAR
STARTCHAR uniFB99
ENCODING 64409
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
46
18
20
20
10
08
F7
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFB9A
ENCODING 64410
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
A4
09
12
04
08
44
82
82
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB9B
ENCODING 64411
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
A4
09
12
04
08
48
84
82
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB9C
ENCODING 64412
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
A2
0C
13
0C
10
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB9D
ENCODING 64413
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
A2
0C
13
0C
10
10
08
04
FB
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB9E
ENCODING 64414
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uniFB9F
ENCODING 64415
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
01
41
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uniFBA0
ENCODING 64416
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA1
ENCODING 64417
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
00
00
01
41
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uniFBA2
ENCODING 64418
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA3
ENCODING 64419
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
1C
14
38
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA4
ENCODING 64420
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
38
40
38
40
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA5
ENCODING 64421
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
70
80
70
80
10
68
88
74
03
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA6
ENCODING 64422
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA7
ENCODING 64423
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
0C
13
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBA8
ENCODING 64424
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
10
F0
10
14
08
00
00
00
00
ENDCHAR
STARTCHAR uniFBA9
ENCODING 64425
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
10
F7
08
08
08
00
00
00
00
ENDCHAR
STARTCHAR uniFBAA
ENCODING 64426
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
38
4C
52
32
3D
40
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBAB
ENCODING 64427
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
38
4C
52
32
3D
40
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBAC
ENCODING 64428
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
38
4C
52
32
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBAD
ENCODING 64429
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
38
4C
52
32
FD
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBAE
ENCODING 64430
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
14
60
80
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBAF
ENCODING 64431
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
07
18
20
3F
00
00
00
00
ENDCHAR
STARTCHAR uniFBB0
ENCODING 64432
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
70
80
70
80
08
14
60
80
FE
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBB1
ENCODING 64433
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
1C
20
1C
20
00
00
07
18
20
3F
00
00
00
00
ENDCHAR
STARTCHAR uniFBD3
ENCODING 64467
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
00
29
01
19
21
19
A1
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBD4
ENCODING 64468
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
00
2A
02
32
42
32
C6
79
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBD5
ENCODING 64469
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
40
00
A3
0C
10
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBD6
ENCODING 64470
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
40
00
A3
0C
10
10
08
04
FB
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBD7
ENCODING 64471
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
28
18
10
20
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBD8
ENCODING 64472
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
28
18
10
20
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFBD9
ENCODING 64473
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
08
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBDA
ENCODING 64474
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
08
00
00
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFBDB
ENCODING 64475
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
08
08
08
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBDC
ENCODING 64476
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
08
08
08
00
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFBDD
ENCODING 64477
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
23
54
33
24
40
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBDE
ENCODING 64478
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBDF
ENCODING 64479
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
14
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFBE0
ENCODING 64480
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
0E
02
3C
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBE1
ENCODING 64481
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
08
00
00
00
0C
12
0F
02
3C
18
60
00
00
00
ENDCHAR
STARTCHAR uniFBE2
ENCODING 64482
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
14
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFBE3
ENCODING 64483
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
14
00
00
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFBE4
ENCODING 64484
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
81
7E
00
10
00
10
ENDCHAR
STARTCHAR uniFBE5
ENCODING 64485
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
07
88
87
81
7E
10
00
10
ENDCHAR
STARTCHAR uniFBE6
ENCODING 64486
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFBE7
ENCODING 64487
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
08
00
08
00
00
00
ENDCHAR
STARTCHAR uniFBE8
ENCODING 64488
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBE9
ENCODING 64489
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFBFC
ENCODING 64508
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
82
7C
00
00
00
00
ENDCHAR
STARTCHAR uniFBFD
ENCODING 64509
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
07
88
87
81
7E
00
00
00
ENDCHAR
STARTCHAR uniFBFE
ENCODING 64510
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFBFF
ENCODING 64511
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFC5B
ENCODING 64603
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
20
20
20
20
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC5C
ENCODING 64604
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
10
10
10
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC5D
ENCODING 64605
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
10
10
10
00
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR uniFC5E
ENCODING 64606
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
24
98
60
C2
12
92
9C
60
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC5F
ENCODING 64607
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
02
92
9C
60
0E
70
0E
70
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC60
ENCODING 64608
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
60
04
54
58
20
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC61
ENCODING 64609
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
28
10
60
04
54
58
20
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC62
ENCODING 64610
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
04
54
58
20
0C
30
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC63
ENCODING 64611
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
10
04
54
58
20
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFC90
ENCODING 64656
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
10
10
10
00
00
00
00
07
88
87
81
7E
00
00
00
ENDCHAR
STARTCHAR uniFCF2
ENCODING 64754
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0E
F0
02
92
9C
60
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFCF3
ENCODING 64755
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
24
18
60
02
92
9C
60
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFCF4
ENCODING 64756
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
02
12
9C
60
0E
70
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFD3C
ENCODING 64828
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
10
28
50
28
08
08
08
08
07
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFD3D
ENCODING 64829
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
14
28
14
04
04
04
04
04
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFD3E
ENCODING 64830
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
08
10
54
38
54
10
08
04
00
00
00
00
00
ENDCHAR
STARTCHAR uniFD3F
ENCODING 64831
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
10
08
2A
1C
2A
08
10
20
00
00
00
00
00
ENDCHAR
STARTCHAR uniFDF2
ENCODING 65010
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
2A
14
00
21
69
A9
69
16
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE50
ENCODING 65104
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
08
10
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE51
ENCODING 65105
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
10
08
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE52
ENCODING 65106
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
10
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE54
ENCODING 65108
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
00
00
08
10
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE55
ENCODING 65109
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
10
00
00
10
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE56
ENCODING 65110
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
24
08
10
00
10
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE57
ENCODING 65111
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
10
10
10
00
10
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE58
ENCODING 65112
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE59
ENCODING 65113
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
10
10
10
10
10
08
00
00
00
00
ENDCHAR
STARTCHAR uniFE5A
ENCODING 65114
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
08
08
08
08
08
10
00
00
00
00
ENDCHAR
STARTCHAR uniFE5B
ENCODING 65115
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
10
10
20
10
10
18
00
00
00
00
ENDCHAR
STARTCHAR uniFE5C
ENCODING 65116
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
08
08
04
08
08
18
00
00
00
00
ENDCHAR
STARTCHAR uniFE5D
ENCODING 65117
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
10
10
10
10
10
18
00
00
00
00
ENDCHAR
STARTCHAR uniFE5E
ENCODING 65118
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
18
08
08
08
08
08
18
00
00
00
00
ENDCHAR
STARTCHAR uniFE5F
ENCODING 65119
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
28
7C
28
7C
28
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE60
ENCODING 65120
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
28
28
10
2A
24
1A
00
00
00
00
ENDCHAR
STARTCHAR uniFE61
ENCODING 65121
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
10
10
7C
38
38
44
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE62
ENCODING 65122
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
10
10
7C
10
10
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE63
ENCODING 65123
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE64
ENCODING 65124
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
10
20
10
08
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE65
ENCODING 65125
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
20
10
08
10
20
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE66
ENCODING 65126
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
3C
00
3C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE68
ENCODING 65128
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
20
10
10
08
08
04
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE69
ENCODING 65129
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
10
38
54
30
18
54
38
10
00
00
00
00
ENDCHAR
STARTCHAR uniFE6A
ENCODING 65130
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
24
08
08
10
10
24
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE6B
ENCODING 65131
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
44
54
58
40
38
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE70
ENCODING 65136
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
0C
30
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE71
ENCODING 65137
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
06
18
60
06
18
60
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE72
ENCODING 65138
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
12
CA
2C
70
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE74
ENCODING 65140
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
0C
30
0C
30
00
00
ENDCHAR
STARTCHAR uniFE76
ENCODING 65142
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
30
00
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE77
ENCODING 65143
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
06
18
60
00
00
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE78
ENCODING 65144
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
08
14
0C
08
10
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE79
ENCODING 65145
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
24
14
18
60
00
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE7A
ENCODING 65146
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
00
00
00
00
0C
30
00
00
ENDCHAR
STARTCHAR uniFE7B
ENCODING 65147
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
FF
00
00
06
18
60
00
00
ENDCHAR
STARTCHAR uniFE7C
ENCODING 65148
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0A
2A
2C
10
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE7D
ENCODING 65149
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
02
12
92
9C
60
00
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE7E
ENCODING 65150
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
24
18
00
00
00
00
00
00
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE7F
ENCODING 65151
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
24
24
18
00
00
00
00
FF
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE80
ENCODING 65152
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
20
1E
20
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE81
ENCODING 65153
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
02
3C
40
10
10
10
10
10
10
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE82
ENCODING 65154
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
01
3E
40
08
08
08
08
08
07
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE83
ENCODING 65155
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
18
20
1C
20
08
08
08
08
08
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE84
ENCODING 65156
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
0C
10
0E
10
04
04
04
04
03
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE85
ENCODING 65157
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1C
20
1C
20
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFE86
ENCODING 65158
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1C
20
1C
20
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFE87
ENCODING 65159
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
04
04
04
04
04
00
0C
10
0E
10
00
00
ENDCHAR
STARTCHAR uniFE88
ENCODING 65160
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
04
04
04
04
03
00
0C
10
0E
10
00
00
ENDCHAR
STARTCHAR uniFE89
ENCODING 65161
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
40
38
40
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR uniFE8A
ENCODING 65162
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
30
40
38
40
00
00
00
07
88
87
81
7E
00
00
00
ENDCHAR
STARTCHAR uniFE8B
ENCODING 65163
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1C
20
1C
20
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE8C
ENCODING 65164
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
1C
20
1C
20
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE8D
ENCODING 65165
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
08
08
08
08
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE8E
ENCODING 65166
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
08
08
08
08
07
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE8F
ENCODING 65167
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
81
81
7E
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR uniFE90
ENCODING 65168
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
40
80
81
7E
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR uniFE91
ENCODING 65169
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
00
10
00
00
00
00
ENDCHAR
STARTCHAR uniFE92
ENCODING 65170
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR uniFE93
ENCODING 65171
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
28
00
00
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE94
ENCODING 65172
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
50
00
10
10
68
88
74
03
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE95
ENCODING 65173
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
14
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE96
ENCODING 65174
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
14
00
40
80
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE97
ENCODING 65175
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
14
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE98
ENCODING 65176
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
14
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE99
ENCODING 65177
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
40
81
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE9A
ENCODING 65178
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
40
80
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE9B
ENCODING 65179
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE9C
ENCODING 65180
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFE9D
ENCODING 65181
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
80
88
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFE9E
ENCODING 65182
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
41
80
88
80
40
3E
00
00
ENDCHAR
STARTCHAR uniFE9F
ENCODING 65183
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
47
18
E0
00
00
10
00
00
00
00
ENDCHAR
STARTCHAR uniFEA0
ENCODING 65184
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
C1
00
00
08
00
00
00
00
ENDCHAR
STARTCHAR uniFEA1
ENCODING 65185
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFEA2
ENCODING 65186
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
41
80
80
80
40
3E
00
00
ENDCHAR
STARTCHAR uniFEA3
ENCODING 65187
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
38
47
18
E0
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEA4
ENCODING 65188
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
70
8F
32
C1
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEA5
ENCODING 65189
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
20
00
00
70
8F
30
40
80
80
80
41
3E
00
00
00
ENDCHAR
STARTCHAR uniFEA6
ENCODING 65190
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
00
00
70
8F
32
41
80
80
80
40
3E
00
00
ENDCHAR
STARTCHAR uniFEA7
ENCODING 65191
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
00
38
47
18
E0
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEA8
ENCODING 65192
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
00
00
70
8F
32
C1
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEA9
ENCODING 65193
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEAA
ENCODING 65194
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
08
04
46
39
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEAB
ENCODING 65195
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
00
08
04
02
42
3C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEAC
ENCODING 65196
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
00
08
08
04
46
39
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEAD
ENCODING 65197
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEAE
ENCODING 65198
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
04
07
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFEAF
ENCODING 65199
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
04
02
02
04
18
60
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB0
ENCODING 65200
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
00
00
04
07
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFEB1
ENCODING 65201
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
01
15
88
84
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB2
ENCODING 65202
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
01
15
88
84
84
78
00
00
00
00
ENDCHAR
STARTCHAR uniFEB3
ENCODING 65203
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
01
15
EA
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB4
ENCODING 65204
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
2A
D5
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB5
ENCODING 65205
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
01
15
88
84
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB6
ENCODING 65206
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
14
00
01
15
88
84
84
78
00
00
00
00
ENDCHAR
STARTCHAR uniFEB7
ENCODING 65207
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
04
00
0A
00
00
01
15
EA
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB8
ENCODING 65208
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
14
00
00
00
2A
D5
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEB9
ENCODING 65209
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
06
09
31
9E
88
88
70
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEBA
ENCODING 65210
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
06
09
31
9E
88
88
70
00
00
00
00
ENDCHAR
STARTCHAR uniFEBB
ENCODING 65211
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
06
29
31
DE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEBC
ENCODING 65212
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
06
29
31
DE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEBD
ENCODING 65213
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
09
31
9E
88
88
70
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEBE
ENCODING 65214
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
04
00
06
09
31
9E
88
88
70
00
00
00
00
ENDCHAR
STARTCHAR uniFEBF
ENCODING 65215
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
00
06
29
31
DE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC0
ENCODING 65216
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
00
06
29
31
DE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC1
ENCODING 65217
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
20
20
2C
32
A2
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC2
ENCODING 65218
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
20
20
2C
32
A2
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC3
ENCODING 65219
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
20
20
2C
32
22
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC4
ENCODING 65220
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
20
20
20
2C
32
22
FD
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC5
ENCODING 65221
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
20
20
2C
32
A2
7C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC6
ENCODING 65222
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
20
20
2C
32
A2
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC7
ENCODING 65223
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
20
20
2C
32
22
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC8
ENCODING 65224
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
24
20
20
2C
32
22
FD
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEC9
ENCODING 65225
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
70
80
8C
70
40
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR uniFECA
ENCODING 65226
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
1E
22
1C
22
41
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR uniFECB
ENCODING 65227
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0E
10
10
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFECC
ENCODING 65228
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
1E
22
1C
E3
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFECD
ENCODING 65229
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
40
00
00
70
80
8C
70
40
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR uniFECE
ENCODING 65230
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
08
00
00
1E
22
1C
22
41
80
80
80
41
3E
00
00
ENDCHAR
STARTCHAR uniFECF
ENCODING 65231
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
10
00
00
0E
10
10
FE
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED0
ENCODING 65232
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
1E
22
1C
E3
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED1
ENCODING 65233
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
49
85
83
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED2
ENCODING 65234
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
04
00
06
49
89
86
7D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED3
ENCODING 65235
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
0C
12
0A
06
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED4
ENCODING 65236
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
0C
12
12
0C
F3
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED5
ENCODING 65237
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0A
00
06
09
09
47
81
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uniFED6
ENCODING 65238
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
0A
00
00
06
09
49
87
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uniFED7
ENCODING 65239
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
00
0C
12
0A
06
FC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED8
ENCODING 65240
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
14
00
00
0C
12
12
0C
F3
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFED9
ENCODING 65241
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
19
21
19
21
01
81
7E
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEDA
ENCODING 65242
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
32
42
32
42
02
86
79
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEDB
ENCODING 65243
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
18
20
10
08
08
F0
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEDC
ENCODING 65244
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
06
18
20
20
10
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEDD
ENCODING 65245
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
02
02
02
02
02
42
82
82
84
78
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEDE
ENCODING 65246
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
02
02
02
02
02
03
42
82
82
84
78
00
00
ENDCHAR
STARTCHAR uniFEDF
ENCODING 65247
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
08
08
08
08
08
F0
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE0
ENCODING 65248
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
08
08
08
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE1
ENCODING 65249
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
0C
12
12
3C
40
40
40
40
40
40
00
00
ENDCHAR
STARTCHAR uniFEE2
ENCODING 65250
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
3C
4B
4A
44
40
40
40
00
00
ENDCHAR
STARTCHAR uniFEE3
ENCODING 65251
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
32
CC
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE4
ENCODING 65252
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
32
CD
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE5
ENCODING 65253
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
08
00
00
41
81
81
81
42
3C
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE6
ENCODING 65254
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
01
41
81
81
42
3C
00
00
00
ENDCHAR
STARTCHAR uniFEE7
ENCODING 65255
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
00
08
04
04
F8
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE8
ENCODING 65256
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
08
00
00
08
08
F7
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEE9
ENCODING 65257
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
18
24
22
22
1C
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEEA
ENCODING 65258
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
10
10
68
88
74
03
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEEB
ENCODING 65259
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
40
30
4E
49
39
E6
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEEC
ENCODING 65260
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
08
14
24
28
F3
24
18
0C
00
00
00
00
ENDCHAR
STARTCHAR uniFEED
ENCODING 65261
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
0C
12
0E
02
04
18
60
00
00
00
00
ENDCHAR
STARTCHAR uniFEEE
ENCODING 65262
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
0C
12
0F
02
04
18
60
00
00
00
ENDCHAR
STARTCHAR uniFEEF
ENCODING 65263
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
81
7E
00
00
00
00
ENDCHAR
STARTCHAR uniFEF0
ENCODING 65264
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
07
88
87
81
7E
00
00
00
ENDCHAR
STARTCHAR uniFEF1
ENCODING 65265
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
07
08
88
86
81
81
7E
00
00
24
00
ENDCHAR
STARTCHAR uniFEF2
ENCODING 65266
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
00
00
07
88
87
81
7E
00
24
00
ENDCHAR
STARTCHAR uniFEF3
ENCODING 65267
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
08
04
04
F8
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFEF4
ENCODING 65268
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
00
00
00
00
08
08
F7
00
00
14
00
00
00
00
ENDCHAR
STARTCHAR uniFEF5
ENCODING 65269
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
68
90
02
22
12
0A
04
0C
12
3C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEF6
ENCODING 65270
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
68
90
02
32
12
0A
0A
0E
3D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEF7
ENCODING 65271
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
60
80
72
A2
12
0A
04
0C
12
3C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEF8
ENCODING 65272
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
30
40
3A
52
12
0A
0A
0E
3D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEF9
ENCODING 65273
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
42
22
12
0A
04
0C
12
3C
00
18
20
1C
20
00
ENDCHAR
STARTCHAR uniFEFA
ENCODING 65274
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
22
12
12
0A
0A
0E
3D
00
00
18
20
1C
20
00
ENDCHAR
STARTCHAR uniFEFB
ENCODING 65275
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
42
22
12
0A
04
0C
12
3C
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEFC
ENCODING 65276
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
00
22
12
12
0A
0A
0E
3D
00
00
00
00
00
00
00
ENDCHAR
STARTCHAR uniFEFF
ENCODING 65279
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
F1
35
55
8A
E0
06
95
D6
B5
97
00
EE
8A
EE
28
E8
ENDCHAR
STARTCHAR uniFFFD
ENCODING 65533
SWIDTH 480 0
DWIDTH 8 0
BBX 8 16 0 -4
BITMAP
00
38
7C
7C
C6
92
F2
E6
FE
E6
7C
7C
38
00
00
00
ENDCHAR
ENDFONT
/branches/arm/contrib/util/DownloadAndPatchSILO.sh
0,0 → 1,74
#!/bin/bash
 
# Download SILO and patch it so that it can be used to create a bootable CD
# for the Serengeti machine
# by Pavel Rimsky <rimskyp@seznam.cz>
# portions by Martin Decky <martin@decky.cz>
#
# GPL'ed, copyleft
#
 
# stuff to be downloaded
SILO_DOWNLOAD_FILE='silo-loaders-1.4.11.tar.gz'
SILO_DOWNLOAD_URL='http://silo.auxio.org/pub/silo/old/'$SILO_DOWNLOAD_FILE
 
# check whether the last command failed, if so, write an error message and exit
check_error() {
if [ "$1" -ne "0" ]; then
echo
echo "Script failed: $2"
exit
fi
}
 
# temporary files are to be stored in /tmp
# the resulting file in the current directory
WD=`pwd`
cd /tmp
 
# download SILO from its official website
echo ">>> Downloading SILO"
wget $SILO_DOWNLOAD_URL
check_error $? "Error downloading SILO."
 
# unpack the downloaded file
echo ">>> Unpacking tarball"
tar xvzf $SILO_DOWNLOAD_FILE
check_error $? "Error unpacking tarball."
 
# CD to the unpacked directory
echo ">>> Changing to the unpacked SILO directory"
cd boot
check_error $? "Changing directory failed."
 
# patch it - remove bytes 512 to 512 + 32 (counted from 0), which belong to
# the ELF header which is not recognized by the Serengeti firmware
echo ">>> Patching SILO"
(((xxd -p -l 512 isofs.b) && (xxd -p -s 544 isofs.b)) | xxd -r -p) \
> isofs.b.patched
check_error $? "Patching SILO failed"
mv isofs.b.patched isofs.b
 
# get rid of files which are not needed for creating the bootable CD
echo ">>> Purging SILO directory"
for file in `ls`; do
if [ \( -f $file \) -a \( $file != "isofs.b" \) -a \( $file != "second.b" \) ];
then
rm -fr $file;
fi
done
check_error $? "Purging SILO directory failed"
 
# create the gzipped tarball with patched SILO
echo ">>> Creating tarball with patched SILO"
tar cvzf silo.patched.tar.gz *.b
check_error $? "Creating tarball with patched SILO failed"
 
# and move it to the directory where the user expects it to be
echo ">>> Moving the tarball with patched SILO to the current directory"
mv silo.patched.tar.gz $WD
check_error $? "Moving the tarball with patched SILO failed"
 
# move back to the working directory from /tmp
cd $WD
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/arm/uspace/uspace.config
File deleted
/branches/arm/uspace/app/tetris/pathnames.h
File deleted
/branches/arm/uspace/app/tetris/screen.c
36,7 → 36,7
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
50,22 → 50,26
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <io/stream.h>
 
 
#include <vfs/vfs.h>
#include <async.h>
#include "screen.h"
#include "tetris.h"
#include "../../srv/console/console.h"
#include <io/console.h>
 
static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */
#define STOP (B_COLS - 3)
 
static cell curscreen[B_SIZE]; /* non-zero => standout (or otherwise marked) */
static int curscore;
static int isset; /* true => terminal is in game mode */
static int isset; /* true => terminal is in game mode */
 
static int use_color; /* true => use colors */
 
static const struct shape *lastshape;
 
 
/*
* putstr() is for unpadded strings (either as in termcap(5) or
* simply literal strings);
* simply literal strings);
*/
static inline void putstr(char *s)
{
73,29 → 77,22
putchar(*(s++));
}
 
static int con_phone;
 
 
 
static void set_style(int fgcolor, int bgcolor)
static void start_standout(uint32_t color)
{
async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xf0f0f0,
use_color ? color : 0x000000);
}
 
static void start_standout(void)
{
set_style(0xf0f0f0, 0);
}
 
static void resume_normal(void)
{
set_style(0, 0xf0f0f0);
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0, 0xf0f0f0);
}
 
 
void clear_screen(void)
{
async_msg_0(con_phone, CONSOLE_CLEAR);
console_clear(fphone(stdout));
moveto(0, 0);
}
 
102,24 → 99,20
/*
* Clear the screen, forgetting the current contents in the process.
*/
void
scr_clear(void)
void scr_clear(void)
{
 
resume_normal();
async_msg_0(con_phone, CONSOLE_CLEAR);
console_clear(fphone(stdout));
curscore = -1;
memset((char *)curscreen, 0, sizeof(curscreen));
memset(curscreen, 0, sizeof(curscreen));
}
 
/*
* Set up screen
*/
void
scr_init(void)
void scr_init(void)
{
con_phone = get_cons_phone();
async_msg_1(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
console_cursor_visibility(fphone(stdout), 0);
resume_normal();
scr_clear();
}
126,38 → 119,49
 
void moveto(int r, int c)
{
async_msg_2(con_phone, CONSOLE_GOTO, r, c);
fflush(stdout);
console_goto(fphone(stdout), c, r);
}
 
static void fflush(void)
{
async_msg_0(con_phone, CONSOLE_FLUSH);
}
 
winsize_t winsize;
 
static int get_display_size(winsize_t *ws)
{
return async_req_0_2(con_phone, CONSOLE_GETSIZE, &ws->ws_row,
&ws->ws_col);
return console_get_size(fphone(stdout), &ws->ws_col, &ws->ws_row);
}
 
static int get_display_color_sup(void)
{
int rc;
int ccap;
 
rc = console_get_color_cap(fphone(stdout), &ccap);
if (rc != 0)
return 0;
 
return (ccap >= CONSOLE_CCAP_RGB);
}
 
/*
* Set up screen mode.
*/
void
scr_set(void)
void scr_set(void)
{
winsize_t ws;
 
Rows = 0, Cols = 0;
Rows = 0;
Cols = 0;
if (get_display_size(&ws) == 0) {
Rows = ws.ws_row;
Cols = ws.ws_col;
}
if (Rows < MINROWS || Cols < MINCOLS) {
 
use_color = get_display_color_sup();
if ((Rows < MINROWS) || (Cols < MINCOLS)) {
char smallscr[55];
 
snprintf(smallscr, sizeof(smallscr),
"the screen is too small (must be at least %dx%d)",
MINROWS, MINCOLS);
164,7 → 168,7
stop(smallscr);
}
isset = 1;
 
scr_clear();
}
 
171,76 → 175,80
/*
* End screen mode.
*/
void
scr_end(void)
void scr_end(void)
{
console_cursor_visibility(fphone(stdout), 1);
}
 
void
stop(char *why)
void stop(char *why)
{
 
if (isset)
scr_end();
errx(1, "aborting: %s", why);
}
 
 
/*
* Update the screen.
*/
void
scr_update(void)
void scr_update(void)
{
cell *bp, *sp;
cell so, cur_so = 0;
int i, ccol, j;
static const struct shape *lastshape;
 
/* always leave cursor after last displayed point */
cell *bp;
cell *sp;
cell so;
cell cur_so = 0;
int i;
int j;
int ccol;
/* Always leave cursor after last displayed point */
curscreen[D_LAST * B_COLS - 1] = -1;
 
if (score != curscore) {
moveto(0, 0);
printf("Score: %d", score);
curscore = score;
}
 
/* draw preview of next pattern */
if (showpreview && (nextshape != lastshape)) {
/* Draw preview of next pattern */
if ((showpreview) && (nextshape != lastshape)) {
int i;
static int r=5, c=2;
static int r = 5, c = 2;
int tr, tc, t;
 
lastshape = nextshape;
 
/* clean */
/* Clean */
resume_normal();
moveto(r-1, c-1); putstr(" ");
moveto(r, c-1); putstr(" ");
moveto(r+1, c-1); putstr(" ");
moveto(r+2, c-1); putstr(" ");
 
moveto(r-3, c-2);
moveto(r - 1, c - 1);
putstr(" ");
moveto(r, c - 1);
putstr(" ");
moveto(r + 1, c - 1);
putstr(" ");
moveto(r + 2, c - 1);
putstr(" ");
moveto(r - 3, c - 2);
putstr("Next shape:");
 
/* draw */
start_standout();
/* Draw */
start_standout(nextshape->color);
moveto(r, 2 * c);
putstr(" ");
for (i = 0; i < 3; i++) {
t = c + r * B_COLS;
t += nextshape->off[i];
 
tr = t / B_COLS;
tc = t % B_COLS;
 
moveto(tr, 2*tc);
putstr(" ");
}
resume_normal();
}
 
bp = &board[D_FIRST * B_COLS];
sp = &curscreen[D_FIRST * B_COLS];
for (j = D_FIRST; j < D_LAST; j++) {
248,6 → 256,7
for (i = 0; i < B_COLS; bp++, sp++, i++) {
if (*sp == (so = *bp))
continue;
*sp = so;
if (i != ccol) {
if (cur_so) {
256,15 → 265,16
}
moveto(RTOD(j), CTOD(i));
}
if (so != cur_so) {
if (so)
start_standout();
start_standout(so);
else
resume_normal();
cur_so = so;
}
putstr(" ");
 
ccol = i + 1;
/*
* Look ahead a bit, to avoid extra motion if
274,33 → 284,35
* `unnecessarily'. Skip it all, though, if
* the next cell is a different color.
*/
#define STOP (B_COLS - 3)
if (i > STOP || sp[1] != bp[1] || so != bp[1])
if ((i > STOP) || (sp[1] != bp[1]) || (so != bp[1]))
continue;
if (sp[2] != bp[2])
sp[1] = -1;
else if (i < STOP && so == bp[2] && sp[3] != bp[3]) {
else if ((i < STOP) && (so == bp[2]) && (sp[3] != bp[3])) {
sp[2] = -1;
sp[1] = -1;
}
}
}
if (cur_so)
resume_normal();
fflush();
fflush(stdout);
}
 
/*
* Write a message (set!=0), or clear the same message (set==0).
* Write a message (set != 0), or clear the same message (set == 0).
* (We need its length in case we have to overwrite with blanks.)
*/
void
scr_msg(char *s, int set)
void scr_msg(char *s, int set)
{
int l = str_size(s);
int l = strlen(s);
moveto(Rows - 2, ((Cols - l) >> 1) - 1);
moveto(Rows - 2, ((Cols - l) >> 1) - 1);
if (set)
putstr(s);
else
310,4 → 322,3
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/scores.c
36,7 → 36,7
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
48,21 → 48,18
*
* Major whacks since then.
*/
 
#include <errno.h>
/* #include <err.h> */
/* #include <fcntl.h> */
/* #include <pwd.h> */
#include <stdio.h>
/* #include <stdlib.h> */
#include <string.h>
/* #include <time.h> */
/* #include <term.h> */
/* #include <unistd.h> */
/* #include <sys/param.h> */
/* #include <sys/stat.h> */
/* #include <sys/types.h> */
#include <io/console.h>
#include <io/keycode.h>
#include <vfs/vfs.h>
#include <stdlib.h>
#include <fcntl.h>
#include <err.h>
#include <time.h>
 
#include "pathnames.h"
#include "screen.h"
#include "tetris.h"
#include "scores.h"
75,20 → 72,22
* As long as the scores are kept sorted, this is simply the first one at
* that level.
*/
#define NUMSPOTS (MAXHISCORES + 1)
#define NLEVELS (MAXLEVEL + 1)
 
/* static time_t now; */
/* static int nscores; */
/* static int gotscores; */
/* static struct highscore scores[NUMSPOTS]; */
#define NUMSPOTS (MAXHISCORES + 1)
#define NLEVELS (MAXLEVEL + 1)
 
static struct highscore scores[NUMSPOTS];
 
/* static int checkscores(struct highscore *, int); */
/* static int cmpscores(const void *, const void *); */
/* static void getscores(FILE **); */
/* static void printem(int, int, struct highscore *, int, const char *); */
/* static char *thisuser(void); */
/** Copy from hiscore table score with index src to dest
*
*/
static void copyhiscore(int dest, int src)
{
str_cpy(scores[dest].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,
scores[src].hs_name);
scores[dest].hs_score = scores[src].hs_score;
scores[dest].hs_level = scores[src].hs_level;
}
 
void showscores(int firstgame)
{
98,446 → 97,137
moveto(10, 0);
printf("\tRank \tLevel \tName\t points\n");
printf("\t========================================================\n");
for (i = 0; i < NUMSPOTS - 1; i++) {
printf("\t%6d %6d %-16s %20d\n", i+1, scores[i].hs_level, scores[i].hs_name, scores[i].hs_score);
}
for (i = 0; i < NUMSPOTS - 1; i++)
printf("\t%6d %6d %-16s %20d\n",
i + 1, scores[i].hs_level, scores[i].hs_name, scores[i].hs_score);
if (!firstgame) {
printf("\t========================================================\n");
printf("\t Last %6d %-16s %20d\n", scores[NUMSPOTS - 1].hs_level, scores[NUMSPOTS - 1].hs_name, scores[NUMSPOTS - 1].hs_score);
printf("\t Last %6d %-16s %20d\n",
scores[NUMSPOTS - 1].hs_level, scores[NUMSPOTS - 1].hs_name, scores[NUMSPOTS - 1].hs_score);
}
printf("\n\n\n\n\tPress any key to return to main menu.");
getchar();
}
 
/** Copy from hiscore table score with index src to dest
*
*/
static void copyhiscore(int dest, int src)
{
strcpy(scores[dest].hs_name, scores[src].hs_name);
scores[dest].hs_score = scores[src].hs_score;
scores[dest].hs_level = scores[src].hs_level;
}
 
void insertscore(int score, int level)
{
int i,j;
int key;
 
int i;
int j;
size_t off;
console_event_t ev;
clear_screen();
moveto(10 , 10);
moveto(10, 10);
puts("Insert your name: ");
strncpy(scores[NUMSPOTS - 1].hs_name, "Player", MAXLOGNAME);
str_cpy(scores[NUMSPOTS - 1].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,
"Player");
i = 6;
 
off = 6;
moveto(10 , 28);
printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................");
key = getchar();
while(key != '\n') {
if (key == '\b') {
if (i > 0)
scores[NUMSPOTS - 1].hs_name[--i] = '\0';
} else {
if (i < (MAXLOGNAME - 1))
scores[NUMSPOTS - 1].hs_name[i++] = key;
scores[NUMSPOTS - 1].hs_name[i] = '\0';
printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME-i,
"........................................");
while (1) {
fflush(stdout);
if (!console_get_event(fphone(stdin), &ev))
exit(1);
if (ev.type == KEY_RELEASE)
continue;
if (ev.key == KC_ENTER || ev.key == KC_NENTER)
break;
if (ev.key == KC_BACKSPACE) {
if (i > 0) {
wchar_t uc;
--i;
while (off > 0) {
--off;
size_t otmp = off;
uc = str_decode(scores[NUMSPOTS - 1].hs_name,
&otmp, STR_BOUNDS(MAXLOGNAME) + 1);
if (uc != U_SPECIAL)
break;
}
scores[NUMSPOTS - 1].hs_name[off] = '\0';
}
} else if (ev.c != '\0') {
if (i < (MAXLOGNAME - 1)) {
if (chr_encode(ev.c, scores[NUMSPOTS - 1].hs_name,
&off, STR_BOUNDS(MAXLOGNAME) + 1) == EOK) {
++i;
}
scores[NUMSPOTS - 1].hs_name[off] = '\0';
}
}
moveto(10 , 28);
printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................");
key = getchar();
moveto(10, 28);
printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME - i,
"........................................");
}
scores[NUMSPOTS - 1].hs_score = score;
scores[NUMSPOTS - 1].hs_score = score;
scores[NUMSPOTS - 1].hs_level = level;
i = NUMSPOTS-1;
i = NUMSPOTS - 1;
while ((i > 0) && (scores[i - 1].hs_score < score))
i--;
 
for (j = NUMSPOTS - 2; j > i; j--) {
copyhiscore(j,j-1);
}
copyhiscore(i, NUMSPOTS - 1);
for (j = NUMSPOTS - 2; j > i; j--)
copyhiscore(j, j-1);
copyhiscore(i, NUMSPOTS - 1);
}
 
void initscores(void)
{
int i;
for(i = 0; i < NUMSPOTS; i++) {
strncpy(scores[i].hs_name, "HelenOS Team", MAXLOGNAME);
scores[i].hs_score = (NUMSPOTS - i) * 200;
scores[i].hs_level = (i + 1 > MAXLEVEL?MAXLEVEL:i + 1);
for (i = 0; i < NUMSPOTS; i++) {
str_cpy(scores[i].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, "HelenOS Team");
scores[i].hs_score = (NUMSPOTS - i) * 200;
scores[i].hs_level = (i + 1 > MAXLEVEL ? MAXLEVEL : i + 1);
}
}
 
/*
* Read the score file. Can be called from savescore (before showscores)
* or showscores (if savescore will not be called). If the given pointer
* is not NULL, sets *fpp to an open file pointer that corresponds to a
* read/write score file that is locked with LOCK_EX. Otherwise, the
* file is locked with LOCK_SH for the read and closed before return.
*
* Note, we assume closing the stdio file releases the lock.
*/
/* static void */
/* getscores(FILE **fpp) */
/* { */
/* int sd, mint, lck, mask, i; */
/* char *mstr, *human; */
/* FILE *sf; */
int loadscores(void)
{
FILE *f;
size_t cnt;
int rc;
 
/* if (fpp != NULL) { */
/* mint = O_RDWR | O_CREAT; */
/* mstr = "r+"; */
/* human = "read/write"; */
/* lck = LOCK_EX; */
/* } else { */
/* mint = O_RDONLY; */
/* mstr = "r"; */
/* human = "reading"; */
/* lck = LOCK_SH; */
/* } */
/* setegid(egid); */
/* mask = umask(S_IWOTH); */
/* sd = open(_PATH_SCOREFILE, mint, 0666); */
/* (void)umask(mask); */
/* setegid(gid); */
/* if (sd < 0) { */
/* if (fpp == NULL) { */
/* nscores = 0; */
/* return; */
/* } */
/* err(1, "cannot open %s for %s", _PATH_SCOREFILE, human); */
/* } */
/* setegid(egid); */
/* if ((sf = fdopen(sd, mstr)) == NULL) */
/* err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human); */
/* setegid(gid); */
f = fopen("/data/tetris.sco", "rb");
if (f == NULL)
return ENOENT;
 
/* /\* */
/* * Grab a lock. */
/* *\/ */
/* if (flock(sd, lck)) */
/* warn("warning: score file %s cannot be locked", */
/* _PATH_SCOREFILE); */
cnt = fread(scores, sizeof(struct highscore), NUMSPOTS, f);
rc = fclose(f);
 
/* nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf); */
/* if (ferror(sf)) */
/* err(1, "error reading %s", _PATH_SCOREFILE); */
/* for (i = 0; i < nscores; i++) */
/* if (scores[i].hs_level < MINLEVEL || */
/* scores[i].hs_level > MAXLEVEL) */
/* errx(1, "scorefile %s corrupt", _PATH_SCOREFILE); */
if (cnt != NUMSPOTS || rc != 0)
return EIO;
 
/* if (fpp) */
/* *fpp = sf; */
/* else */
/* (void)fclose(sf); */
/* } */
return EOK;
}
 
void
savescore(int level)
void savescores(void)
{
return;
}
/* struct highscore *sp; */
/* int i; */
/* int change; */
/* FILE *sf; */
/* const char *me; */
FILE *f;
size_t cnt;
int rc;
 
/* getscores(&sf); */
/* gotscores = 1; */
/* (void)time(&now); */
f = fopen("/data/tetris.sco", "wb");
cnt = fwrite(scores, sizeof(struct highscore), NUMSPOTS, f);
rc = fclose(f);
 
/* /\* */
/* * Allow at most one score per person per level -- see if we */
/* * can replace an existing score, or (easiest) do nothing. */
/* * Otherwise add new score at end (there is always room). */
/* *\/ */
/* change = 0; */
/* me = thisuser(); */
/* for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) { */
/* if (sp->hs_level != level || strcmp(sp->hs_name, me) != 0) */
/* continue; */
/* if (score > sp->hs_score) { */
/* (void)printf("%s bettered %s %d score of %d!\n", */
/* "\nYou", "your old level", level, */
/* sp->hs_score * sp->hs_level); */
/* sp->hs_score = score; /\* new score *\/ */
/* sp->hs_time = now; /\* and time *\/ */
/* change = 1; */
/* } else if (score == sp->hs_score) { */
/* (void)printf("%s tied %s %d high score.\n", */
/* "\nYou", "your old level", level); */
/* sp->hs_time = now; /\* renew it *\/ */
/* change = 1; /\* gotta rewrite, sigh *\/ */
/* } /\* else new score < old score: do nothing *\/ */
/* break; */
/* } */
/* if (i >= nscores) { */
/* strlcpy(sp->hs_name, me, sizeof sp->hs_name); */
/* sp->hs_level = level; */
/* sp->hs_score = score; */
/* sp->hs_time = now; */
/* nscores++; */
/* change = 1; */
/* } */
 
/* if (change) { */
/* /\* */
/* * Sort & clean the scores, then rewrite. */
/* *\/ */
/* nscores = checkscores(scores, nscores); */
/* rewind(sf); */
/* if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores || */
/* fflush(sf) == EOF) */
/* warnx("error writing %s: %s\n\t-- %s", */
/* _PATH_SCOREFILE, strerror(errno), */
/* "high scores may be damaged"); */
/* } */
/* (void)fclose(sf); /\* releases lock *\/ */
/* } */
 
/*
* Get login name, or if that fails, get something suitable.
* The result is always trimmed to fit in a score.
*/
/* static char * */
/* thisuser(void) */
/* { */
/* const char *p; */
/* struct passwd *pw; */
/* static char u[sizeof(scores[0].hs_name)]; */
 
/* if (u[0]) */
/* return (u); */
/* p = getlogin(); */
/* if (p == NULL || *p == '\0') { */
/* pw = getpwuid(getuid()); */
/* if (pw != NULL) */
/* p = pw->pw_name; */
/* else */
/* p = " ???"; */
/* } */
/* strlcpy(u, p, sizeof(u)); */
/* return (u); */
/* } */
 
/*
* Score comparison function for qsort.
*
* If two scores are equal, the person who had the score first is
* listed first in the highscore file.
*/
/* static int */
/* cmpscores(const void *x, const void *y) */
/* { */
/* const struct highscore *a, *b; */
/* long l; */
 
/* a = x; */
/* b = y; */
/* l = (long)b->hs_level * b->hs_score - (long)a->hs_level * a->hs_score; */
/* if (l < 0) */
/* return (-1); */
/* if (l > 0) */
/* return (1); */
/* if (a->hs_time < b->hs_time) */
/* return (-1); */
/* if (a->hs_time > b->hs_time) */
/* return (1); */
/* return (0); */
/* } */
 
/*
* If we've added a score to the file, we need to check the file and ensure
* that this player has only a few entries. The number of entries is
* controlled by MAXSCORES, and is to ensure that the highscore file is not
* monopolised by just a few people. People who no longer have accounts are
* only allowed the highest score. Scores older than EXPIRATION seconds are
* removed, unless they are someone's personal best.
* Caveat: the highest score on each level is always kept.
*/
/* static int */
/* checkscores(struct highscore *hs, int num) */
/* { */
/* struct highscore *sp; */
/* int i, j, k, numnames; */
/* int levelfound[NLEVELS]; */
/* struct peruser { */
/* char *name; */
/* int times; */
/* } count[NUMSPOTS]; */
/* struct peruser *pu; */
 
/* /\* */
/* * Sort so that highest totals come first. */
/* * */
/* * levelfound[i] becomes set when the first high score for that */
/* * level is encountered. By definition this is the highest score. */
/* *\/ */
/* qsort((void *)hs, nscores, sizeof(*hs), cmpscores); */
/* for (i = MINLEVEL; i < NLEVELS; i++) */
/* levelfound[i] = 0; */
/* numnames = 0; */
/* for (i = 0, sp = hs; i < num;) { */
/* /\* */
/* * This is O(n^2), but do you think we care? */
/* *\/ */
/* for (j = 0, pu = count; j < numnames; j++, pu++) */
/* if (strcmp(sp->hs_name, pu->name) == 0) */
/* break; */
/* if (j == numnames) { */
/* /\* */
/* * Add new user, set per-user count to 1. */
/* *\/ */
/* pu->name = sp->hs_name; */
/* pu->times = 1; */
/* numnames++; */
/* } else { */
/* /\* */
/* * Two ways to keep this score: */
/* * - Not too many (per user), still has acct, & */
/* * score not dated; or */
/* * - High score on this level. */
/* *\/ */
/* if ((pu->times < MAXSCORES && */
/* getpwnam(sp->hs_name) != NULL && */
/* sp->hs_time + EXPIRATION >= now) || */
/* levelfound[sp->hs_level] == 0) */
/* pu->times++; */
/* else { */
/* /\* */
/* * Delete this score, do not count it, */
/* * do not pass go, do not collect $200. */
/* *\/ */
/* num--; */
/* for (k = i; k < num; k++) */
/* hs[k] = hs[k + 1]; */
/* continue; */
/* } */
/* } */
/* levelfound[sp->hs_level] = 1; */
/* i++, sp++; */
/* } */
/* return (num > MAXHISCORES ? MAXHISCORES : num); */
/* } */
 
/*
* Show current scores. This must be called after savescore, if
* savescore is called at all, for two reasons:
* - Showscores munches the time field.
* - Even if that were not the case, a new score must be recorded
* before it can be shown anyway.
*/
/*
void
showscores(int level)
{
return;
if (cnt != NUMSPOTS || rc != 0)
printf("Error saving score table\n");
}
*/
/* struct highscore *sp; */
/* int i, n, c; */
/* const char *me; */
/* int levelfound[NLEVELS]; */
 
/* if (!gotscores) */
/* getscores((FILE **)NULL); */
/* (void)printf("\n\t\t Tetris High Scores\n"); */
 
/* /\* */
/* * If level == 0, the person has not played a game but just asked for */
/* * the high scores; we do not need to check for printing in highlight */
/* * mode. If SOstr is null, we can't do highlighting anyway. */
/* *\/ */
/* me = level && SOstr ? thisuser() : NULL; */
 
/* /\* */
/* * Set times to 0 except for high score on each level. */
/* *\/ */
/* for (i = MINLEVEL; i < NLEVELS; i++) */
/* levelfound[i] = 0; */
/* for (i = 0, sp = scores; i < nscores; i++, sp++) { */
/* if (levelfound[sp->hs_level]) */
/* sp->hs_time = 0; */
/* else { */
/* sp->hs_time = 1; */
/* levelfound[sp->hs_level] = 1; */
/* } */
/* } */
 
/* /\* */
/* * Page each screenful of scores. */
/* *\/ */
/* for (i = 0, sp = scores; i < nscores; sp += n) { */
/* n = 20; */
/* if (i + n > nscores) */
/* n = nscores - i; */
/* printem(level, i + 1, sp, n, me); */
/* if ((i += n) < nscores) { */
/* (void)printf("\nHit RETURN to continue."); */
/* (void)fflush(stdout); */
/* while ((c = getchar()) != '\n') */
/* if (c == EOF) */
/* break; */
/* (void)printf("\n"); */
/* } */
/* } */
 
/* if (nscores == 0) */
/* printf("\t\t\t - none to date.\n"); */
/* } */
 
/* static void */
/* printem(int level, int offset, struct highscore *hs, int n, const char *me) */
/* { */
/* struct highscore *sp; */
/* int row, highlight, i; */
/* char buf[100]; */
/* #define TITLE "Rank Score Name (points/level)" */
/* #define TITL2 "==========================================================" */
 
/* printf("%s\n%s\n", TITLE, TITL2); */
 
/* highlight = 0; */
 
/* for (row = 0; row < n; row++) { */
/* sp = &hs[row]; */
/* (void)snprintf(buf, sizeof(buf), */
/* "%3d%c %6d %-31s (%6d on %d)\n", */
/* row + offset, sp->hs_time ? '*' : ' ', */
/* sp->hs_score * sp->hs_level, */
/* sp->hs_name, sp->hs_score, sp->hs_level); */
/* /\* Print leaders every three lines *\/ */
/* if ((row + 1) % 3 == 0) { */
/* for (i = 0; i < sizeof(buf); i++) */
/* if (buf[i] == ' ') */
/* buf[i] = '_'; */
/* } */
/* /\* */
/* * Highlight if appropriate. This works because */
/* * we only get one score per level. */
/* *\/ */
/* if (me != NULL && */
/* sp->hs_level == level && */
/* sp->hs_score == score && */
/* strcmp(sp->hs_name, me) == 0) { */
/* putpad(SOstr); */
/* highlight = 1; */
/* } */
/* (void)printf("%s", buf); */
/* if (highlight) { */
/* putpad(SEstr); */
/* highlight = 0; */
/* } */
/* } */
/* } */
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/scores.h
34,8 → 34,9
*
* @(#)scores.h 8.1 (Berkeley) 5/31/93
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
44,24 → 45,27
/*
* Tetris scores.
*/
 
#include <sys/time.h>
#define MAXLOGNAME 16
#include <string.h>
 
#define MAXLOGNAME 16
#define MAXHISCORES 10
#define MAXSCORES 9 /* maximum high score entries per person */
#define EXPIRATION (5L * 365 * 24 * 60 * 60)
 
struct highscore {
char hs_name[MAXLOGNAME + 1]; /* login name */
int hs_score; /* raw score */
int hs_level; /* play level */
// time_t hs_time; /* time at game end */
char hs_name[STR_BOUNDS(MAXLOGNAME) + 1]; /* login name */
int hs_score; /* raw score */
int hs_level; /* play level */
time_t hs_time; /* time at game end */
};
 
#define MAXHISCORES 10
//#define MAXSCORES 9 /* maximum high score entries per person */
//#define EXPIRATION (5L * 365 * 24 * 60 * 60)
extern void showscores(int);
extern void initscores(void);
extern void insertscore(int score, int level);
extern int loadscores(void);
extern void savescores(void);
 
void savescore(int);
void showscores(int);
void insertscore(int score, int level);
void initscores(void);
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/tetris.c
36,30 → 36,25
*/
 
/** @addtogroup tetris Tetris
* @brief Tetris ported from OpenBSD
* @{
* @brief Tetris ported from OpenBSD
* @{
*/
/** @file
*/
 
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
"@(#) Copyright (c) 1992, 1993\n"
"\tThe Regents of the University of California. All rights reserved.\n";
 
/*
* Tetris (or however it is spelled).
*/
 
#include <sys/time.h>
#include <sys/types.h>
 
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
 
#include "input.h"
#include "scores.h"
66,66 → 61,76
#include "screen.h"
#include "tetris.h"
 
cell board[B_SIZE];
int Rows, Cols;
cell board[B_SIZE];
 
int Rows;
int Cols;
 
const struct shape *curshape;
const struct shape *nextshape;
long fallrate;
int score;
//gid_t gid, egid;
char key_msg[100];
int showpreview, classic;
 
static void elide(void);
static void setup_board(void);
const struct shape *randshape(void);
void onintr(int);
void usage(void);
long fallrate;
int score;
char key_msg[100];
int showpreview;
int classic;
 
static void elide(void);
static void setup_board(void);
static const struct shape *randshape(void);
 
static void usage(void);
 
static int firstgame = 1;
 
/*
* Set up the initial board. The bottom display row is completely set,
* along with another (hidden) row underneath that. Also, the left and
* Set up the initial board. The bottom display row is completely set,
* along with another (hidden) row underneath that. Also, the left and
* right edges are set.
*/
static void
setup_board(void)
static void setup_board(void)
{
int i;
cell *p;
 
p = board;
cell *p = board;
for (i = B_SIZE; i; i--)
*p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2;
*p++ = (i <= (2 * B_COLS) || (i % B_COLS) < 2) ? 0x0000ff : 0x000000;
}
 
/*
* Elide any full active rows.
*/
static void
elide(void)
static void elide(void)
{
int rows = 0;
int i, j, base;
int i;
int j;
int base;
cell *p;
 
for (i = A_FIRST; i < A_LAST; i++) {
base = i * B_COLS + 1;
p = &board[base];
for (j = B_COLS - 2; *p++ != 0;) {
if (--j <= 0) {
/* this row is to be elided */
/* This row is to be elided */
rows++;
memset(&board[base], 0, B_COLS - 2);
memset(&board[base], 0, sizeof(cell) * (B_COLS - 2));
scr_update();
tsleep();
while (--base != 0)
board[base + B_COLS] = board[base];
scr_update();
tsleep();
break;
}
}
}
switch (rows) {
case 1:
score += 10;
144,16 → 149,15
}
}
 
const struct shape *
randshape(void)
const struct shape *randshape(void)
{
const struct shape *tmp;
int i, j;
 
tmp = &shapes[random() % 7];
j = random() % 4;
const struct shape *tmp = &shapes[random() % 7];
int i;
int j = random() % 4;
for (i = 0; i < j; i++)
tmp = &shapes[classic? tmp->rotc : tmp->rot];
tmp = &shapes[classic ? tmp->rotc : tmp->rot];
return (tmp);
}
 
160,7 → 164,7
static void srandomdev(void)
{
struct timeval tv;
 
gettimeofday(&tv, NULL);
srandom(tv.tv_sec + tv.tv_usec / 100000);
}
167,61 → 171,43
 
static void tetris_menu_draw(int level)
{
clear_screen();
moveto(5,10);
puts("Tetris\n\n");
moveto(8,10);
printf("Level = %d (press keys 1 - 9 to change)",level);
moveto(9,10);
printf("Preview is %s (press 'p' to change)", (showpreview?"on ":"off"));
moveto(12,10);
printf("Press 'h' to show hiscore table.");
moveto(13,10);
printf("Press 's' to start game.");
moveto(14,10);
printf("Press 'q' to quit game.");
moveto(20,10);
printf("In game controls:");
moveto(21,0);
puts(key_msg);
clear_screen();
moveto(5, 10);
puts("Tetris\n\n");
moveto(8, 10);
printf("Level = %d (press keys 1 - 9 to change)", level);
moveto(9, 10);
printf("Preview is %s (press 'p' to change)", (showpreview ? "on ": "off"));
moveto(12, 10);
printf("Press 'h' to show hiscore table.");
moveto(13, 10);
printf("Press 's' to start game.");
moveto(14, 10);
printf("Press 'q' to quit game.");
moveto(20, 10);
printf("In game controls:");
moveto(21, 0);
puts(key_msg);
}
 
static int tetris_menu(int *level)
static int tetris_menu(int *level)
{
static int firstgame = 1;
int i;
/* if (showpreview == 0)
(void)printf("Your score: %d point%s x level %d = %d\n",
score, score == 1 ? "" : "s", level, score * level);
else {
(void)printf("Your score: %d point%s x level %d x preview penalty %0.3f = %d\n",
score, score == 1 ? "" : "s", level, (double)PRE_PENALTY,
(int)(score * level * PRE_PENALTY));
score = score * PRE_PENALTY;
}
savescore(level);
 
showscores(level);
printf("\nHit 's' to new game, 'q' to quit.\n");
*/
tetris_menu_draw(*level);
while (1) {
i = getchar();
int i = getchar();
switch(i) {
case 'p':
showpreview = !showpreview;
moveto(9,21);
moveto(9, 21);
if (showpreview)
printf("on ");
else
printf("off");
break;
case 'h':
loadscores();
showscores(firstgame);
tetris_menu_draw(*level);
break;
235,112 → 221,103
case '3':
case '4':
case '5':
case '6':
case '6':
case '7':
case '8':
case '9':
*level = i - '0';
moveto(8,18);
moveto(8, 18);
printf("%d", *level);
break;
}
}
}
 
int
main(int argc, char *argv[])
int main(int argc, char *argv[])
{
int pos, c;
int pos;
int c;
char *keys;
int level = 2;
char key_write[6][10];
int i, j;
 
int i;
int j;
int ch;
keys = "jkl pq";
 
// gid = getgid();
// egid = getegid();
// setegid(gid);
 
classic = 0;
showpreview = 1;
 
/* while ((ch = getopt(argc, argv, "ck:l:ps")) != -1) */
/* switch(ch) { */
/* case 'c': */
/* /\* */
/* * this means: */
/* * - rotate the other way; */
/* * - no reverse video. */
/* *\/ */
/* classic = 1; */
/* break; */
/* case 'k': */
/* if (strlen(keys = optarg) != 6) */
/* usage(); */
/* break; */
/* case 'l': */
/* level = (int)strtonum(optarg, MINLEVEL, MAXLEVEL, */
/* &errstr); */
/* if (errstr) */
/* errx(1, "level must be from %d to %d", */
/* MINLEVEL, MAXLEVEL); */
/* break; */
/* case 'p': */
/* showpreview = 1; */
/* break; */
/* case 's': */
/* showscores(0); */
/* exit(0); */
/* default: */
/* usage(); */
/* } */
 
/* argc -= optind; */
/* argv += optind; */
 
/* if (argc) */
/* usage(); */
 
 
while ((ch = getopt(argc, argv, "ck:ps")) != -1)
switch(ch) {
case 'c':
/*
* this means:
* - rotate the other way
* - no reverse video
*/
classic = 1;
break;
case 'k':
if (str_size(keys = optarg) != 6)
usage();
break;
case 'p':
showpreview = 1;
break;
case 's':
showscores(0);
exit(0);
default:
usage();
}
argc -= optind;
argv += optind;
if (argc)
usage();
for (i = 0; i <= 5; i++) {
for (j = i+1; j <= 5; j++) {
for (j = i + 1; j <= 5; j++) {
if (keys[i] == keys[j])
errx(1, "duplicate command keys specified.");
}
if (keys[i] == ' ')
strncpy(key_write[i], "<space>", sizeof key_write[i]);
str_cpy(key_write[i], sizeof(key_write[i]), "<space>");
else {
key_write[i][0] = keys[i];
key_write[i][1] = '\0';
}
}
snprintf(key_msg, sizeof(key_msg),
"%s - left %s - rotate %s - right %s - drop %s - pause %s - quit",
key_write[0], key_write[1], key_write[2], key_write[3],
key_write[4], key_write[5]);
scr_init();
if (loadscores() != EOK)
initscores();
 
snprintf(key_msg, sizeof key_msg,
"%s - left %s - rotate %s - right %s - drop %s - pause %s - quit",
key_write[0], key_write[1], key_write[2], key_write[3],
key_write[4], key_write[5]);
 
scr_init();
initscores();
while (tetris_menu(&level)) {
fallrate = 1000000 / level;
scr_clear();
setup_board();
srandomdev();
scr_set();
pos = A_FIRST*B_COLS + (B_COLS/2)-1;
pos = A_FIRST * B_COLS + (B_COLS / 2) - 1;
nextshape = randshape();
curshape = randshape();
scr_msg(key_msg, 1);
for (;;) {
while (1) {
place(curshape, pos, 1);
scr_update();
place(curshape, pos, 0);
353,7 → 330,7
pos += B_COLS;
continue;
}
/*
* Put up the current shape `permanently',
* bump score, and elide any full rows.
361,7 → 338,7
place(curshape, pos, 1);
score++;
elide();
/*
* Choose a new shape. If it does not fit,
* the game is over.
368,12 → 345,14
*/
curshape = nextshape;
nextshape = randshape();
pos = A_FIRST*B_COLS + (B_COLS/2)-1;
pos = A_FIRST * B_COLS + (B_COLS / 2) - 1;
if (!fits_in(curshape, pos))
break;
continue;
}
/*
* Handle command keys.
*/
381,22 → 360,25
/* quit */
break;
}
if (c == keys[4]) {
static char msg[] =
"paused - press RETURN to continue";
place(curshape, pos, 1);
do {
scr_update();
scr_msg(key_msg, 0);
scr_msg(msg, 1);
// (void) fflush(stdout);
} while (rwait((struct timeval *)NULL) == -1);
(void) fflush(stdout);
} while (rwait((struct timeval *) NULL) == -1);
scr_msg(msg, 0);
scr_msg(key_msg, 1);
place(curshape, pos, 0);
continue;
}
if (c == keys[0]) {
/* move left */
if (fits_in(curshape, pos - 1))
403,15 → 385,17
pos--;
continue;
}
if (c == keys[1]) {
/* turn */
const struct shape *new = &shapes[
classic? curshape->rotc : curshape->rot];
const struct shape *new =
&shapes[classic ? curshape->rotc : curshape->rot];
if (fits_in(new, pos))
curshape = new;
continue;
}
if (c == keys[2]) {
/* move right */
if (fits_in(curshape, pos + 1))
418,6 → 402,7
pos++;
continue;
}
if (c == keys[3]) {
/* move to bottom */
while (fits_in(curshape, pos + B_COLS)) {
426,6 → 411,7
}
continue;
}
if (c == '\f') {
scr_clear();
scr_msg(key_msg, 1);
433,37 → 419,24
}
scr_clear();
loadscores();
insertscore(score, level);
score=0;
savescores();
score = 0;
}
scr_clear();
printf("\n\n\n\t\tGame over.\n");
/*
while ((i = getchar()) != '\n')
if (i == EOF)
break
*/
printf("\nGame over.\n");
scr_end();
 
return 0;
}
 
/* void */
/* onintr(int signo) */
/* { */
/* scr_clear(); /\* XXX signal race *\/ */
/* scr_end(); /\* XXX signal race *\/ */
/* _exit(0); */
/* } */
 
void
usage(void)
void usage(void)
{
(void)fprintf(stderr, "usage: tetris [-ps] [-k keys] [-l level]\n");
fprintf(stderr, "usage: tetris [-ps] [-k keys]\n");
exit(1);
}
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/input.c
36,7 → 36,7
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
57,7 → 57,9
#include "tetris.h"
 
#include <async.h>
#include "../../srv/console/console.h"
#include <vfs/vfs.h>
#include <io/console.h>
#include <ipc/console.h>
 
/* return true iff the given timeval is positive */
#define TV_POS(tv) \
90,14 → 92,12
* Return 0 => no input, 1 => can read() from stdin
*
*/
int
rwait(struct timeval *tvp)
int rwait(struct timeval *tvp)
{
struct timeval starttv, endtv, *s;
static ipc_call_t charcall;
ipcarg_t rc;
int cons_phone;
 
/*
* Someday, select() will do this for us.
* Just in case that day is now, and no one has
109,14 → 109,15
s = &endtv;
} else
s = NULL;
 
if (!lastchar) {
again:
if (!getchar_inprog) {
cons_phone = get_cons_phone();
getchar_inprog = async_send_2(cons_phone,
CONSOLE_GETCHAR, 0, 0, &charcall);
getchar_inprog = async_send_0(fphone(stdin),
CONSOLE_GET_EVENT, &charcall);
}
if (!s)
if (!s)
async_wait_for(getchar_inprog, &rc);
else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
tvp->tv_sec = 0;
123,19 → 124,25
tvp->tv_usec = 0;
return (0);
}
getchar_inprog = 0;
if (rc) {
if (rc)
stop("end of file, help");
}
lastchar = IPC_GET_ARG1(charcall);
if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
goto again;
lastchar = IPC_GET_ARG4(charcall);
}
if (tvp) {
/* since there is input, we may not have timed out */
(void) gettimeofday(&endtv, NULL);
TV_SUB(&endtv, &starttv);
TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */
TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */
}
return (1);
return 1;
}
 
/*
142,11 → 149,10
* `sleep' for the current turn time (using select).
* Eat any input that might be available.
*/
void
tsleep(void)
void tsleep(void)
{
struct timeval tv;
 
tv.tv_sec = 0;
tv.tv_usec = fallrate;
while (TV_POS(&tv))
159,12 → 165,11
/*
* getchar with timeout.
*/
int
tgetchar(void)
int tgetchar(void)
{
static struct timeval timeleft;
char c;
 
/*
* Reset timeleft to fallrate whenever it is not positive.
* In any case, wait to see if there is any input. If so,
175,17 → 180,18
* Most of the hard work is done by rwait().
*/
if (!TV_POS(&timeleft)) {
faster(); /* go faster */
faster(); /* go faster */
timeleft.tv_sec = 0;
timeleft.tv_usec = fallrate;
}
if (!rwait(&timeleft))
return (-1);
return -1;
c = lastchar;
lastchar = '\0';
return ((int)(unsigned char)c);
return ((int) (unsigned char) c);
}
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/tetris.h
36,7 → 36,7
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
55,57 → 55,60
* worrying about addressing problems.
*/
 
/* the board */
#define B_COLS 12
#define B_ROWS 23
#define B_SIZE (B_ROWS * B_COLS)
/* The board */
#define B_COLS 12
#define B_ROWS 23
#define B_SIZE (B_ROWS * B_COLS)
 
typedef unsigned char cell;
extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */
typedef uint32_t cell;
 
/* the displayed area (rows) */
#define D_FIRST 1
#define D_LAST 22
extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */
 
/* the active area (rows) */
#define A_FIRST 1
#define A_LAST 21
/* The displayed area (rows) */
#define D_FIRST 1
#define D_LAST 22
 
/* The active area (rows) */
#define A_FIRST 1
#define A_LAST 21
 
/*
* Minimum display size.
*/
#define MINROWS 23
#define MINCOLS 40
#define MINROWS 23
#define MINCOLS 40
 
extern int Rows, Cols; /* current screen size */
/* Current screen size */
extern int Rows;
extern int Cols;
 
/*
* Translations from board coordinates to display coordinates.
* As with board coordinates, display coordiates are zero origin.
*/
#define RTOD(x) ((x) - 1)
#define CTOD(x) ((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1))
#define RTOD(x) ((x) - 1)
#define CTOD(x) ((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1))
 
/*
* A `shape' is the fundamental thing that makes up the game. There
* are 7 basic shapes, each consisting of four `blots':
*
* X.X X.X X.X
* X.X X.X X.X.X X.X X.X.X X.X.X X.X.X.X
* X X X
* X.X X.X X.X
* X.X X.X X.X.X X.X X.X.X X.X.X X.X.X.X
* X X X
*
* 0 1 2 3 4 5 6
* 0 1 2 3 4 5 6
*
* Except for 3 and 6, the center of each shape is one of the blots.
* This blot is designated (0,0). The other three blots can then be
* This blot is designated (0, 0). The other three blots can then be
* described as offsets from the center. Shape 3 is the same under
* rotation, so its center is effectively irrelevant; it has been chosen
* so that it `sticks out' upward and leftward. Except for shape 6,
* all the blots are contained in a box going from (-1,-1) to (+1,+1);
* all the blots are contained in a box going from (-1, -1) to (+1, +1);
* shape 6's center `wobbles' as it rotates, so that while it `sticks out'
* rightward, its rotation---a vertical line---`sticks out' downward.
* The containment box has to include the offset (2,0), making the overall
* containment box range from offset (-1,-1) to (+2,+1). (This is why
* The containment box has to include the offset (2, 0), making the overall
* containment box range from offset (-1, -1) to (+2, +1). (This is why
* there is only one row above, but two rows below, the display area.)
*
* The game works by choosing one of these shapes at random and putting
116,7 → 119,7
* At this time, any completely filled rows are elided, and blots above
* these rows move down to make more room. A new random shape is again
* introduced at the top of the board, and the whole process repeats.
* The game ends when the new shape will not fit at (1,5).
* The game ends when the new shape will not fit at (1, 5).
*
* While the shapes are falling, the user can rotate them counterclockwise
* 90 degrees (in addition to moving them left or right), provided that the
128,9 → 131,10
* rotated forms.
*/
struct shape {
int rot; /* index of rotated version of this shape */
int rotc; /* -- " -- in classic version */
int off[3]; /* offsets to other blots if center is at (0,0) */
int rot; /* index of rotated version of this shape */
int rotc; /* -- " -- in classic version */
int off[3]; /* offsets to other blots if center is at (0,0) */
uint32_t color;
};
 
extern const struct shape shapes[];
148,15 → 152,16
* The value eventually reaches a limit, and things stop going faster,
* but by then the game is utterly impossible.
*/
extern long fallrate; /* less than 1 million; smaller => faster */
#define faster() (fallrate -= fallrate / 3000)
extern long fallrate; /* less than 1 million; smaller => faster */
 
#define faster() (fallrate -= fallrate / 3000)
 
/*
* Game level must be between 1 and 9. This controls the initial fall rate
* and affects scoring.
*/
#define MINLEVEL 1
#define MAXLEVEL 9
#define MINLEVEL 1
#define MAXLEVEL 9
 
/*
* Scoring is as follows:
170,19 → 175,17
*
* If previewing has been turned on, the score is multiplied by PRE_PENALTY.
*/
#define PRE_PENALTY 0.75
#define PRE_PENALTY 0.75
 
extern int score; /* the obvious thing */
//extern gid_t gid, egid;
extern int score; /* The obvious thing */
 
extern char key_msg[100];
extern int showpreview;
extern int classic;
extern char key_msg[100];
extern int showpreview;
extern int classic;
 
int fits_in(const struct shape *, int);
void place(const struct shape *, int, int);
void stop(char *);
extern int fits_in(const struct shape *, int);
extern void place(const struct shape *, int, int);
extern void stop(char *);
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/shapes.c
36,7 → 36,7
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
50,35 → 50,35
#include <unistd.h>
#include "tetris.h"
 
#define TL -B_COLS-1 /* top left */
#define TC -B_COLS /* top center */
#define TR -B_COLS+1 /* top right */
#define ML -1 /* middle left */
#define MR 1 /* middle right */
#define BL B_COLS-1 /* bottom left */
#define BC B_COLS /* bottom center */
#define BR B_COLS+1 /* bottom right */
#define TL (-B_COLS - 1) /* top left */
#define TC (-B_COLS) /* top center */
#define TR (-B_COLS + 1) /* top right */
#define ML -1 /* middle left */
#define MR 1 /* middle right */
#define BL (B_COLS - 1) /* bottom left */
#define BC B_COLS /* bottom center */
#define BR (B_COLS + 1) /* bottom right */
 
const struct shape shapes[] = {
/* 0*/ { 7, 7, { TL, TC, MR } },
/* 1*/ { 8, 8, { TC, TR, ML } },
/* 2*/ { 9, 11, { ML, MR, BC } },
/* 3*/ { 3, 3, { TL, TC, ML } },
/* 4*/ { 12, 14, { ML, BL, MR } },
/* 5*/ { 15, 17, { ML, BR, MR } },
/* 6*/ { 18, 18, { ML, MR, 2 } }, /* sticks out */
/* 7*/ { 0, 0, { TC, ML, BL } },
/* 8*/ { 1, 1, { TC, MR, BR } },
/* 9*/ { 10, 2, { TC, MR, BC } },
/*10*/ { 11, 9, { TC, ML, MR } },
/*11*/ { 2, 10, { TC, ML, BC } },
/*12*/ { 13, 4, { TC, BC, BR } },
/*13*/ { 14, 12, { TR, ML, MR } },
/*14*/ { 4, 13, { TL, TC, BC } },
/*15*/ { 16, 5, { TR, TC, BC } },
/*16*/ { 17, 15, { TL, MR, ML } },
/*17*/ { 5, 16, { TC, BC, BL } },
/*18*/ { 6, 6, { TC, BC, 2*B_COLS } }/* sticks out */
/* 0 */ { 7, 7, { TL, TC, MR }, 0xff042d},
/* 1 */ { 8, 8, { TC, TR, ML }, 0xff9304},
/* 2 */ { 9, 11, { ML, MR, BC }, 0xbeff04},
/* 3 */ { 3, 3, { TL, TC, ML }, 0x63ff04},
/* 4 */ { 12, 14, { ML, BL, MR }, 0xce04ff},
/* 5 */ { 15, 17, { ML, BR, MR }, 0xff04cf},
/* 6 */ { 18, 18, { ML, MR, 2 }, 0x7604ff}, /* sticks out */
/* 7 */ { 0, 0, { TC, ML, BL }, 0xff042d},
/* 8 */ { 1, 1, { TC, MR, BR }, 0xff9304},
/* 9 */ { 10, 2, { TC, MR, BC }, 0xbeff04},
/* 10 */ { 11, 9, { TC, ML, MR }, 0xbeff04},
/* 11 */ { 2, 10, { TC, ML, BC }, 0xbeff04},
/* 12 */ { 13, 4, { TC, BC, BR }, 0xce04ff},
/* 13 */ { 14, 12, { TR, ML, MR }, 0xce04ff},
/* 14 */ { 4, 13, { TL, TC, BC }, 0xce04ff},
/* 15 */ { 16, 5, { TR, TC, BC }, 0xff04cf},
/* 16 */ { 17, 15, { TL, MR, ML }, 0xff04cf},
/* 17 */ { 5, 16, { TC, BC, BL }, 0xff04cf},
/* 18 */ { 6, 6, { TC, BC, 2 * B_COLS }, 0x7604ff} /* sticks out */
};
 
/*
85,14 → 85,14
* Return true iff the given shape fits in the given position,
* taking the current board into account.
*/
int
fits_in(const struct shape *shape, int pos)
int fits_in(const struct shape *shape, int pos)
{
int *o = shape->off;
 
if (board[pos] || board[pos + *o++] || board[pos + *o++] ||
board[pos + *o])
if ((board[pos]) || (board[pos + *o++]) || (board[pos + *o++]) ||
(board[pos + *o]))
return 0;
return 1;
}
 
100,17 → 100,15
* Write the given shape into the current board, turning it on
* if `onoff' is 1, and off if `onoff' is 0.
*/
void
place(const struct shape *shape, int pos, int onoff)
void place(const struct shape *shape, int pos, int onoff)
{
int *o = shape->off;
 
board[pos] = onoff;
board[pos + *o++] = onoff;
board[pos + *o++] = onoff;
board[pos + *o] = onoff;
board[pos] = onoff ? shape->color : 0x000000;
board[pos + *o++] = onoff ? shape->color : 0x000000;
board[pos + *o++] = onoff ? shape->color : 0x000000;
board[pos + *o] = onoff ? shape->color : 0x000000;
}
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/input.h
36,15 → 36,14
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
 
int rwait(struct timeval *);
int tgetchar(void);
void tsleep(void);
extern int rwait(struct timeval *);
extern int tgetchar(void);
extern void tsleep(void);
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/screen.h
36,16 → 36,17
*/
 
/** @addtogroup tetris
* @{
* @{
*/
/** @file
*/
 
/*
* putpad() is for padded strings with count=1.
* putpad() is for padded strings with count = 1.
*/
#define putpad(s) tputs(s, 1, put)
#define putpad(s) tputs(s, 1, put)
 
#include <sys/types.h>
#include <async.h>
 
typedef struct {
55,17 → 56,17
 
extern winsize_t winsize;
 
void moveto(int r, int c);
void clear_screen(void);
extern void moveto(int r, int c);
extern void clear_screen(void);
 
int put(int); /* just calls putchar; for tputs */
void scr_clear(void);
void scr_end(void);
void scr_init(void);
void scr_msg(char *, int);
void scr_set(void);
void scr_update(void);
/* just calls putchar; for tputs */
extern int put(int);
extern void scr_clear(void);
extern void scr_end(void);
extern void scr_init(void);
extern void scr_msg(char *, int);
extern void scr_set(void);
extern void scr_update(void);
 
/** @}
*/
 
/branches/arm/uspace/app/tetris/Makefile
1,5 → 1,6
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
18,7 → 19,7
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o
26,7 → 27,7
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/app/init/version.c
File deleted
/branches/arm/uspace/app/init/version.h
File deleted
/branches/arm/uspace/app/init/init.c
27,9 → 27,9
*/
 
/** @addtogroup init Init
* @brief Init process for testing purposes.
* @brief Init process for user space environment configuration.
* @{
*/
*/
/**
* @file
*/
36,46 → 36,91
 
#include <stdio.h>
#include <unistd.h>
#include <ipc/ipc.h>
#include <vfs/vfs.h>
#include <bool.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <task.h>
#include <malloc.h>
#include <macros.h>
#include <string.h>
#include <devmap.h>
#include "init.h"
#include "version.h"
 
static void console_wait(void)
static void info_print(void)
{
while (get_cons_phone() < 0)
usleep(50000); // FIXME
printf(NAME ": HelenOS init\n");
}
 
static bool mount_fs(const char *fstype)
static bool mount_root(const char *fstype)
{
int rc = -1;
char *opts = "";
const char *root_dev = "initrd";
while (rc < 0) {
rc = mount(fstype, "/", "initrd");
if (str_cmp(fstype, "tmpfs") == 0)
opts = "restore";
int rc = mount(fstype, "/", root_dev, opts, IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
printf(NAME ": Root filesystem mounted, %s at %s\n",
fstype, root_dev);
break;
case EBUSY:
printf(NAME ": Root filesystem already mounted\n");
return false;
case ELIMIT:
printf(NAME ": Unable to mount root filesystem\n");
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (%s)\n", fstype);
return false;
default:
printf(NAME ": Error mounting root filesystem (%d)\n", rc);
return false;
}
return true;
}
 
switch (rc) {
case EOK:
printf(NAME ": Root filesystem mounted\n");
break;
case EBUSY:
printf(NAME ": Root filesystem already mounted\n");
break;
case ELIMIT:
printf(NAME ": Unable to mount root filesystem\n");
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (%s)\n", fstype);
return false;
default:
sleep(5); // FIXME
}
static bool mount_devfs(void)
{
char null[MAX_DEVICE_NAME];
int null_id = devmap_null_create();
if (null_id == -1) {
printf(NAME ": Unable to create null device\n");
return false;
}
snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
int rc = mount("devfs", "/dev", null, "", IPC_FLAG_BLOCKING);
switch (rc) {
case EOK:
printf(NAME ": Device filesystem mounted\n");
break;
case EBUSY:
printf(NAME ": Device filesystem already mounted\n");
devmap_null_destroy(null_id);
return false;
case ELIMIT:
printf(NAME ": Unable to mount device filesystem\n");
devmap_null_destroy(null_id);
return false;
case ENOENT:
printf(NAME ": Unknown filesystem type (devfs)\n");
devmap_null_destroy(null_id);
return false;
default:
printf(NAME ": Error mounting device filesystem (%d)\n", rc);
devmap_null_destroy(null_id);
return false;
}
return true;
}
 
82,37 → 127,132
static void spawn(char *fname)
{
char *argv[2];
 
struct stat s;
if (stat(fname, &s) == ENOENT)
return;
printf(NAME ": Spawning %s\n", fname);
argv[0] = fname;
argv[1] = NULL;
if (!task_spawn(fname, argv))
printf(NAME ": Error spawning %s\n", fname);
}
 
static void srv_start(char *fname)
{
char *argv[2];
task_id_t id;
task_exit_t texit;
int rc, retval;
struct stat s;
if (stat(fname, &s) == ENOENT)
return;
printf(NAME ": Starting %s\n", fname);
argv[0] = fname;
argv[1] = NULL;
id = task_spawn(fname, argv);
if (!id) {
printf(NAME ": Error spawning %s\n", fname);
return;
}
 
if (task_spawn(fname, argv) != 0) {
/* Success */
sleep(1);
rc = task_wait(id, &texit, &retval);
if (rc != EOK) {
printf(NAME ": Error waiting for %s\n", fname);
return;
}
 
if (texit != TASK_EXIT_NORMAL || retval != 0) {
printf(NAME ": Server %s failed to start (returned %d)\n",
fname, retval);
}
}
 
static void getvc(char *dev, char *app)
{
char *argv[4];
char vc[MAX_DEVICE_NAME];
int rc;
snprintf(vc, MAX_DEVICE_NAME, "/dev/%s", dev);
printf(NAME ": Spawning getvc on %s\n", vc);
dev_handle_t handle;
rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
if (rc == EOK) {
argv[0] = "/app/getvc";
argv[1] = vc;
argv[2] = app;
argv[3] = NULL;
if (!task_spawn("/app/getvc", argv))
printf(NAME ": Error spawning getvc on %s\n", vc);
} else {
printf(NAME ": Error waiting on %s\n", vc);
}
}
 
void mount_data(void)
{
int rc;
 
printf("Trying to mount disk0 on /data... ");
fflush(stdout);
 
rc = mount("fat", "/data", "disk0", "wtcache", 0);
if (rc == EOK)
printf("OK\n");
else
printf("Failed\n");
}
 
int main(int argc, char *argv[])
{
info_print();
sleep(5); // FIXME
if (!mount_fs("tmpfs") && !mount_fs("fat")) {
if (!mount_root(STRING(RDFMT))) {
printf(NAME ": Exiting\n");
return -1;
}
// FIXME: spawn("/srv/pci");
spawn("/srv/devfs");
if (!mount_devfs()) {
printf(NAME ": Exiting\n");
return -2;
}
spawn("/srv/fb");
spawn("/srv/kbd");
spawn("/srv/console");
spawn("/srv/fhc");
spawn("/srv/obio");
 
/*
* Start these synchronously so that mount_data() can be
* non-blocking.
*/
srv_start("/srv/ata_bd");
srv_start("/srv/gxe_bd");
console_wait();
version_print();
mount_data();
spawn("/app/bdsh");
getvc("vc0", "/app/bdsh");
getvc("vc1", "/app/bdsh");
getvc("vc2", "/app/bdsh");
getvc("vc3", "/app/bdsh");
getvc("vc4", "/app/bdsh");
getvc("vc5", "/app/bdsh");
getvc("vc6", "/app/klog");
return 0;
}
/branches/arm/uspace/app/init/init.h
28,7 → 28,7
 
/** @addtogroup init
* @{
*/
*/
/**
* @file
*/
36,10 → 36,11
#ifndef __INIT_H__
#define __INIT_H__
 
#define NAME "init"
#define NAME "init"
 
#define MAX_DEVICE_NAME 32
 
#endif
 
/** @}
*/
 
/branches/arm/uspace/app/init/Makefile
26,36 → 26,22
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
include ../../../version
include ../../Makefile.config
 
## Setup toolchain
#
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../srv/kbd/include
 
LIBS = $(LIBC_PREFIX)/libc.a
DEFS += -DRELEASE=\"$(RELEASE)\"
 
ifdef REVISION
DEFS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
## Sources
#
 
OUTPUT = init
SOURCES = \
init.c \
version.c
init.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
66,18 → 52,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/app/bdsh/exec.c
71,7 → 71,7
char *path_tok;
char *path[PATH_MAX];
int n = 0, i = 0;
size_t x = strlen(cmd) + 2;
size_t x = str_size(cmd) + 2;
 
found = (char *)malloc(PATH_MAX);
 
80,18 → 80,18
return (char *) cmd;
}
 
path_tok = cli_strdup(PATH);
path_tok = str_dup(PATH);
 
/* Extract the PATH env to a path[] array */
path[n] = cli_strtok(path_tok, PATH_DELIM);
path[n] = strtok(path_tok, PATH_DELIM);
while (NULL != path[n]) {
if ((strlen(path[n]) + x ) > PATH_MAX) {
if ((str_size(path[n]) + x ) > PATH_MAX) {
cli_error(CL_ENOTSUP,
"Segment %d of path is too large, search ends at segment %d",
n, n-1);
break;
}
path[++n] = cli_strtok(NULL, PATH_DELIM);
path[++n] = strtok(NULL, PATH_DELIM);
}
 
/* We now have n places to look for the command */
112,18 → 112,27
unsigned int try_exec(char *cmd, char **argv)
{
task_id_t tid;
task_exit_t texit;
char *tmp;
int retval;
 
tmp = cli_strdup(find_command(cmd));
tmp = str_dup(find_command(cmd));
free(found);
 
tid = task_spawn((const char *)tmp, (const char **)argv);
tid = task_spawn((const char *)tmp, argv);
free(tmp);
 
if (tid == 0) {
cli_error(CL_EEXEC, "Can not spawn %s", cmd);
cli_error(CL_EEXEC, "Cannot spawn `%s'.", cmd);
return 1;
} else {
return 0;
}
task_wait(tid, &texit, &retval);
if (texit != TASK_EXIT_NORMAL) {
printf("Command failed (unexpectedly terminated).\n");
} else if (retval != 0) {
printf("Command failed (return value %d).\n", retval);
}
 
return 0;
}
/branches/arm/uspace/app/bdsh/cmds/modules/quit/quit.c
File deleted
/branches/arm/uspace/app/bdsh/cmds/modules/quit/quit_def.h
File deleted
/branches/arm/uspace/app/bdsh/cmds/modules/quit/entry.h
File deleted
/branches/arm/uspace/app/bdsh/cmds/modules/quit/quit.h
File deleted
/branches/arm/uspace/app/bdsh/cmds/modules/ls/ls.c
50,30 → 50,9
 
static char *cmdname = "ls";
 
static unsigned int ls_scope(const char *path)
{
int fd;
DIR *dirp;
 
dirp = opendir(path);
if (dirp) {
closedir(dirp);
return LS_DIR;
}
 
fd = open(path, O_RDONLY);
if (fd > 0) {
close(fd);
return LS_FILE;
}
 
return LS_BOGUS;
}
 
static void ls_scan_dir(const char *d, DIR *dirp)
{
struct dirent *dp;
unsigned int scope;
char *buff;
 
if (! dirp)
90,20 → 69,7
/* Don't worry if inserting a double slash, this will be fixed by
* absolutize() later with subsequent calls to open() or readdir() */
snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);
scope = ls_scope(buff);
switch (scope) {
case LS_DIR:
ls_print_dir(dp->d_name);
break;
case LS_FILE:
ls_print_file(dp->d_name);
break;
case LS_BOGUS:
/* Odd chance it was deleted from the time readdir() found
* it and the time that it was scoped */
printf("ls: skipping bogus node %s\n", dp->d_name);
break;
}
ls_print(dp->d_name, buff);
}
 
free(buff);
111,7 → 77,7
return;
}
 
/* ls_print_* currently does nothing more than print the entry.
/* ls_print currently does nothing more than print the entry.
* in the future, we will likely pass the absolute path, and
* some sort of ls_options structure that controls how each
* entry is printed and what is printed about it.
118,17 → 84,23
*
* Now we just print basic DOS style lists */
 
static void ls_print_dir(const char *d)
static void ls_print(const char *name, const char *pathname)
{
printf("%-40s\t<DIR>\n", d);
struct stat s;
int rc;
 
return;
}
if (rc = stat(pathname, &s)) {
/* Odd chance it was deleted from the time readdir() found it */
printf("ls: skipping bogus node %s\n", pathname);
printf("rc=%d\n", rc);
return;
}
if (s.is_file)
printf("%-40s\t%llu\n", name, (long long) s.size);
else
printf("%-40s\n", name);
 
static void ls_print_file(const char *f)
{
printf("%-40s\n", f);
 
return;
}
 
148,7 → 120,7
int cmd_ls(char **argv)
{
unsigned int argc;
unsigned int scope;
struct stat s;
char *buff;
DIR *dirp;
 
164,21 → 136,19
if (argc == 1)
getcwd(buff, PATH_MAX);
else
strncpy(buff, argv[1], PATH_MAX);
str_cpy(buff, PATH_MAX, argv[1]);
 
scope = ls_scope(buff);
 
switch (scope) {
case LS_BOGUS:
if (stat(buff, &s)) {
cli_error(CL_ENOENT, buff);
free(buff);
return CMD_FAILURE;
case LS_FILE:
ls_print_file(buff);
break;
case LS_DIR:
}
 
if (s.is_file) {
ls_print(buff, buff);
} else {
dirp = opendir(buff);
if (! dirp) {
if (!dirp) {
/* May have been deleted between scoping it and opening it */
cli_error(CL_EFAIL, "Could not stat %s", buff);
free(buff);
186,7 → 156,6
}
ls_scan_dir(buff, dirp);
closedir(dirp);
break;
}
 
free(buff);
/branches/arm/uspace/app/bdsh/cmds/modules/ls/ls.h
9,8 → 9,7
 
static unsigned int ls_scope(const char *);
static void ls_scan_dir(const char *, DIR *);
static void ls_print_dir(const char *);
static void ls_print_file(const char *);
static void ls_print(const char *, const char *);
 
#endif /* LS_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/ls/ls_def.h
3,14 → 3,4
"List files and directories",
&cmd_ls,
&help_cmd_ls,
0
},
 
{
"dir",
NULL,
&cmd_ls,
&help_cmd_ls,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/bdd/bdd.c
0,0 → 1,154
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "util.h"
#include "errors.h"
#include "entry.h"
#include "bdd.h"
#include "cmds.h"
 
#include <libblock.h>
#include <devmap.h>
#include <errno.h>
 
#define BLOCK_SIZE 512
#define BPR 16
 
static const char *cmdname = "bdd";
 
/* Dispays help for bdd in various levels */
void help_cmd_bdd(unsigned int level)
{
static char helpfmt[] =
"Usage: %s <device> [<block_number> [<bytes>]]\n";
if (level == HELP_SHORT) {
printf("'%s' dump block device contents.\n", cmdname);
} else {
help_cmd_bdd(HELP_SHORT);
printf(helpfmt, cmdname);
}
return;
}
 
/* Main entry point for bdd, accepts an array of arguments */
int cmd_bdd(char **argv)
{
unsigned int argc;
unsigned int i, j;
dev_handle_t handle;
block_t *block;
uint8_t *blk;
size_t size, bytes, rows;
int rc;
bn_t boff;
uint8_t b;
 
/* Count the arguments */
for (argc = 0; argv[argc] != NULL; argc ++);
 
if (argc < 2 || argc > 4) {
printf("%s - incorrect number of arguments.\n", cmdname);
return CMD_FAILURE;
}
 
if (argc >= 3)
boff = strtol(argv[2], NULL, 0);
else
boff = 0;
 
if (argc >= 4)
size = strtol(argv[3], NULL, 0);
else
size = 256;
 
rc = devmap_device_get_handle(argv[1], &handle, 0);
if (rc != EOK) {
printf("Error: could not resolve device `%s'.\n", argv[1]);
return CMD_FAILURE;
}
 
rc = block_init(handle, BLOCK_SIZE);
if (rc != EOK) {
printf("Error: could not init libblock.\n");
return CMD_FAILURE;
}
 
rc = block_cache_init(handle, BLOCK_SIZE, 2, CACHE_MODE_WB);
if (rc != EOK) {
printf("Error: could not init block cache.\n");
return CMD_FAILURE;
}
 
while (size > 0) {
block = block_get(handle, boff, 0);
blk = (uint8_t *) block->data;
 
bytes = (size < BLOCK_SIZE) ? size : BLOCK_SIZE;
rows = (bytes + BPR - 1) / BPR;
 
for (j = 0; j < rows; j++) {
for (i = 0; i < BPR; i++) {
if (j * BPR + i < bytes)
printf("%02x ", blk[j * BPR + i]);
else
printf(" ");
}
putchar('\t');
 
for (i = 0; i < BPR; i++) {
if (j * BPR + i < bytes) {
b = blk[j * BPR + i];
if (b >= 32 && b < 127)
putchar(b);
else
putchar(' ');
} else {
putchar(' ');
}
}
putchar('\n');
}
 
block_put(block);
 
if (size > rows * BPR)
size -= rows * BPR;
else
size = 0;
 
boff += rows * BPR;
}
 
block_fini(handle);
 
return CMD_SUCCESS;
}
/branches/arm/uspace/app/bdsh/cmds/modules/bdd/bdd.h
0,0 → 1,8
#ifndef BDD_H
#define BDD_H
 
/* Prototypes for the bdd command, excluding entry points */
 
 
#endif /* BDD_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/bdd/entry.h
0,0 → 1,9
#ifndef BDD_ENTRY_H
#define BDD_ENTRY_H
 
/* Entry points for the bdd command */
extern int cmd_bdd(char **);
extern void help_cmd_bdd(unsigned int);
 
#endif /* BDD_ENTRY_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/bdd/bdd_def.h
0,0 → 1,7
{
"bdd",
"Dump block device contents",
&cmd_bdd,
&help_cmd_bdd,
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/kcon/kcon.c
0,0 → 1,73
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <stdio.h>
#include <stdlib.h>
#include <io/console.h>
#include <vfs/vfs.h>
#include "config.h"
#include "util.h"
#include "errors.h"
#include "entry.h"
#include "kcon.h"
#include "cmds.h"
 
static char *cmdname = "kcon";
 
/* Dispays help for kcon in various levels */
void help_cmd_kcon(unsigned int level)
{
printf("`kcon' switches to the kernel debug console.\n");
 
if (level != HELP_SHORT) {
printf("Usage: %s\n", cmdname);
}
 
return;
}
 
/* Main entry point for kcon, accepts an array of arguments */
int cmd_kcon(char **argv)
{
unsigned int argc;
 
argc = cli_count_args(argv);
 
if (argc != 1) {
printf("%s - incorrect number of arguments. Try `%s --help'\n",
cmdname, cmdname);
return CMD_FAILURE;
}
 
console_kcon_enable(fphone(stdout));
 
return CMD_SUCCESS;
}
 
/branches/arm/uspace/app/bdsh/cmds/modules/kcon/kcon.h
0,0 → 1,8
#ifndef KCON_H
#define KCON_H
 
/* Prototypes for the kcon command, excluding entry points */
 
 
#endif /* KCON_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/kcon/entry.h
0,0 → 1,9
#ifndef KCON_ENTRY_H
#define KCON_ENTRY_H
 
/* Entry points for the kcon command */
extern int cmd_kcon(char **);
extern void help_cmd_kcon(unsigned int);
 
#endif /* KCON_ENTRY_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/kcon/kcon_def.h
0,0 → 1,7
{
"kcon",
"Switch to kernel console",
&cmd_kcon,
&help_cmd_kcon,
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/pwd/pwd.c
30,6 → 30,7
 
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
 
#include "config.h"
#include "errors.h"
/branches/arm/uspace/app/bdsh/cmds/modules/pwd/pwd_def.h
3,5 → 3,4
"Prints the current working directory",
&cmd_pwd,
&help_cmd_pwd,
-1
},
/branches/arm/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
37,6 → 37,7
#include <sys/stat.h>
#include <getopt.h>
#include <stdarg.h>
#include <string.h>
 
#include "config.h"
#include "errors.h"
93,7 → 94,7
 
/* Its a good idea to allocate path, plus we (may) need a copy of
* path to tokenize if parents are specified */
if (NULL == (tmp = cli_strdup(path))) {
if (NULL == (tmp = str_dup(path))) {
cli_error(CL_ENOMEM, "%s: path too big?", cmdname);
return 1;
}
128,9 → 129,9
absolute = 1;
 
/* TODO: Canonify the path prior to tokenizing it, see below */
dirs[i] = cli_strtok(tmp, "/");
dirs[i] = strtok(tmp, "/");
while (dirs[i] && i < 255)
dirs[++i] = cli_strtok(NULL, "/");
dirs[++i] = strtok(NULL, "/");
 
if (NULL == dirs[0])
return 1;
149,7 → 150,7
while (dirs[i] != NULL) {
/* Sometimes make or scripts conjoin odd paths. Account for something
* like this: ../../foo/bar/../foo/foofoo/./bar */
if (!strcmp(dirs[i], "..") || !strcmp(dirs[i], ".")) {
if (!str_cmp(dirs[i], "..") || !str_cmp(dirs[i], ".")) {
if (0 != (chdir(dirs[i]))) {
cli_error(CL_EFAIL, "%s: impossible path: %s",
cmdname, path);
/branches/arm/uspace/app/bdsh/cmds/modules/mkdir/mkdir_def.h
3,14 → 3,6
"Create new directories",
&cmd_mkdir,
&help_cmd_mkdir,
0
},
 
{
"md",
NULL,
&cmd_mkdir,
&help_cmd_mkdir,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/rm/rm.c
33,8 → 33,9
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <assert.h>
#include <getopt.h>
#include <mem.h>
#include <string.h>
 
#include "config.h"
#include "errors.h"
217,9 → 218,13
 
i = optind;
while (NULL != argv[i]) {
len = strlen(argv[i]) + 2;
len = str_size(argv[i]) + 2;
buff = (char *) realloc(buff, len);
assert(buff != NULL);
if (buff == NULL) {
printf("rm: out of memory\n");
ret = 1;
break;
}
memset(buff, 0, sizeof(buff));
snprintf(buff, len, argv[i]);
 
/branches/arm/uspace/app/bdsh/cmds/modules/rm/rm_def.h
3,14 → 3,5
"Remove files and directories",
&cmd_rm,
&help_cmd_rm,
0
},
 
{
"del",
NULL,
&cmd_rm,
&help_cmd_rm,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/modules.h
18,9 → 18,9
/* Prototypes for each module's entry (help/exec) points */
 
#include "help/entry.h"
#include "quit/entry.h"
#include "mkdir/entry.h"
#include "rm/entry.h"
#include "bdd/entry.h"
#include "cat/entry.h"
#include "touch/entry.h"
#include "ls/entry.h"
27,6 → 27,9
#include "pwd/entry.h"
#include "sleep/entry.h"
#include "cp/entry.h"
#include "mv/entry.h"
#include "mount/entry.h"
#include "kcon/entry.h"
 
/* Each .def function fills the module_t struct with the individual name, entry
* point, help entry point, etc. You can use config.h to control what modules
34,9 → 37,9
 
module_t modules[] = {
#include "help/help_def.h"
#include "quit/quit_def.h"
#include "mkdir/mkdir_def.h"
#include "rm/rm_def.h"
#include "bdd/bdd_def.h"
#include "cat/cat_def.h"
#include "touch/touch_def.h"
#include "ls/ls_def.h"
43,6 → 46,10
#include "pwd/pwd_def.h"
#include "sleep/sleep_def.h"
#include "cp/cp_def.h"
#include "mv/mv_def.h"
#include "mount/mount_def.h"
#include "kcon/kcon_def.h"
 
{NULL, NULL, NULL, NULL}
};
 
/branches/arm/uspace/app/bdsh/cmds/modules/mount/mount.c
0,0 → 1,82
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <vfs/vfs.h>
#include <errno.h>
#include "config.h"
#include "util.h"
#include "errors.h"
#include "entry.h"
#include "mount.h"
#include "cmds.h"
 
static const char *cmdname = "mount";
 
/* Dispays help for mount in various levels */
void help_cmd_mount(unsigned int level)
{
static char helpfmt[] =
"Usage: %s <fstype> <mp> <dev> [<moptions>]\n";
if (level == HELP_SHORT) {
printf("'%s' mounts a file system.\n", cmdname);
} else {
help_cmd_mount(HELP_SHORT);
printf(helpfmt, cmdname);
}
return;
}
 
/* Main entry point for mount, accepts an array of arguments */
int cmd_mount(char **argv)
{
unsigned int argc;
char *mopts = "";
int rc;
 
argc = cli_count_args(argv);
 
if ((argc < 4) || (argc > 5)) {
printf("%s: invalid number of arguments.\n",
cmdname);
return CMD_FAILURE;
}
if (argc == 5)
mopts = argv[4];
 
rc = mount(argv[1], argv[2], argv[3], mopts, 0);
if (rc != EOK) {
printf("Unable to mount %s filesystem to %s on %s (rc=%d)\n",
argv[1], argv[2], argv[3], rc);
return CMD_FAILURE;
}
 
return CMD_SUCCESS;
}
 
/branches/arm/uspace/app/bdsh/cmds/modules/mount/mount_def.h
0,0 → 1,7
{
"mount",
"The mount command",
&cmd_mount,
&help_cmd_mount,
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/mount/entry.h
0,0 → 1,9
#ifndef MOUNT_ENTRY_H
#define MOUNT_ENTRY_H
 
/* Entry points for the mount command */
extern int cmd_mount(char **);
extern void help_cmd_mount(unsigned int);
 
#endif /* MOUNT_ENTRY_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/mount/mount.h
0,0 → 1,8
#ifndef MOUNT_H
#define MOUNT_H
 
/* Prototypes for the mount command, excluding entry points */
 
 
#endif /* MOUNT_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/mv/mv.c
0,0 → 1,70
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "config.h"
#include "util.h"
#include "errors.h"
#include "entry.h"
#include "mv.h"
#include "cmds.h"
 
static const char *cmdname = "mv";
 
/* Dispays help for mv in various levels */
void help_cmd_mv(unsigned int level)
{
printf("'%s' renames files\n", cmdname);
return;
}
 
/* Main entry point for mv, accepts an array of arguments */
int cmd_mv(char **argv)
{
unsigned int argc;
int rc;
 
argc = cli_count_args(argv);
if (argc != 3) {
printf("%s: invalid number of arguments.\n",
cmdname);
return CMD_FAILURE;
}
 
rc = rename(argv[1], argv[2]);
if (rc != EOK) {
printf("Unable to rename %s to %s (rc=%d)\n",
argv[1], argv[2], rc);
return CMD_FAILURE;
}
 
return CMD_SUCCESS;
}
 
/branches/arm/uspace/app/bdsh/cmds/modules/mv/mv_def.h
0,0 → 1,14
{
"mv",
"The mv command",
&cmd_mv,
&help_cmd_mv,
},
 
{
"ren",
NULL,
&cmd_mv,
&help_cmd_mv,
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/mv/entry.h
0,0 → 1,9
#ifndef MV_ENTRY_H
#define MV_ENTRY_H
 
/* Entry points for the mv command */
extern int cmd_mv(char **);
extern void help_cmd_mv(unsigned int);
 
#endif /* MV_ENTRY_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/mv/mv.h
0,0 → 1,8
#ifndef MV_H
#define MV_H
 
/* Prototypes for the mv command, excluding entry points */
 
 
#endif /* MV_H */
 
/branches/arm/uspace/app/bdsh/cmds/modules/module_aliases.h
12,10 → 12,7
* the entry point being reached. */
 
char *mod_aliases[] = {
"exit", "quit",
"md", "mkdir",
"del", "rm",
"dir", "ls",
"ren", "mv",
NULL, NULL
};
 
/branches/arm/uspace/app/bdsh/cmds/modules/cat/cat.c
87,7 → 87,8
off_t total = 0;
char *buff = NULL;
 
if (-1 == (fd = open(fname, O_RDONLY))) {
fd = open(fname, O_RDONLY);
if (fd < 0) {
printf("Unable to open %s\n", fname);
return 1;
}
103,13 → 104,11
}
 
do {
memset(buff, 0, sizeof(buff));
bytes = read(fd, buff, blen);
if (bytes > 0) {
count += bytes;
if (bytes < blen)
buff[bytes] = '\0';
printf(buff);
buff[bytes] = '\0';
printf("%s", buff);
reads++;
}
} while (bytes > 0);
/branches/arm/uspace/app/bdsh/cmds/modules/cat/cat_def.h
3,6 → 3,5
"Show the contents of a file",
&cmd_cat,
&help_cmd_cat,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/touch/touch.c
37,6 → 37,7
#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h>
#include <string.h>
 
#include "config.h"
#include "errors.h"
79,7 → 80,7
}
 
for (i = 1; i < argc; i ++) {
buff = cli_strdup(argv[i]);
buff = str_dup(argv[i]);
dirp = opendir(buff);
if (dirp) {
cli_error(CL_ENOTSUP, "%s is a directory", buff);
/branches/arm/uspace/app/bdsh/cmds/modules/touch/touch_def.h
3,6 → 3,5
"Create files or update access times",
&cmd_touch,
&help_cmd_touch,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/help/help.c
107,7 → 107,7
}
 
if (argc == 3) {
if (!strcmp("extended", argv[2]))
if (!str_cmp("extended", argv[2]))
level = HELP_LONG;
else
level = HELP_SHORT;
133,13 → 133,11
 
/* First, show a list of built in commands that are available in this mode */
for (cmd = builtins; cmd->name != NULL; cmd++, i++) {
if (!builtin_is_restricted(i)) {
if (is_builtin_alias(cmd->name))
printf(" %-16s\tAlias for `%s'\n", cmd->name,
alias_for_builtin(cmd->name));
else
printf(" %-16s\t%s\n", cmd->name, cmd->desc);
}
}
 
i = 0;
146,13 → 144,11
 
/* Now, show a list of module commands that are available in this mode */
for (mod = modules; mod->name != NULL; mod++, i++) {
if (!module_is_restricted(i)) {
if (is_module_alias(mod->name))
printf(" %-16s\tAlias for `%s'\n", mod->name,
alias_for_module(mod->name));
else
printf(" %-16s\t%s\n", mod->name, mod->desc);
}
}
 
printf("\n Try %s %s for more information on how `%s' works.\n\n",
/branches/arm/uspace/app/bdsh/cmds/modules/help/help_def.h
3,5 → 3,4
"Show help for commands",
&cmd_help,
&help_cmd_help,
0
},
/branches/arm/uspace/app/bdsh/cmds/modules/cp/cp.c
30,6 → 30,10
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <fcntl.h>
#include "config.h"
#include "util.h"
#include "errors.h"
37,37 → 41,191
#include "cp.h"
#include "cmds.h"
 
static char *cmdname = "cp";
#define CP_VERSION "0.0.1"
#define CP_DEFAULT_BUFLEN 1024
 
/* Dispays help for cp in various levels */
static const char *cmdname = "cp";
 
static struct option const long_options[] = {
{ "buffer", required_argument, 0, 'b' },
{ "force", no_argument, 0, 'f' },
{ "recursive", no_argument, 0, 'r' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
{ "verbose", no_argument, 0, 'V' },
{ 0, 0, 0, 0 }
};
 
static int strtoint(const char *s1)
{
long t1;
 
if (-1 == (t1 = strtol(s1, (char **) NULL, 10)))
return -1;
 
if (t1 <= 0)
return -1;
 
return (int) t1;
}
 
static int64_t copy_file(const char *src, const char *dest,
size_t blen, int vb)
{
int fd1, fd2, bytes = 0;
off_t total = 0;
int64_t copied = 0;
char *buff = NULL;
 
if (vb)
printf("Copying %s to %s\n", src, dest);
 
if (-1 == (fd1 = open(src, O_RDONLY))) {
printf("Unable to open source file %s\n", src);
return -1;
}
 
if (-1 == (fd2 = open(dest, O_CREAT))) {
printf("Unable to open destination file %s\n", dest);
close(fd1);
return -1;
}
 
total = lseek(fd1, 0, SEEK_END);
 
if (vb)
printf("%d bytes to copy\n", total);
 
lseek(fd1, 0, SEEK_SET);
 
if (NULL == (buff = (char *) malloc(blen))) {
printf("Unable to allocate enough memory to read %s\n",
src);
copied = -1;
goto out;
}
 
for (;;) {
ssize_t res;
 
bytes = read(fd1, buff, blen);
if (bytes <= 0)
break;
copied += bytes;
res = bytes;
do {
/*
* Theoretically, it may not be enough to call write()
* only once. Also the previous read() may have
* returned less data than requested.
*/
bytes = write(fd2, buff, res);
if (bytes < 0)
goto err;
res -= bytes;
} while (res > 0);
 
/* TODO: re-insert assert() once this is stand alone,
* removed as abort() exits the entire shell
*/
if (res != 0) {
printf("\n%d more bytes than actually exist were copied\n", res);
goto err;
}
}
 
if (bytes < 0) {
err:
printf("\nError copying %s, (%d)\n", src, bytes);
copied = bytes;
}
 
out:
close(fd1);
close(fd2);
if (buff)
free(buff);
return copied;
}
 
void help_cmd_cp(unsigned int level)
{
printf("This is the %s help for '%s'.\n",
level ? EXT_HELP : SHORT_HELP, cmdname);
static char helpfmt[] =
"Usage: %s [options] <source> <dest>\n"
"Options: (* indicates not yet implemented)\n"
" -h, --help A short option summary\n"
" -v, --version Print version information and exit\n"
"* -V, --verbose Be annoyingly noisy about what's being done\n"
"* -f, --force Do not complain when <dest> exists\n"
"* -r, --recursive Copy entire directories\n"
" -b, --buffer ## Set the read buffer size to ##\n"
"Currently, %s is under development, some options may not work.\n";
if (level == HELP_SHORT) {
printf("`%s' copies files and directories\n", cmdname);
} else {
help_cmd_cp(HELP_SHORT);
printf(helpfmt, cmdname, cmdname);
}
 
return;
}
 
/* Main entry point for cp, accepts an array of arguments */
int cmd_cp(char **argv)
{
unsigned int argc;
unsigned int i;
unsigned int argc, buffer = 0, verbose = 0;
int c, opt_ind;
int64_t ret;
 
/* Count the arguments */
for (argc = 0; argv[argc] != NULL; argc ++);
argc = cli_count_args(argv);
 
printf("%s %s\n", TEST_ANNOUNCE, cmdname);
printf("%d arguments passed to %s", argc - 1, cmdname);
for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
c = getopt_long(argc, argv, "hvVfrb:", long_options, &opt_ind);
switch (c) {
case 'h':
help_cmd_cp(1);
return CMD_SUCCESS;
case 'v':
printf("%d\n", CP_VERSION);
return CMD_SUCCESS;
case 'V':
verbose = 1;
break;
case 'f':
break;
case 'r':
break;
case 'b':
if (-1 == (buffer = strtoint(optarg))) {
printf("%s: Invalid buffer specification, "
"(should be a number greater than zero)\n",
cmdname);
return CMD_FAILURE;
}
if (verbose)
printf("Buffer = %d\n", buffer);
break;
}
}
 
if (argc < 2) {
printf("\n");
return CMD_SUCCESS;
if (buffer == 0)
buffer = CP_DEFAULT_BUFLEN;
 
argc -= optind;
 
if (argc != 2) {
printf("%s: invalid number of arguments. Try %s --help\n",
cmdname, cmdname);
return CMD_FAILURE;
}
 
printf(":\n");
for (i = 1; i < argc; i++)
printf("[%d] -> %s\n", i, argv[i]);
ret = copy_file(argv[optind], argv[optind + 1], buffer, verbose);
 
return CMD_SUCCESS;
if (verbose)
printf("%d bytes copied\n", ret);
 
if (ret >= 0)
return CMD_SUCCESS;
else
return CMD_FAILURE;
}
 
/branches/arm/uspace/app/bdsh/cmds/modules/cp/cp_def.h
3,6 → 3,5
"Copy files and directories",
&cmd_cp,
&help_cmd_cp,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/modules/sleep/sleep_def.h
3,6 → 3,5
"Pause for given time interval (in seconds)",
&cmd_sleep,
&help_cmd_sleep,
0
},
 
/branches/arm/uspace/app/bdsh/cmds/mod_cmds.c
53,26 → 53,6
 
extern volatile unsigned int cli_interactive;
 
int module_is_restricted(int pos)
{
/* Restriction Levels:
* -1 -> Available only in interactive mode
* 0 -> Available in any mode
* 1 -> Available only in non-interactive mode */
 
module_t *mod = modules;
mod += pos;
/* We're interactive, and the module is OK to run */
if (cli_interactive && mod->restricted <= 0)
return 0;
/* We're not interactive, and the module is OK to run */
if (!cli_interactive && mod->restricted >= 0)
return 0;
 
/* Anything else is just a big fat no :) */
return 1;
}
 
/* Checks if an entry function matching command exists in modules[], if so
* its position in the array is returned */
int is_module(const char *command)
84,7 → 64,7
return -2;
 
for (mod = modules; mod->name != NULL; mod++, i++) {
if (!strcmp(mod->name, command))
if (!str_cmp(mod->name, command))
return i;
}
 
101,7 → 81,7
return -1;
 
for(i=0; mod_aliases[i] != NULL; i+=2) {
if (!strcmp(mod_aliases[i], command))
if (!str_cmp(mod_aliases[i], command))
return 1;
}
 
117,7 → 97,7
return (char *)NULL;
 
for(i=0; mod_aliases[i] != NULL; i++) {
if (!strcmp(mod_aliases[i], command))
if (!str_cmp(mod_aliases[i], command))
return (char *)mod_aliases[++i];
i++;
}
/branches/arm/uspace/app/bdsh/cmds/builtin_cmds.c
40,19 → 40,6
 
extern volatile unsigned int cli_interactive;
 
int builtin_is_restricted(int pos)
{
builtin_t *cmd = builtins;
cmd += pos;
 
if (cli_interactive && cmd->restricted <= 0)
return 0;
if (!cli_interactive && cmd->restricted >= 0)
return 0;
 
return 1;
}
 
int is_builtin(const char *command)
{
builtin_t *cmd;
62,7 → 49,7
return -2;
 
for (cmd = builtins; cmd->name != NULL; cmd++, i++) {
if (!strcmp(cmd->name, command))
if (!str_cmp(cmd->name, command))
return i;
}
 
77,7 → 64,7
return -1;
 
for(i=0; builtin_aliases[i] != NULL; i+=2) {
if (!strcmp(builtin_aliases[i], command))
if (!str_cmp(builtin_aliases[i], command))
return 1;
}
 
92,7 → 79,7
return (char *)NULL;
 
for(i=0; builtin_aliases[i] != NULL; i++) {
if (!strcmp(builtin_aliases[i], command))
if (!str_cmp(builtin_aliases[i], command))
return (char *)builtin_aliases[++i];
i++;
}
/branches/arm/uspace/app/bdsh/cmds/builtins/builtins.h
4,9 → 4,11
#include "config.h"
 
#include "cd/entry.h"
#include "exit/entry.h"
 
builtin_t builtins[] = {
#include "cd/cd_def.h"
#include "exit/exit_def.h"
{NULL, NULL, NULL, NULL}
};
 
/branches/arm/uspace/app/bdsh/cmds/builtins/exit/exit.h
0,0 → 1,6
#ifndef EXIT_H
#define EXIT_H
 
/* Prototypes for the quit command (excluding entry points) */
 
#endif
/branches/arm/uspace/app/bdsh/cmds/builtins/exit/entry.h
0,0 → 1,12
#ifndef EXIT_ENTRY_H_
#define EXIT_ENTRY_H_
 
#include "scli.h"
 
/* Entry points for the quit command */
extern void help_cmd_exit(unsigned int);
extern int cmd_exit(char *[], cliuser_t *);
 
#endif
 
 
/branches/arm/uspace/app/bdsh/cmds/builtins/exit/exit.c
0,0 → 1,55
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <stdio.h>
#include <stdlib.h>
#include "entry.h"
#include "exit.h"
#include "cmds.h"
 
static const char *cmdname = "exit";
 
extern volatile unsigned int cli_quit;
extern const char *progname;
 
void help_cmd_exit(unsigned int level)
{
printf("Type `%s' to exit %s\n", cmdname, progname);
return;
}
 
/* Quits the program and returns the status of whatever command
* came before invoking 'quit' */
int cmd_exit(char *argv[], cliuser_t *usr)
{
/* Inform that we're outta here */
cli_quit = 1;
return CMD_SUCCESS;
}
/branches/arm/uspace/app/bdsh/cmds/builtins/exit/exit_def.h
0,0 → 1,6
{
"exit",
"Exit the shell",
&cmd_exit,
&help_cmd_exit,
},
/branches/arm/uspace/app/bdsh/cmds/builtins/cd/cd_def.h
3,12 → 3,4
"Change the current working directory",
&cmd_cd,
&help_cmd_cd,
-1
},
{
"chdir",
NULL,
&cmd_cd,
&help_cmd_cd,
-1
},
/branches/arm/uspace/app/bdsh/cmds/builtins/builtin_aliases.h
4,7 → 4,6
/* See modules/module_aliases.h for an explanation of this file */
 
char *builtin_aliases[] = {
"chdir", "cd",
NULL, NULL
};
 
/branches/arm/uspace/app/bdsh/cmds/mknewcmd
46,8 → 46,6
-e, --entry Entry function of the command (def: cmd_${def})
-h, --help-entry Entry function for command help (def: help_cmd_${def})
-a, --alias Alias (nickname) for this command (def: none)
-r, --restrict Restriction level (interactive, non-interactive, both)
(def: module is both, builtin is interactive only)
-t, --type Type of command (module or builtin) (def: module)
-H, --help This help summary
-V, --version Print $PROGNAME version and exit normally
67,8 → 65,7
$PROGNAME -n foo -d "Foo power" -a bar -r both -t module modules/foo
 
The example would generate a modular command named 'foo', which is also
reached by typing 'bar' and available in either interactive or noninteractive
mode.
reached by typing 'bar'.
 
Skeletal files do *not* depend on the autoconf generated "config.h" unless you
include it. This may or may not be desirable depending on your use.
97,7 → 94,6
"${CMDDESC}",
&${CMDENTRY},
&${HELPENTRY},
${CMDRESTRICT}
},
 
EOF
107,7 → 103,6
NULL,
&${CMDENTRY},
&${HELPENTRY},
${CMDRESTRICT}
},
 
EOF
167,7 → 162,7
#include "${CMDNAME}.h"
#include "cmds.h"
 
static char *cmdname = "${CMDNAME}";
static const char *cmdname = "${CMDNAME}";
 
/* Dispays help for ${CMDNAME} in various levels */
void ${HELPENTRY}(unsigned int level)
234,8 → 229,8
# We need at least one
[ $# = 0 ] && usage && exit 1;
 
TEMP=$(getopt -o n:d:e:h:a:r:t:HV \
--long name:,desc:,entry:,help-entry:,alias:,restrict:,type:,help,version \
TEMP=$(getopt -o n:d:e:h:a:t:HV \
--long name:,desc:,entry:,help-entry:,alias:,type:,help,version \
-- "$@") || {
echo "Try $PROGNAME --help for help"
}
269,11 → 264,6
shift 2
continue
;;
-r | --restrict)
CMDRESTRICT="$2"
shift 2
continue
;;
-t | --type)
CMDTYPE="$2"
shift 2
305,30 → 295,7
[ -n "$CMDTYPE" ] || CMDTYPE="module"
[ -n "$OUTDIR" ] || OUTDIR="${CMDTYPE}s/${CMDNAME}"
 
# Builtins typically only need to be available in interactive mode,
# set the default accordingly.
[ -n "$CMDRESTRICT" ] || {
[ "$CMDTYPE" = "module" ] && CMDRESTRICT="both"
[ "$CMDTYPE" = "builtin" ] && CMDRESTRICT="interactive"
}
 
# Set the restriction level as the structure expects to see it
case "$CMDRESTRICT" in
0 | both)
CMDRESTRICT="0"
;;
1 | non-interactive)
CMDRESTRICT="1"
;;
-1 | interactive)
CMDRESTRICT="-1"
;;
*)
usage
exit 1
;;
esac
 
# Do a little sanity
[ -d $OUTDIR ] && {
echo "$OUTDIR already exists, remove it to proceed."
/branches/arm/uspace/app/bdsh/cmds/cmds.h
36,7 → 36,6
char *desc; /* Description of the command */
mod_entry_t entry; /* Command (exec) entry function */
mod_help_t help; /* Command (help) entry function */
int restricted; /* Restricts to interactive/non-interactive only */
} module_t;
 
/* Builtin structure, same as modules except different types of entry points */
/branches/arm/uspace/app/bdsh/input.c
32,7 → 32,12
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io/stream.h>
#include <io/console.h>
#include <io/keycode.h>
#include <io/style.h>
#include <vfs/vfs.h>
#include <errno.h>
#include <bool.h>
 
#include "config.h"
#include "util.h"
41,21 → 46,8
#include "errors.h"
#include "exec.h"
 
extern volatile unsigned int cli_interactive;
 
/* Not exposed in input.h */
static void cli_restricted(char *);
static void read_line(char *, int);
 
/* More than a macro than anything */
static void cli_restricted(char *cmd)
{
printf("%s is not available in %s mode\n", cmd,
cli_interactive ? "interactive" : "non-interactive");
 
return;
}
 
/* Tokenizes input from console, sees if the first word is a built-in, if so
* invokes the built-in entry point (a[0]) passing all arguments in a[] to
* the handler */
69,14 → 61,11
if (NULL == usr->line)
return CL_EFAIL;
 
tmp = cli_strdup(usr->line);
tmp = str_dup(usr->line);
 
/* Break up what the user typed, space delimited */
 
/* TODO: Protect things in quotes / ticks, expand wildcards */
cmd[n] = cli_strtok(tmp, " ");
cmd[n] = strtok(tmp, " ");
while (cmd[n] && n < WORD_MAX) {
cmd[++n] = cli_strtok(NULL, " ");
cmd[++n] = strtok(NULL, " ");
}
 
/* We have rubbish */
85,39 → 74,19
goto finit;
}
 
/* Its a builtin command */
/* Its a builtin command ? */
if ((i = (is_builtin(cmd[0]))) > -1) {
/* Its not available in this mode, see what try_exec() thinks */
if (builtin_is_restricted(i)) {
rc = try_exec(cmd[0], cmd);
if (rc)
/* No external matching it could be found, tell the
* user that the command does exist, but is not
* available in this mode. */
cli_restricted(cmd[0]);
goto finit;
}
/* Its a builtin, its available, run it */
rc = run_builtin(i, cmd, usr);
goto finit;
/* We repeat the same dance for modules */
/* Its a module ? */
} else if ((i = (is_module(cmd[0]))) > -1) {
if (module_is_restricted(i)) {
rc = try_exec(cmd[0], cmd);
if (rc)
cli_restricted(cmd[0]);
goto finit;
}
rc = run_module(i, cmd);
goto finit;
} else {
/* Its not a module or builtin, restricted or otherwise.
* See what try_exec() thinks of it and just pass its return
* value back to the caller */
rc = try_exec(cmd[0], cmd);
goto finit;
}
 
/* See what try_exec thinks of it */
rc = try_exec(cmd[0], cmd);
 
finit:
if (NULL != usr->line) {
free(usr->line);
129,31 → 98,46
return rc;
}
 
/* Borrowed from Jiri Svoboda's 'cli' uspace app */
static void read_line(char *buffer, int n)
{
char c;
int chars;
console_event_t ev;
size_t offs, otmp;
wchar_t dec;
 
chars = 0;
while (chars < n - 1) {
c = getchar();
if (c < 0)
offs = 0;
while (true) {
fflush(stdout);
if (!console_get_event(fphone(stdin), &ev))
return;
if (c == '\n')
if (ev.type != KEY_PRESS)
continue;
if (ev.key == KC_ENTER || ev.key == KC_NENTER)
break;
if (c == '\b') {
if (chars > 0) {
if (ev.key == KC_BACKSPACE) {
if (offs > 0) {
/*
* Back up until we reach valid start of
* character.
*/
while (offs > 0) {
--offs; otmp = offs;
dec = str_decode(buffer, &otmp, n);
if (dec != U_SPECIAL)
break;
}
putchar('\b');
--chars;
}
continue;
}
putchar(c);
buffer[chars++] = c;
if (ev.c >= ' ') {
if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK)
putchar(ev.c);
}
}
putchar('\n');
buffer[chars] = '\0';
buffer[offs] = '\0';
}
 
/* TODO:
162,15 → 146,18
void get_input(cliuser_t *usr)
{
char line[INPUT_MAX];
size_t len = 0;
 
fflush(stdout);
console_set_style(fphone(stdout), STYLE_EMPHASIS);
printf("%s", usr->prompt);
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
 
read_line(line, INPUT_MAX);
len = strlen(line);
/* Make sure we don't have rubbish or a C/R happy user */
if (len == 0 || line[0] == '\n')
if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0)
return;
usr->line = cli_strdup(line);
usr->line = str_dup(line);
 
return;
}
/branches/arm/uspace/app/bdsh/Makefile
30,25 → 30,18
# POSSIBILITY OF SUCH DAMAGE.
 
include ../../../version
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
LIBBLOCK_PREFIX = ../../lib/libblock
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../srv/kbd/include
CFLAGS += -I../../srv/kbd/include -I$(LIBBLOCK_PREFIX)
 
LIBS = $(LIBC_PREFIX)/libc.a
DEFS += -DRELEASE=\"$(RELEASE)\"
LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
DEFS += -DRELEASE=$(RELEASE)
 
ifdef REVISION
DEFS += "-DREVISION=\"$(TIMESTAMP)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
PROGRAM = bdsh
 
# Any directory that cleaning targets should know about
57,9 → 50,9
cmds/ \
cmds/modules/ \
cmds/modules/help/ \
cmds/modules/quit/ \
cmds/modules/mkdir/ \
cmds/modules/rm/ \
cmds/modules/bdd/ \
cmds/modules/cat/ \
cmds/modules/touch/ \
cmds/modules/ls/ \
66,14 → 59,18
cmds/modules/pwd/ \
cmds/modules/sleep/ \
cmds/modules/cp/ \
cmds/modules/mv/ \
cmds/modules/mount/ \
cmds/modules/kcon/ \
cmds/builtins/ \
cmds/builtins/exit/\
cmds/builtins/cd/
 
SOURCES = \
cmds/modules/help/help.c \
cmds/modules/quit/quit.c \
cmds/modules/mkdir/mkdir.c \
cmds/modules/rm/rm.c \
cmds/modules/bdd/bdd.c \
cmds/modules/cat/cat.c \
cmds/modules/touch/touch.c \
cmds/modules/ls/ls.c \
80,6 → 77,10
cmds/modules/pwd/pwd.c \
cmds/modules/sleep/sleep.c \
cmds/modules/cp/cp.c \
cmds/modules/mv/mv.c \
cmds/modules/mount/mount.c \
cmds/modules/kcon/kcon.c \
cmds/builtins/exit/exit.c \
cmds/builtins/cd/cd.c \
cmds/mod_cmds.c \
cmds/builtin_cmds.c \
112,7 → 113,7
@$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d
 
$(PROGRAM): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(PROGRAM).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(PROGRAM).map
 
# Everything else is a phony target
.PHONY: all clean distclean depend disasm
/branches/arm/uspace/app/bdsh/AUTHORS
8,9 → 8,6
 
* Based on the HelenOS testing sub-system written by Martin Decky
 
* cli_strtok() and cli_strtok_r() (util.c) were adapted from the FreeBSD
strtok() and strtok_r() functions written by Wes Peters.
 
* read_line() (input.c) was written by Jiri Svoboda
 
Individual author copyrights are listed in the headers of each file.
/branches/arm/uspace/app/bdsh/util.c
1,7 → 1,4
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* Copyright (C) 1998 by Wes Peters <wes@softweyr.com>
* Copyright (c) 1988, 1993 The Regents of the University of California.
* All rights reserved by all copyright holders.
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> - All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
30,18 → 27,6
* POSSIBILITY OF SUCH DAMAGE.
*/
 
/* NOTES:
* 1 - Various functions were adapted from FreeBSD (copyright holders noted above)
* these functions are identified with comments.
*
* 2 - Some of these have since appeared in libc. They remain here for various
* reasons, such as the eventual integration of garbage collection for things
* that allocate memory and don't automatically free it.
*
* 3 - Things that expect a pointer to an allocated string do _no_ sanity checking
* if developing on a simulator with no debugger, take care :)
*/
 
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
54,190 → 39,6
 
extern volatile int cli_errno;
 
/* some platforms do not have strdup, implement it here.
* Returns a pointer to an allocated string or NULL on failure */
char * cli_strdup(const char *s1)
{
size_t len = strlen(s1) + 1;
void *ret = malloc(len);
 
if (ret == NULL) {
cli_errno = CL_ENOMEM;
return (char *) NULL;
}
 
cli_errno = CL_EOK;
return (char *) memcpy(ret, s1, len);
}
 
/*
* Take a previously allocated string (s1), re-size it to accept s2 and copy
* the contents of s2 into s1.
* Return -1 on failure, or the length of the copied string on success.
*/
int cli_redup(char **s1, const char *s2)
{
size_t len = strlen(s2) + 1;
 
if (! len)
return -1;
 
*s1 = realloc(*s1, len);
 
if (*s1 == NULL) {
cli_errno = CL_ENOMEM;
return -1;
}
 
memset(*s1, 0, sizeof(*s1));
memcpy(*s1, s2, len);
cli_errno = CL_EOK;
return (int) len;
}
 
/* An asprintf() for formatting paths, similar to asprintf() but ensures
* the returned allocated string is <= PATH_MAX. On failure, an attempt
* is made to return the original string (if not null) unmodified.
*
* Returns: Length of the new string on success, 0 if the string was handed
* back unmodified, -1 on failure. On failure, cli_errno is set.
*
* We do not use POSIX_PATH_MAX, as it is typically much smaller than the
* PATH_MAX defined by the kernel.
*
* Use this like:
* if (1 > cli_psprintf(&char, "%s/%s", foo, bar)) {
* cli_error(cli_errno, "Failed to format path");
* stop_what_your_doing_as_your_out_of_memory();
* }
*/
 
int cli_psprintf(char **s1, const char *fmt, ...)
{
va_list ap;
size_t needed, base = PATH_MAX + 1;
int skipped = 0;
char *orig = NULL;
char *tmp = (char *) malloc(base);
 
/* Don't even touch s1, not enough memory */
if (NULL == tmp) {
cli_errno = CL_ENOMEM;
return -1;
}
 
/* If re-allocating s1, save a copy in case we fail */
if (NULL != *s1)
orig = cli_strdup(*s1);
 
/* Print the string to tmp so we can determine the size that
* we actually need */
memset(tmp, 0, sizeof(tmp));
va_start(ap, fmt);
/* vsnprintf will return the # of bytes not written */
skipped = vsnprintf(tmp, base, fmt, ap);
va_end(ap);
 
/* realloc/alloc s1 to be just the size that we need */
needed = strlen(tmp) + 1;
*s1 = realloc(*s1, needed);
 
if (NULL == *s1) {
/* No string lived here previously, or we failed to
* make a copy of it, either way there's nothing we
* can do. */
if (NULL == *orig) {
cli_errno = CL_ENOMEM;
return -1;
}
/* We can't even allocate enough size to restore the
* saved copy, just give up */
*s1 = realloc(*s1, strlen(orig) + 1);
if (NULL == *s1) {
free(tmp);
free(orig);
cli_errno = CL_ENOMEM;
return -1;
}
/* Give the string back as we found it */
memset(*s1, 0, sizeof(*s1));
memcpy(*s1, orig, strlen(orig) + 1);
free(tmp);
free(orig);
cli_errno = CL_ENOMEM;
return 0;
}
 
/* Ok, great, we have enough room */
memset(*s1, 0, sizeof(*s1));
memcpy(*s1, tmp, needed);
free(tmp);
 
/* Free tmp only if s1 was reallocated instead of allocated */
if (NULL != orig)
free(orig);
 
if (skipped) {
/* s1 was bigger than PATH_MAX when expanded, however part
* of the string was printed. Tell the caller not to use it */
cli_errno = CL_ETOOBIG;
return -1;
}
 
/* Success! */
cli_errno = CL_EOK;
return (int) needed;
}
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */
char * cli_strtok_r(char *s, const char *delim, char **last)
{
char *spanp, *tok;
int c, sc;
 
if (s == NULL && (s = *last) == NULL) {
cli_errno = CL_EFAIL;
return (NULL);
}
 
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
 
if (c == 0) { /* no non-delimiter characters */
*last = NULL;
return (NULL);
}
 
tok = s - 1;
 
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = '\0';
*last = s;
return (tok);
}
} while (sc != 0);
}
}
 
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */
char * cli_strtok(char *s, const char *delim)
{
static char *last;
 
return (cli_strtok_r(s, delim, &last));
}
 
/* Count and return the # of elements in an array */
unsigned int cli_count_args(char **args)
{
273,10 → 74,7
if (NULL == usr->cwd)
snprintf(usr->cwd, PATH_MAX, "(unknown)");
 
if (1 < cli_psprintf(&usr->prompt, "%s # ", usr->cwd)) {
cli_error(cli_errno, "Failed to set prompt");
return 1;
}
asprintf(&usr->prompt, "%s # ", usr->cwd);
 
return 0;
}
/branches/arm/uspace/app/bdsh/util.h
3,13 → 3,6
 
#include "scli.h"
 
/* Internal string handlers */
extern char * cli_strdup(const char *);
extern int cli_redup(char **, const char *);
extern int cli_psprintf(char **, const char *, ...);
extern char * cli_strtok_r(char *, const char *, char **);
extern char * cli_strtok(char *, const char *);
 
/* Utility functions */
extern unsigned int cli_count_args(char **);
extern unsigned int cli_set_prompt(cliuser_t *usr);
/branches/arm/uspace/app/bdsh/scli.c
45,7 → 45,6
/* Globals that are modified during start-up that modules/builtins
* should be aware of. */
volatile unsigned int cli_quit = 0;
volatile unsigned int cli_interactive = 1;
volatile unsigned int cli_verbocity = 1;
 
/* The official name of this program
/branches/arm/uspace/app/getvc/getvc.c
0,0 → 1,109
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup getvc GetVC
* @brief Console initialization task.
* @{
*/
/**
* @file
*/
 
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <task.h>
#include "version.h"
 
static void usage(void)
{
printf("Usage: getvc <device> <path>\n");
}
 
static void closeall(void)
{
fclose(stdin);
fclose(stdout);
fclose(stderr);
close(0);
close(1);
close(2);
}
 
static task_id_t spawn(char *fname)
{
char *argv[2];
argv[0] = fname;
argv[1] = NULL;
task_id_t id = task_spawn(fname, argv);
if (id == 0)
printf("Error spawning %s\n", fname);
return id;
}
 
int main(int argc, char *argv[])
{
task_exit_t texit;
int retval;
 
if (argc < 3) {
usage();
return -1;
}
closeall();
stdin = fopen(argv[1], "r");
stdout = fopen(argv[1], "w");
stderr = fopen(argv[1], "w");
 
/*
* FIXME: fopen() should actually detect that we are opening a console
* and it should set line-buffering mode automatically.
*/
setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
if ((stdin == NULL)
|| (stdout == NULL)
|| (stderr == NULL))
return -2;
version_print(argv[1]);
task_id_t id = spawn(argv[2]);
task_wait(id, &texit, &retval);
return 0;
}
 
/** @}
*/
/branches/arm/uspace/app/getvc/version.c
0,0 → 1,67
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup getvc
* @{
*/
/**
* @file
*/
 
#include <unistd.h>
#include <stdio.h>
#include <macros.h>
#include "getvc.h"
#include "version.h"
 
static char *release = STRING(RELEASE);
static char *name = STRING(NAME);
static char *arch = STRING(UARCH);
 
#ifdef REVISION
static char *revision = ", revision " STRING(REVISION);
#else
static char *revision = "";
#endif
 
#ifdef TIMESTAMP
static char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
#else
static char *timestamp = "";
#endif
 
/** Print version information. */
void version_print(const char *vc)
{
printf("HelenOS release %s (%s)%s%s\n", release, name, revision, timestamp);
printf("Running on %s (%s)\n", arch, vc);
printf("Copyright (c) 2001-2009 HelenOS project\n\n");
}
 
/** @}
*/
/branches/arm/uspace/app/getvc/version.h
0,0 → 1,44
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup getvc
* @{
*/
/**
* @file
*/
 
#ifndef VERSION_H__
#define VERSION_H__
 
extern void version_print(const char *vc);
 
#endif
 
/** @}
*/
/branches/arm/uspace/app/getvc/Makefile
0,0 → 1,79
#
# Copyright (c) 2009 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
include ../../../version
 
## Setup toolchain
#
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)"
 
## Sources
#
 
OUTPUT = getvc
SOURCES = \
getvc.c \
version.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/app/getvc/getvc.h
0,0 → 1,42
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup getvc
* @{
*/
/**
* @file
*/
 
#ifndef GETVC_H__
#define GETVC_H__
 
#endif
 
/** @}
*/
/branches/arm/uspace/app/tester/devmap/devmap1.def
File deleted
/branches/arm/uspace/app/tester/devmap/devmap1.c
File deleted
/branches/arm/uspace/app/tester/console/console1.c
0,0 → 1,123
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <io/console.h>
#include <io/color.h>
#include <io/style.h>
#include <vfs/vfs.h>
#include <async.h>
#include "../tester.h"
 
const char *color_name[] = {
[COLOR_BLACK] = "black",
[COLOR_BLUE] = "blue",
[COLOR_GREEN] = "green",
[COLOR_CYAN] = "cyan",
[COLOR_RED] = "red",
[COLOR_MAGENTA] = "magenta",
[COLOR_YELLOW] = "yellow",
[COLOR_WHITE] = "white"
};
 
char *test_console1(void)
{
if (!test_quiet) {
printf("Style test: ");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
printf("normal ");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_EMPHASIS);
printf("emphasized");
fflush(stdout);
console_set_style(fphone(stdout), STYLE_NORMAL);
printf(".\n");
unsigned int i;
unsigned int j;
printf("\nForeground color test:\n");
for (j = 0; j < 2; j++) {
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
fflush(stdout);
console_set_color(fphone(stdout), i, COLOR_WHITE,
j ? CATTR_BRIGHT : 0);
printf(" %s ", color_name[i]);
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
printf("\nBackground color test:\n");
for (j = 0; j < 2; j++) {
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) {
fflush(stdout);
console_set_color(fphone(stdout), COLOR_WHITE, i,
j ? CATTR_BRIGHT : 0);
printf(" %s ", color_name[i]);
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
printf("\nRGB colors test:\n");
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i << 16);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i << 8);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
for (i = 0; i < 255; i += 16) {
fflush(stdout);
console_set_rgb_color(fphone(stdout), 0xffffff, i);
putchar('X');
}
fflush(stdout);
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
putchar('\n');
}
return NULL;
}
/branches/arm/uspace/app/tester/console/console1.def
0,0 → 1,6
{
"console1",
"Console color test",
&test_console1,
true
},
/branches/arm/uspace/app/tester/stdio/stdio1.c
0,0 → 1,90
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "../tester.h"
 
#define BUF_SIZE 32
 
static char buf[BUF_SIZE + 1];
 
char *test_stdio1(void)
{
FILE *file;
char *file_name = "/readme";
TPRINTF("Open file \"%s\"...", file_name);
errno = 0;
file = fopen(file_name, "rt");
if (file == NULL) {
TPRINTF("errno = %d\n", errno);
return "Failed opening file";
} else
TPRINTF("OK\n");
TPRINTF("Read file...");
size_t cnt = fread(buf, 1, BUF_SIZE, file);
if (ferror(file)) {
TPRINTF("errno = %d\n", errno);
fclose(file);
return "Failed reading file";
} else
TPRINTF("OK\n");
buf[cnt] = '\0';
TPRINTF("Read %u bytes, string \"%s\"\n", cnt, buf);
TPRINTF("Seek to beginning...");
if (fseek(file, 0, SEEK_SET) != 0) {
TPRINTF("errno = %d\n", errno);
fclose(file);
return "Failed seeking in file";
} else
TPRINTF("OK\n");
TPRINTF("Read using fgetc()...");
while (true) {
int c = fgetc(file);
if (c == EOF)
break;
TPRINTF(".");
}
TPRINTF("[EOF]\n");
TPRINTF("Close...");
if (fclose(file) != 0) {
TPRINTF("errno = %d\n", errno);
return "Failed closing file";
} else
TPRINTF("OK\n");
return NULL;
}
/branches/arm/uspace/app/tester/stdio/stdio2.c
0,0 → 1,83
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "../tester.h"
 
char *test_stdio2(void)
{
FILE *file;
char *file_name = "/test";
TPRINTF("Open file \"%s\" for writing...", file_name);
errno = 0;
file = fopen(file_name, "wt");
if (file == NULL) {
TPRINTF("errno = %d\n", errno);
return "Failed opening file";
} else
TPRINTF("OK\n");
TPRINTF("Write to file...");
fprintf(file, "integer: %u, string: \"%s\"", 42, "Hello!");
TPRINTF("OK\n");
TPRINTF("Close...");
if (fclose(file) != 0) {
TPRINTF("errno = %d\n", errno);
return "Failed closing file";
} else
TPRINTF("OK\n");
TPRINTF("Open file \"%s\" for reading...", file_name);
file = fopen(file_name, "rt");
if (file == NULL) {
TPRINTF("errno = %d\n", errno);
return "Failed opening file";
} else
TPRINTF("OK\n");
TPRINTF("File contains:\n");
while (true) {
int c = fgetc(file);
if (c == EOF)
break;
TPRINTF("%c", c);
}
TPRINTF("\nClose...");
if (fclose(file) != 0) {
TPRINTF("errno = %d\n", errno);
return "Failed closing file";
} else
TPRINTF("OK\n");
return NULL;
}
/branches/arm/uspace/app/tester/stdio/stdio1.def
0,0 → 1,6
{
"stdio1",
"ANSI C streams reading test",
&test_stdio1,
true
},
/branches/arm/uspace/app/tester/stdio/stdio2.def
0,0 → 1,6
{
"stdio2",
"ANSI C streams writing test",
&test_stdio2,
true
},
/branches/arm/uspace/app/tester/tester.c
27,10 → 27,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup tester User space Tester
* @brief User space testing infrastructure.
/** @addtogroup tester User space tester
* @brief User space testing infrastructure.
* @{
*/
*/
/**
* @file
*/
37,42 → 37,44
 
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "tester.h"
 
int myservice = 0;
int phones[MAX_PHONES];
int connections[MAX_CONNECTIONS];
ipc_callid_t callids[MAX_CONNECTIONS];
bool test_quiet;
int test_argc;
char **test_argv;
 
test_t tests[] = {
#include "thread/thread1.def"
#include "print/print1.def"
#include "print/print2.def"
#include "print/print3.def"
#include "print/print4.def"
#include "console/console1.def"
#include "stdio/stdio1.def"
#include "stdio/stdio2.def"
#include "fault/fault1.def"
#include "fault/fault2.def"
#include "vfs/vfs1.def"
#include "ipc/ping_pong.def"
#include "ipc/register.def"
#include "ipc/connect.def"
#include "ipc/send_async.def"
#include "ipc/send_sync.def"
#include "ipc/answer.def"
#include "ipc/hangup.def"
#include "devmap/devmap1.def"
#include "vfs/vfs1.def"
{NULL, NULL, NULL}
#include "loop/loop1.def"
#include "mm/malloc1.def"
{NULL, NULL, NULL, false}
};
 
static bool run_test(test_t *test)
{
printf("%s\t\t%s\n", test->name, test->desc);
/* Execute the test */
char * ret = test->entry(false);
char *ret = test->entry();
if (ret == NULL) {
printf("Test passed\n\n");
printf("\nTest passed\n");
return true;
}
 
printf("%s\n\n", ret);
printf("\n%s\n", ret);
return false;
}
 
81,11 → 83,12
test_t *test;
unsigned int i = 0;
unsigned int n = 0;
 
printf("\n*** Running all safe tests ***\n\n");
 
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
printf("%s (%s)\n", test->name, test->desc);
if (run_test(test))
i++;
else
92,61 → 95,52
n++;
}
}
 
printf("\nSafe tests completed, %u tests run, %u passed.\n\n", i + n, i);
printf("\nCompleted, %u tests run, %u passed.\n", i + n, i);
}
 
static void list_tests(void)
{
size_t len = 0;
test_t *test;
char c = 'a';
for (test = tests; test->name != NULL; test++) {
if (str_length(test->name) > len)
len = str_length(test->name);
}
for (test = tests; test->name != NULL; test++, c++)
printf("%c\t%s\t\t%s%s\n", c, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
for (test = tests; test->name != NULL; test++)
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("*\t\t\tRun all safe tests\n");
printf("%-*s Run all safe tests\n", len, "*");
}
 
int main(int argc, char **argv)
int main(int argc, char *argv[])
{
printf("Number of arguments: %d\n", argc);
if (argv) {
printf("Arguments:");
while (*argv) {
printf(" '%s'", *argv++);
}
printf("\n");
if (argc < 2) {
printf("Usage:\n\n");
printf("%s <test> [args ...]\n\n", argv[0]);
list_tests();
return 0;
}
 
while (1) {
char c;
test_t *test;
list_tests();
printf("> ");
c = getchar();
printf("%c\n", c);
if ((c >= 'a') && (c <= 'z')) {
for (test = tests; test->name != NULL; test++, c--)
if (c == 'a')
break;
if (test->name == NULL)
printf("Unknown test\n\n");
else
run_test(test);
} else if (c == '*') {
run_safe_tests();
} else if (c < 0) {
/* got EOF */
break;
} else {
printf("Invalid test\n\n");
test_quiet = false;
test_argc = argc - 2;
test_argv = argv + 2;
if (str_cmp(argv[1], "*") == 0) {
run_safe_tests();
return 0;
}
test_t *test;
for (test = tests; test->name != NULL; test++) {
if (str_cmp(argv[1], test->name) == 0) {
return (run_test(test) ? 0 : -1);
}
}
printf("Unknown test \"%s\"\n", argv[1]);
return -2;
}
 
/** @}
/branches/arm/uspace/app/tester/thread/thread1.c
27,7 → 27,8
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#define THREADS 5
#define THREADS 20
#define DELAY 10
 
#include <atomic.h>
#include <thread.h>
42,40 → 43,38
static void threadtest(void *data)
{
thread_detach(thread_get_id());
 
while (atomic_get(&finish)) {
if (!sh_quiet)
printf("%llu ", thread_get_id());
while (atomic_get(&finish))
usleep(100000);
}
atomic_inc(&threads_finished);
}
 
char * test_thread1(bool quiet)
char *test_thread1(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
unsigned int i;
unsigned int total = 0;
atomic_set(&finish, 1);
atomic_set(&threads_finished, 0);
 
for (i = 0; i < THREADS; i++) {
TPRINTF("Creating threads");
for (i = 0; i < THREADS; i++) {
if (thread_create(threadtest, NULL, "threadtest", NULL) < 0) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("\nCould not create thread %u\n", i);
break;
}
TPRINTF(".");
total++;
}
if (!quiet)
printf("Running threads for 10 seconds...\n");
sleep(10);
TPRINTF("\nRunning threads for %u seconds...", DELAY);
sleep(DELAY);
TPRINTF("\n");
atomic_set(&finish, 0);
while (atomic_get(&threads_finished) < total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_finished));
TPRINTF("Threads left: %u\n", total - atomic_get(&threads_finished));
sleep(1);
}
/branches/arm/uspace/app/tester/loop/loop1.c
0,0 → 1,40
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include "../tester.h"
 
char *test_loop1(void)
{
TPRINTF("Looping...");
while (true);
TPRINTF("\n");
return "Survived endless loop";
}
/branches/arm/uspace/app/tester/loop/loop1.def
0,0 → 1,6
{
"loop1",
"Endless loop",
&test_loop1,
false
},
/branches/arm/uspace/app/tester/fault/fault1.c
29,7 → 29,7
 
#include "../tester.h"
 
char * test_fault1(bool quiet)
char *test_fault1(void)
{
((int *)(0))[1] = 0;
/branches/arm/uspace/app/tester/fault/fault2.c
29,7 → 29,7
 
#include "../tester.h"
 
char * test_fault2(bool quiet)
char *test_fault2(void)
{
volatile long long var;
volatile int var1;
/branches/arm/uspace/app/tester/ipc/send_sync.def
File deleted
/branches/arm/uspace/app/tester/ipc/answer.def
File deleted
/branches/arm/uspace/app/tester/ipc/send_async.def
File deleted
/branches/arm/uspace/app/tester/ipc/answer.c
File deleted
/branches/arm/uspace/app/tester/ipc/hangup.def
File deleted
/branches/arm/uspace/app/tester/ipc/send_async.c
File deleted
/branches/arm/uspace/app/tester/ipc/send_sync.c
File deleted
/branches/arm/uspace/app/tester/ipc/hangup.c
File deleted
/branches/arm/uspace/app/tester/ipc/ping_pong.c
0,0 → 1,78
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <ipc/ns.h>
#include <async.h>
#include <errno.h>
#include "../tester.h"
 
#define DURATION_SECS 10
#define COUNT_GRANULARITY 100
 
char *test_ping_pong(void)
{
TPRINTF("Pinging ns server for %d seconds...", DURATION_SECS);
struct timeval start;
if (gettimeofday(&start, NULL) != 0) {
TPRINTF("\n");
return "Failed getting the time";
}
uint64_t count = 0;
while (true) {
struct timeval now;
if (gettimeofday(&now, NULL) != 0) {
TPRINTF("\n");
return "Failed getting the time";
}
if (tv_sub(&now, &start) >= DURATION_SECS * 1000000L)
break;
size_t i;
for (i = 0; i < COUNT_GRANULARITY; i++) {
int retval = async_req_0_0(PHONE_NS, NS_PING);
if (retval != EOK) {
TPRINTF("\n");
return "Failed to send ping message";
}
}
count += COUNT_GRANULARITY;
}
TPRINTF("OK\nCompleted %llu round trips in %u seconds, %llu rt/s.\n",
count, DURATION_SECS, count / DURATION_SECS);
return NULL;
}
/branches/arm/uspace/app/tester/ipc/register.c
32,58 → 32,58
#include <errno.h>
#include "../tester.h"
 
#define MAX_CONNECTIONS 50
 
static int connections[MAX_CONNECTIONS];
 
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t phonehash = icall->in_phone_hash;
int retval;
int i;
 
printf("Connected phone: %P, accepting\n", icall->in_phone_hash);
unsigned int i;
TPRINTF("Connected phone %#x accepting\n", icall->in_phone_hash);
ipc_answer_0(iid, EOK);
for (i = 0; i < 1024; i++)
for (i = 0; i < MAX_CONNECTIONS; i++) {
if (!connections[i]) {
connections[i] = phonehash;
connections[i] = icall->in_phone_hash;
break;
}
}
while (1) {
callid = async_get_call(&call);
while (true) {
ipc_call_t call;
ipc_callid_t callid = async_get_call(&call);
int retval;
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
printf("Phone (%P) hung up.\n", phonehash);
TPRINTF("Phone %#x hung up\n", icall->in_phone_hash);
retval = 0;
break;
case IPC_TEST_METHOD:
TPRINTF("Received well known message from %#x: %#x\n",
icall->in_phone_hash, callid);
ipc_answer_0(callid, EOK);
break;
default:
printf("Received message from %P: %X\n", phonehash,
callid);
for (i = 0; i < 1024; i++)
if (!callids[i]) {
callids[i] = callid;
break;
}
continue;
TPRINTF("Received unknown message from %#x: %#x\n",
icall->in_phone_hash, callid);
ipc_answer_0(callid, ENOENT);
break;
}
ipc_answer_0(callid, retval);
}
}
 
char * test_register(bool quiet)
char *test_register(void)
{
int i;
async_set_client_connection(client_connection);
 
for (i = IPC_TEST_START; i < IPC_TEST_START + 10; i++) {
ipcarg_t phonead;
int res = ipc_connect_to_me(PHONE_NS, i, 0, 0, &phonead);
if (!res)
break;
printf("Failed registering as %d..:%d\n", i, res);
}
printf("Registered as service: %d\n", i);
myservice = i;
ipcarg_t phonead;
int res = ipc_connect_to_me(PHONE_NS, IPC_TEST_SERVICE, 0, 0, &phonead);
if (res != 0)
return "Failed registering IPC service";
TPRINTF("Registered as service %u, accepting connections\n", IPC_TEST_SERVICE);
async_manager();
return NULL;
}
/branches/arm/uspace/app/tester/ipc/connect.c
28,32 → 28,46
 
#include <stdio.h>
#include <unistd.h>
#include <atomic.h>
#include "../tester.h"
 
char * test_connect(bool quiet)
static atomic_t finish;
 
static void callback(void *priv, int retval, ipc_call_t *data)
{
char c;
int svc;
int phid;
atomic_set(&finish, 1);
}
 
printf("Choose one service: 0:10000....9:10009 (q to skip)\n");
do {
c = getchar();
if ((c == 'Q') || (c == 'q'))
return TEST_SKIPPED;
} while (c < '0' || c > '9');
char *test_connect(void)
{
TPRINTF("Connecting to %u...", IPC_TEST_SERVICE);
int phone = ipc_connect_me_to(PHONE_NS, IPC_TEST_SERVICE, 0, 0);
if (phone > 0) {
TPRINTF("phoneid %d\n", phone);
} else {
TPRINTF("\n");
return "ipc_connect_me_to() failed";
}
svc = IPC_TEST_START + c - '0';
if (svc == myservice)
return "Currently cannot connect to myself, update test";
printf("Sending synchronous message...\n");
int retval = ipc_call_sync_0_0(phone, IPC_TEST_METHOD);
TPRINTF("Received response to synchronous message\n");
printf("Connecting to %d..", svc);
phid = ipc_connect_me_to(PHONE_NS, svc, 0, 0);
if (phid > 0) {
printf("phoneid: %d\n", phid);
phones[phid] = 1;
} else
return "Error";
TPRINTF("Sending asynchronous message...\n");
atomic_set(&finish, 0);
ipc_call_async_0(phone, IPC_TEST_METHOD, NULL, callback, 1);
while (atomic_get(&finish) != 1)
TPRINTF(".");
TPRINTF("Received response to asynchronous message\n");
TPRINTF("Hanging up...");
retval = ipc_hangup(phone);
if (retval == 0) {
TPRINTF("OK\n");
} else {
TPRINTF("\n");
return "ipc_hangup() failed";
}
return NULL;
}
/branches/arm/uspace/app/tester/ipc/ping_pong.def
0,0 → 1,6
{
"ping_pong",
"IPC ping-pong benchmark",
&test_ping_pong,
true
},
/branches/arm/uspace/app/tester/print/print2.c
0,0 → 1,52
/*
* Copyright (c) 2005 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
char *test_print2(void)
{
TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
TPRINTF("Expected output: [a] [ b] [c ] [ d] [e ]\n");
TPRINTF("Real output: [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n");
TPRINTF("Expected output: [1] [ 02] [03 ] [004] [005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", 1, 2, 3, 4, 5);
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", -1, -2, -3, -4, -5):\n");
TPRINTF("Expected output: [-1] [-02] [-03] [-004] [-005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", -1, -2, -3, -4, -5);
TPRINTF("Testing printf(\"%%#x %%5.3#x %%-5.3#x %%3.5#x %%-3.5#x\", 17, 18, 19, 20, 21):\n");
TPRINTF("Expected output: [0x11] [0x012] [0x013] [0x00014] [0x00015]\n");
TPRINTF("Real output: [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21);
return NULL;
}
/branches/arm/uspace/app/tester/print/print3.c
0,0 → 1,62
/*
* Copyright (c) 2005 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <macros.h>
#include "../tester.h"
 
#define BUFFER_SIZE 32
 
char *test_print3(void)
{
char buffer[BUFFER_SIZE];
int retval;
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short text without parameters.\"):\n");
TPRINTF("Expected result: retval=30 buffer=\"Short text without parameters.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very very very long text without parameters.\"):\n");
TPRINTF("Expected result: retval=44 buffer=\"Very very very long text withou\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short %%s.\", \"text\"):\n");
TPRINTF("Expected result: retval=11 buffer=\"Short text.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short %s.", "text");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very long %%s. This text's length is more than %%d. We are interested in the result.\", \"text\", " STRING(BUFFER_SIZE) "):\n");
TPRINTF("Expected result: retval=84 buffer=\"Very long text. This text's len\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text's length is more than %d. We are interested in the result.", "text", BUFFER_SIZE);
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
return NULL;
}
/branches/arm/uspace/app/tester/print/print4.c
0,0 → 1,83
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include "../tester.h"
 
char *test_print4(void)
{
TPRINTF("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n");
uint8_t group;
for (group = 1; group < 4; group++) {
TPRINTF("%#x: ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%c", (char) ((group << 5) + index));
TPRINTF(" ");
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
TPRINTF("\n");
}
TPRINTF("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n");
for (group = 4; group < 8; group++) {
TPRINTF("%#x: ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
TPRINTF("\n");
}
TPRINTF("\nUTF-8 strings using printf(\"%%s\"):\n");
TPRINTF("English: %s\n", "Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %s\n", "Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %s\n", "Սկսեց հրատարակվել Երուսաղեմի հայկական");
TPRINTF("\nUTF-32 strings using printf(\"%%ls\"):\n");
TPRINTF("English: %ls\n", L"Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %ls\n", L"Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %ls\n", L"Սկսեց հրատարակվել Երուսաղեմի հայկական");
return NULL;
}
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/app/tester/print/print1.def
1,6 → 1,6
{
"print1",
"Printf test",
"String printf test",
&test_print1,
true
},
/branches/arm/uspace/app/tester/print/print2.def
0,0 → 1,6
{
"print2",
"Numeric printf test",
&test_print2,
true
},
/branches/arm/uspace/app/tester/print/print3.def
0,0 → 1,6
{
"print3",
"Buffered printf test",
&test_print3,
true
},
/branches/arm/uspace/app/tester/print/print1.c
30,44 → 30,27
#include <unistd.h>
#include "../tester.h"
 
#define BUFFER_SIZE 32
 
char * test_print1(bool quiet)
char *test_print1(void)
{
if (!quiet) {
int retval;
unsigned int nat = 0x12345678u;
char buffer[BUFFER_SIZE];
printf(" text 10.8s %*.*s \n", 5, 3, "text");
printf(" very long text 10.8s %10.8s \n", "very long text");
printf(" text 8.10s %8.10s \n", "text");
printf(" very long text 8.10s %8.10s \n", "very long text");
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' );
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 );
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 );
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 );
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
printf(" Print to NULL '%s'\n", NULL);
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
printf("Result is: '%s', retval = %d\n", buffer, retval);
}
TPRINTF("Testing printf(\"%%*.*s\", 5, 3, \"text\"):\n");
TPRINTF("Expected output: \" tex\"\n");
TPRINTF("Real output: \"%*.*s\"\n\n", 5, 3, "text");
TPRINTF("Testing printf(\"%%10.8s\", \"very long text\"):\n");
TPRINTF("Expected output: \" very lon\"\n");
TPRINTF("Real output: \"%10.8s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%8.10s\", \"text\"):\n");
TPRINTF("Expected output: \"text\"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "text");
TPRINTF("Testing printf(\"%%8.10s\", \"very long text\"):\n");
TPRINTF("Expected output: \"very long \"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%s\", NULL):\n");
TPRINTF("Expected output: \"(NULL)\"\n");
TPRINTF("Real output: \"%s\"\n\n", NULL);
return NULL;
}
/branches/arm/uspace/app/tester/print/print4.def
0,0 → 1,6
{
"print4",
"Unicode test",
&test_print4,
true
},
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/app/tester/tester.h
39,37 → 39,45
#include <bool.h>
#include <ipc/ipc.h>
 
#define IPC_TEST_START 10000
#define MAX_PHONES 20
#define MAX_CONNECTIONS 50
#define TEST_SKIPPED "Test Skipped"
#define IPC_TEST_SERVICE 10240
#define IPC_TEST_METHOD 2000
 
extern int myservice;
extern int phones[MAX_PHONES];
extern int connections[MAX_CONNECTIONS];
extern ipc_callid_t callids[MAX_CONNECTIONS];
extern bool test_quiet;
extern int test_argc;
extern char **test_argv;
 
typedef char * (* test_entry_t)(bool);
#define TPRINTF(format, ...) \
{ \
if (!test_quiet) { \
fprintf(stderr, format, ##__VA_ARGS__); \
} \
}
 
typedef char *(*test_entry_t)(void);
 
typedef struct {
char * name;
char * desc;
char *name;
char *desc;
test_entry_t entry;
bool safe;
} test_t;
 
extern char * test_thread1(bool quiet);
extern char * test_print1(bool quiet);
extern char * test_fault1(bool quiet);
extern char * test_fault2(bool quiet);
extern char * test_register(bool quiet);
extern char * test_connect(bool quiet);
extern char * test_send_async(bool quiet);
extern char * test_send_sync(bool quiet);
extern char * test_answer(bool quiet);
extern char * test_hangup(bool quiet);
extern char * test_devmap1(bool quiet);
extern char * test_vfs1(bool quiet);
extern char *test_thread1(void);
extern char *test_print1(void);
extern char *test_print2(void);
extern char *test_print3(void);
extern char *test_print4(void);
extern char *test_console1(void);
extern char *test_stdio1(void);
extern char *test_stdio2(void);
extern char *test_fault1(void);
extern char *test_fault2(void);
extern char *test_vfs1(void);
extern char *test_ping_pong(void);
extern char *test_register(void);
extern char *test_connect(void);
extern char *test_loop1(void);
extern char *test_malloc1(void);
 
extern test_t tests[];
 
/branches/arm/uspace/app/tester/Makefile
31,6 → 31,7
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../srv/kbd/include
44,16 → 45,20
SOURCES = tester.c \
thread/thread1.c \
print/print1.c \
print/print2.c \
print/print3.c \
print/print4.c \
console/console1.c \
stdio/stdio1.c \
stdio/stdio2.c \
fault/fault1.c \
fault/fault2.c \
vfs/vfs1.c \
ipc/ping_pong.c \
ipc/register.c \
ipc/connect.c \
ipc/send_async.c \
ipc/send_sync.c \
ipc/answer.c \
ipc/hangup.c \
devmap/devmap1.c \
vfs/vfs1.c
loop/loop1.c \
mm/malloc1.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
64,18 → 69,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/app/tester/vfs/vfs1.c
34,109 → 34,118
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <devmap.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../tester.h"
 
char text[] = "O xein', angellein Lakedaimoniois hoti teide "
"keimetha tois keinon rhemasi peithomenoi.";
#define FS_TYPE "tmpfs"
#define MOUNT_POINT "/tmp"
#define OPTIONS ""
#define FLAGS 0
 
char *test_vfs1(bool quiet)
#define TEST_DIRECTORY MOUNT_POINT "/testdir"
#define TEST_FILE TEST_DIRECTORY "/testfile"
#define TEST_FILE2 TEST_DIRECTORY "/nextfile"
 
#define MAX_DEVICE_NAME 32
#define BUF_SIZE 16
 
static char text[] = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
 
static char *read_root(void)
{
int rc;
TPRINTF("Opening the root directory...");
DIR *dirp = opendir("/");
if (!dirp) {
TPRINTF("\n");
return "opendir() failed";
} else
TPRINTF("OK\n");
struct dirent *dp;
while ((dp = readdir(dirp)))
TPRINTF(" node \"%s\"\n", dp->d_name);
closedir(dirp);
return NULL;
}
 
rc = mount("tmpfs", "/", "nulldev0");
char *test_vfs1(void)
{
if (mkdir(MOUNT_POINT, 0) != 0)
return "mkdir() failed";
TPRINTF("Created directory %s\n", MOUNT_POINT);
char null[MAX_DEVICE_NAME];
int null_id = devmap_null_create();
if (null_id == -1)
return "Unable to create null device";
snprintf(null, MAX_DEVICE_NAME, "null%d", null_id);
int rc = mount(FS_TYPE, MOUNT_POINT, null, OPTIONS, FLAGS);
switch (rc) {
case EOK:
if (!quiet)
printf("mounted tmpfs on /\n");
TPRINTF("Mounted /dev/%s as %s on %s\n", null, FS_TYPE, MOUNT_POINT);
break;
case EBUSY:
if (!quiet)
printf("(INFO) something is already mounted on /\n");
TPRINTF("(INFO) Filesystem already mounted on %s\n", MOUNT_POINT);
break;
default:
if (!quiet)
printf("(INFO) IPC returned errno %d\n", rc);
return "mount() failed.";
TPRINTF("(ERR) IPC returned errno %d (is tmpfs loaded?)\n", rc);
return "mount() failed";
}
 
if (mkdir("/mydir", 0) != 0)
return "mkdir() failed.\n";
if (!quiet)
printf("created directory /mydir\n");
int fd0 = open("/mydir/myfile", O_CREAT);
if (mkdir(TEST_DIRECTORY, 0) != 0)
return "mkdir() failed";
TPRINTF("Created directory %s\n", TEST_DIRECTORY);
int fd0 = open(TEST_FILE, O_CREAT);
if (fd0 < 0)
return "open() failed.\n";
if (!quiet)
printf("created file /mydir/myfile, fd=%d\n", fd0);
 
ssize_t cnt;
return "open() failed";
TPRINTF("Created file %s (fd=%d)\n", TEST_FILE, fd0);
size_t size = sizeof(text);
cnt = write(fd0, text, size);
ssize_t cnt = write(fd0, text, size);
if (cnt < 0)
return "write() failed.\n";
if (!quiet)
printf("written %d bytes, fd=%d\n", cnt, fd0);
return "write() failed";
TPRINTF("Written %d bytes\n", cnt);
if (lseek(fd0, 0, SEEK_SET) != 0)
return "lseek() failed.\n";
if (!quiet)
printf("sought to position 0, fd=%d\n", fd0);
 
char buf[10];
 
while ((cnt = read(fd0, buf, sizeof(buf)))) {
return "lseek() failed";
TPRINTF("Sought to position 0\n");
char buf[BUF_SIZE];
while ((cnt = read(fd0, buf, BUF_SIZE))) {
if (cnt < 0)
return "read() failed.\n";
if (!quiet)
printf("read %d bytes: \"%.*s\", fd=%d\n", cnt, cnt,
buf, fd0);
return "read() failed";
TPRINTF("Read %d bytes: \".*s\"\n", cnt, cnt, buf);
}
 
close(fd0);
 
DIR *dirp;
struct dirent *dp;
 
if (!quiet)
printf("scanning the root directory...\n");
 
dirp = opendir("/");
if (!dirp)
return "opendir() failed\n";
while ((dp = readdir(dirp)))
printf("discovered node %s in /\n", dp->d_name);
closedir(dirp);
 
if (rename("/mydir/myfile", "/mydir/yourfile"))
return "rename() failed.\n";
 
if (!quiet)
printf("renamed /mydir/myfile to /mydir/yourfile\n");
 
if (unlink("/mydir/yourfile"))
return "unlink() failed.\n";
if (!quiet)
printf("unlinked file /mydir/yourfile\n");
 
if (rmdir("/mydir"))
return "rmdir() failed.\n";
 
if (!quiet)
printf("removed directory /mydir\n");
char *rv = read_root();
if (rv != NULL)
return rv;
if (!quiet)
printf("scanning the root directory...\n");
 
dirp = opendir("/");
if (!dirp)
return "opendir() failed\n";
while ((dp = readdir(dirp)))
printf("discovered node %s in /\n", dp->d_name);
closedir(dirp);
 
if (rename(TEST_FILE, TEST_FILE2))
return "rename() failed";
TPRINTF("Renamed %s to %s\n", TEST_FILE, TEST_FILE2);
if (unlink(TEST_FILE2))
return "unlink() failed";
TPRINTF("Unlinked %s\n", TEST_FILE2);
if (rmdir(TEST_DIRECTORY))
return "rmdir() failed";
TPRINTF("Removed directory %s\n", TEST_DIRECTORY);
rv = read_root();
if (rv != NULL)
return rv;
return NULL;
}
 
/branches/arm/uspace/app/tester/mm/malloc1.def
0,0 → 1,6
{
"malloc1",
"Memory allocator test",
&test_malloc1,
true
},
/branches/arm/uspace/app/tester/mm/malloc1.c
0,0 → 1,651
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Tomas Bures
* Copyright (c) 2009 Lubomir Bulej
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <malloc.h>
#include "../tester.h"
 
/*
* The test consists of several phases which differ in the size of blocks
* they allocate. The size of blocks is given as a range of minimum and
* maximum allowed size. Each of the phases is divided into 3 subphases which
* differ in the probability of free and alloc actions. Second subphase is
* started when malloc returns 'out of memory' or when MAX_ALLOC is reached.
* Third subphase is started after a given number of cycles. The third subphase
* as well as the whole phase ends when all memory blocks are released.
*/
 
/**
* sizeof_array
* @array array to determine the size of
*
* Returns the size of @array in array elements.
*/
#define sizeof_array(array) \
(sizeof(array) / sizeof((array)[0]))
 
#define MAX_ALLOC (16 * 1024 * 1024)
 
/*
* Subphase control structures: subphase termination conditions,
* probabilities of individual actions, subphase control structure.
*/
 
typedef struct {
unsigned int max_cycles;
unsigned int no_memory;
unsigned int no_allocated;
} sp_term_cond_s;
 
typedef struct {
unsigned int alloc;
unsigned int free;
} sp_action_prob_s;
 
typedef struct {
char *name;
sp_term_cond_s cond;
sp_action_prob_s prob;
} subphase_s;
 
 
/*
* Phase control structures: The minimum and maximum block size that
* can be allocated during the phase execution, phase control structure.
*/
 
typedef struct {
size_t min_block_size;
size_t max_block_size;
} ph_alloc_size_s;
 
typedef struct {
char *name;
ph_alloc_size_s alloc;
subphase_s *subphases;
} phase_s;
 
 
/*
* Subphases are defined separately here. This is for two reasons:
* 1) data are not duplicated, 2) we don't have to state beforehand
* how many subphases a phase contains.
*/
static subphase_s subphases_32B[] = {
{
.name = "Allocation",
.cond = {
.max_cycles = 200,
.no_memory = 1,
.no_allocated = 0,
},
.prob = {
.alloc = 90,
.free = 100
}
},
{
.name = "Alloc/Dealloc",
.cond = {
.max_cycles = 200,
.no_memory = 0,
.no_allocated = 0,
},
.prob = {
.alloc = 50,
.free = 100
}
},
{
.name = "Deallocation",
.cond = {
.max_cycles = 0,
.no_memory = 0,
.no_allocated = 1,
},
.prob = {
.alloc = 10,
.free = 100
}
}
};
 
static subphase_s subphases_128K[] = {
{
.name = "Allocation",
.cond = {
.max_cycles = 0,
.no_memory = 1,
.no_allocated = 0,
},
.prob = {
.alloc = 70,
.free = 100
}
},
{
.name = "Alloc/Dealloc",
.cond = {
.max_cycles = 30,
.no_memory = 0,
.no_allocated = 0,
},
.prob = {
.alloc = 50,
.free = 100
}
},
{
.name = "Deallocation",
.cond = {
.max_cycles = 0,
.no_memory = 0,
.no_allocated = 1,
},
.prob = {
.alloc = 30,
.free = 100
}
}
};
 
static subphase_s subphases_default[] = {
{
.name = "Allocation",
.cond = {
.max_cycles = 0,
.no_memory = 1,
.no_allocated = 0,
},
.prob = {
.alloc = 90,
.free = 100
}
},
{
.name = "Alloc/Dealloc",
.cond = {
.max_cycles = 200,
.no_memory = 0,
.no_allocated = 0,
},
.prob = {
.alloc = 50,
.free = 100
}
},
{
.name = "Deallocation",
.cond = {
.max_cycles = 0,
.no_memory = 0,
.no_allocated = 1,
},
.prob = {
.alloc = 10,
.free = 100
}
}
};
 
 
/*
* Phase definitions.
*/
static phase_s phases[] = {
{
.name = "32 B memory blocks",
.alloc = {
.min_block_size = 32,
.max_block_size = 32
},
.subphases = subphases_32B
},
{
.name = "128 KB memory blocks",
.alloc = {
.min_block_size = 128 * 1024,
.max_block_size = 128 * 1024
},
.subphases = subphases_128K
},
{
.name = "2500 B memory blocks",
.alloc = {
.min_block_size = 2500,
.max_block_size = 2500
},
.subphases = subphases_default
},
{
.name = "1 B .. 250000 B memory blocks",
.alloc = {
.min_block_size = 1,
.max_block_size = 250000
},
.subphases = subphases_default
}
};
 
 
/*
* Global error flag. The flag is set if an error
* is encountered (overlapping blocks, inconsistent
* block data, etc.)
*/
static bool error_flag = false;
 
/*
* Memory accounting: the amount of allocated memory and the
* number and list of allocated blocks.
*/
static size_t mem_allocated;
static size_t mem_blocks_count;
 
static LIST_INITIALIZE(mem_blocks);
 
typedef struct {
/* Address of the start of the block */
void *addr;
/* Size of the memory block */
size_t size;
/* link to other blocks */
link_t link;
} mem_block_s;
 
typedef mem_block_s *mem_block_t;
 
 
/** init_mem
*
* Initializes the memory accounting structures.
*
*/
static void init_mem(void)
{
mem_allocated = 0;
mem_blocks_count = 0;
}
 
 
static bool overlap_match(link_t *entry, void *addr, size_t size)
{
mem_block_t mblk = list_get_instance(entry, mem_block_s, link);
/* Entry block control structure <mbeg, mend) */
uint8_t *mbeg = (uint8_t *) mblk;
uint8_t *mend = (uint8_t *) mblk + sizeof(mem_block_s);
/* Entry block memory <bbeg, bend) */
uint8_t *bbeg = (uint8_t *) mblk->addr;
uint8_t *bend = (uint8_t *) mblk->addr + mblk->size;
/* Data block <dbeg, dend) */
uint8_t *dbeg = (uint8_t *) addr;
uint8_t *dend = (uint8_t *) addr + size;
/* Check for overlaps */
if (((mbeg >= dbeg) && (mbeg < dend)) ||
((mend > dbeg) && (mend <= dend)) ||
((bbeg >= dbeg) && (bbeg < dend)) ||
((bend > dbeg) && (bend <= dend)))
return true;
return false;
}
 
 
/** test_overlap
*
* Test whether a block starting at @addr overlaps with another, previously
* allocated memory block or its control structure.
*
* @param addr Initial address of the block
* @param size Size of the block
*
* @return false if the block does not overlap.
*
*/
static int test_overlap(void *addr, size_t size)
{
link_t *entry;
bool fnd = false;
for (entry = mem_blocks.next; entry != &mem_blocks; entry = entry->next) {
if (overlap_match(entry, addr, size)) {
fnd = true;
break;
}
}
return fnd;
}
 
 
/** checked_malloc
*
* Allocate @size bytes of memory and check whether the chunk comes
* from the non-mapped memory region and whether the chunk overlaps
* with other, previously allocated, chunks.
*
* @param size Amount of memory to allocate
*
* @return NULL if the allocation failed. Sets the global error_flag to
* true if the allocation succeeded but is illegal.
*
*/
static void *checked_malloc(size_t size)
{
void *data;
/* Allocate the chunk of memory */
data = malloc(size);
if (data == NULL)
return NULL;
/* Check for overlaps with other chunks */
if (test_overlap(data, size)) {
TPRINTF("\nError: Allocated block overlaps with another "
"previously allocated block.\n");
error_flag = true;
}
return data;
}
 
 
/** alloc_block
*
* Allocate a block of memory of @size bytes and add record about it into
* the mem_blocks list. Return a pointer to the block holder structure or
* NULL if the allocation failed.
*
* If the allocation is illegal (e.g. the memory does not come from the
* right region or some of the allocated blocks overlap with others),
* set the global error_flag.
*
* @param size Size of the memory block
*
*/
static mem_block_t alloc_block(size_t size)
{
/* Check for allocation limit */
if (mem_allocated >= MAX_ALLOC)
return NULL;
/* Allocate the block holder */
mem_block_t block = (mem_block_t) checked_malloc(sizeof(mem_block_s));
if (block == NULL)
return NULL;
link_initialize(&block->link);
/* Allocate the block memory */
block->addr = checked_malloc(size);
if (block->addr == NULL) {
free(block);
return NULL;
}
block->size = size;
/* Register the allocated block */
list_append(&block->link, &mem_blocks);
mem_allocated += size + sizeof(mem_block_s);
mem_blocks_count++;
return block;
}
 
 
/** free_block
*
* Free the block of memory and the block control structure allocated by
* alloc_block. Set the global error_flag if an error occurs.
*
* @param block Block control structure
*
*/
static void free_block(mem_block_t block)
{
/* Unregister the block */
list_remove(&block->link);
mem_allocated -= block->size + sizeof(mem_block_s);
mem_blocks_count--;
/* Free the memory */
free(block->addr);
free(block);
}
 
 
/** expected_value
*
* Compute the expected value of a byte located at @pos in memory
* block described by @blk.
*
* @param blk Memory block control structure
* @param pos Position in the memory block data area
*
*/
static inline uint8_t expected_value(mem_block_t blk, uint8_t *pos)
{
return ((unsigned long) blk ^ (unsigned long) pos) & 0xff;
}
 
 
/** fill_block
*
* Fill the memory block controlled by @blk with data.
*
* @param blk Memory block control structure
*
*/
static void fill_block(mem_block_t blk)
{
uint8_t *pos;
uint8_t *end;
for (pos = blk->addr, end = pos + blk->size; pos < end; pos++)
*pos = expected_value(blk, pos);
}
 
 
/** check_block
*
* Check whether the block @blk contains the data it was filled with.
* Set global error_flag if an error occurs.
*
* @param blk Memory block control structure
*
*/
static void check_block(mem_block_t blk)
{
uint8_t *pos;
uint8_t *end;
for (pos = blk->addr, end = pos + blk->size; pos < end; pos++) {
if (*pos != expected_value (blk, pos)) {
TPRINTF("\nError: Corrupted content of a data block.\n");
error_flag = true;
return;
}
}
}
 
 
static link_t *list_get_nth(link_t *list, unsigned int i)
{
unsigned int cnt = 0;
link_t *entry;
for (entry = list->next; entry != list; entry = entry->next) {
if (cnt == i)
return entry;
cnt++;
}
return NULL;
}
 
 
/** get_random_block
*
* Select a random memory block from the list of allocated blocks.
*
* @return Block control structure or NULL if the list is empty.
*
*/
static mem_block_t get_random_block(void)
{
if (mem_blocks_count == 0)
return NULL;
unsigned int blkidx = rand() % mem_blocks_count;
link_t *entry = list_get_nth(&mem_blocks, blkidx);
if (entry == NULL) {
TPRINTF("\nError: Corrupted list of allocated memory blocks.\n");
error_flag = true;
}
return list_get_instance(entry, mem_block_s, link);
}
 
 
#define RETURN_IF_ERROR \
{ \
if (error_flag) \
return; \
}
 
 
static void do_subphase(phase_s *phase, subphase_s *subphase)
{
unsigned int cycles;
for (cycles = 0; /* always */; cycles++) {
if (subphase->cond.max_cycles &&
cycles >= subphase->cond.max_cycles) {
/*
* We have performed the required number of
* cycles. End the current subphase.
*/
break;
}
/*
* Decide whether we alloc or free memory in this step.
*/
unsigned int rnd = rand() % 100;
if (rnd < subphase->prob.alloc) {
/* Compute a random number lying in interval <min_block_size, max_block_size> */
int alloc = phase->alloc.min_block_size +
(rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
mem_block_t blk = alloc_block(alloc);
RETURN_IF_ERROR;
if (blk == NULL) {
TPRINTF("F(A)");
if (subphase->cond.no_memory) {
/* We filled the memory. Proceed to next subphase */
break;
}
} else {
TPRINTF("A");
fill_block(blk);
}
} else if (rnd < subphase->prob.free) {
mem_block_t blk = get_random_block();
if (blk == NULL) {
TPRINTF("F(R)");
if (subphase->cond.no_allocated) {
/* We free all the memory. Proceed to next subphase. */
break;
}
} else {
TPRINTF("R");
check_block(blk);
RETURN_IF_ERROR;
free_block(blk);
RETURN_IF_ERROR;
}
}
}
TPRINTF("\n.. finished.\n");
}
 
 
static void do_phase(phase_s *phase)
{
unsigned int subno;
for (subno = 0; subno < 3; subno++) {
subphase_s *subphase = & phase->subphases [subno];
TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name);
do_subphase(phase, subphase);
RETURN_IF_ERROR;
}
}
 
char *test_malloc1(void)
{
init_mem();
unsigned int phaseno;
for (phaseno = 0; phaseno < sizeof_array(phases); phaseno++) {
phase_s *phase = &phases[phaseno];
TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
do_phase(phase);
if (error_flag)
break;
TPRINTF("Phase finished.\n");
}
if (error_flag)
return "Test failed";
return NULL;
}
/branches/arm/uspace/app/trace/trace.c
35,7 → 35,6
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syscall.h>
#include <ipc/ipc.h>
#include <fibril.h>
#include <errno.h>
42,13 → 41,17
#include <udebug.h>
#include <async.h>
#include <task.h>
#include <mem.h>
#include <string.h>
#include <loader/loader.h>
 
#include <libc.h>
 
// Temporary: service and method names
#include "proto.h"
#include <ipc/services.h>
#include "../../srv/vfs/vfs.h"
#include "../../srv/console/console.h"
#include <ipc/console.h>
 
#include "syscalls.h"
#include "ipcp.h"
444,10 → 447,20
thread_hash = (uintptr_t)thread_hash_arg;
thread_id = next_thread_id++;
 
printf("Start tracing thread [%d] (hash 0x%lx)\n", thread_id, thread_hash);
printf("Start tracing thread [%d] (hash 0x%lx).\n", thread_id, thread_hash);
 
while (!abort_trace) {
 
if (paused) {
printf("Press R to resume (and be patient).\n");
while (paused) {
usleep(1000000);
fibril_yield();
printf(".");
}
printf("Resumed\n");
}
 
/* Run thread until an event occurs */
rc = udebug_go(phoneid, thread_hash,
&ev_type, &val0, &val1);
468,23 → 481,16
break;
case UDEBUG_EVENT_STOP:
printf("Stop event\n");
printf("Waiting for resume\n");
while (paused) {
usleep(1000000);
fibril_yield();
printf(".");
}
printf("Resumed\n");
break;
case UDEBUG_EVENT_THREAD_B:
event_thread_b(val0);
break;
case UDEBUG_EVENT_THREAD_E:
printf("Thread 0x%lx exited\n", val0);
printf("Thread 0x%lx exited.\n", val0);
abort_trace = 1;
break;
default:
printf("Unknown event type %d\n", ev_type);
printf("Unknown event type %d.\n", ev_type);
break;
}
}
491,7 → 497,7
 
}
 
printf("Finished tracing thread [%d]\n", thread_id);
printf("Finished tracing thread [%d].\n", thread_id);
return 0;
}
 
515,7 → 521,7
int rc;
 
/* Spawn a program loader */
ldr = loader_spawn();
ldr = loader_connect();
if (ldr == NULL)
return 0;
 
579,6 → 585,7
c = getchar();
if (c == 'q') break;
if (c == 'p') {
printf("Pause...\n");
paused = 1;
rc = udebug_stop(phoneid, thash);
printf("stop -> %d\n", rc);
585,6 → 592,7
}
if (c == 'r') {
paused = 0;
printf("Resume...\n");
}
}
 
617,7 → 625,7
V_INTEGER,
V_INTEGER,
V_INTEGER,
V_INTEGER
V_INTEGER
};
 
next_thread_id = 1;
627,26 → 635,36
 
p = proto_new("vfs");
o = oper_new("read", 1, arg_def, V_ERRNO, 1, resp_def);
proto_add_oper(p, VFS_READ, o);
proto_add_oper(p, VFS_IN_READ, o);
o = oper_new("write", 1, arg_def, V_ERRNO, 1, resp_def);
proto_add_oper(p, VFS_WRITE, o);
proto_add_oper(p, VFS_IN_WRITE, o);
o = oper_new("truncate", 5, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_TRUNCATE, o);
proto_add_oper(p, VFS_IN_TRUNCATE, o);
o = oper_new("mount", 2, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_MOUNT, o);
proto_add_oper(p, VFS_IN_MOUNT, o);
/* o = oper_new("unmount", 0, arg_def);
proto_add_oper(p, VFS_UNMOUNT, o);*/
proto_add_oper(p, VFS_IN_UNMOUNT, o);*/
o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_OPEN, o);
o = oper_new("close", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_CLOSE, o);
o = oper_new("seek", 3, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_SEEK, o);
o = oper_new("mkdir", 1, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_MKDIR, o);
o = oper_new("unlink", 0, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_UNLINK, o);
o = oper_new("rename", 0, arg_def, V_ERRNO, 0, resp_def);
proto_add_oper(p, VFS_IN_RENAME, o);
 
proto_register(SERVICE_VFS, p);
 
p = proto_new("console");
resp_def[0] = V_CHAR;
o = oper_new("getchar", 0, arg_def, V_INTEGER, 2, resp_def);
proto_add_oper(p, CONSOLE_GETCHAR, o);
resp_def[0] = V_INTEGER; resp_def[1] = V_INTEGER;
resp_def[2] = V_INTEGER; resp_def[3] = V_CHAR;
o = oper_new("getkey", 0, arg_def, V_ERRNO, 4, resp_def);
 
arg_def[0] = V_CHAR;
o = oper_new("putchar", 1, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_PUTCHAR, o);
o = oper_new("clear", 0, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_CLEAR, o);
 
656,13 → 674,17
 
resp_def[0] = V_INTEGER; resp_def[1] = V_INTEGER;
o = oper_new("getsize", 0, arg_def, V_INTEGER, 2, resp_def);
proto_add_oper(p, CONSOLE_GETSIZE, o);
o = oper_new("flush", 0, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_FLUSH, o);
proto_add_oper(p, CONSOLE_GET_SIZE, o);
 
arg_def[0] = V_INTEGER;
o = oper_new("set_style", 1, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_SET_STYLE, o);
arg_def[0] = V_INTEGER; arg_def[1] = V_INTEGER; arg_def[2] = V_INTEGER;
o = oper_new("set_color", 3, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_SET_COLOR, o);
arg_def[0] = V_INTEGER; arg_def[1] = V_INTEGER;
o = oper_new("set_style", 2, arg_def, V_INTEGER, 0, resp_def);
proto_add_oper(p, CONSOLE_SET_STYLE, o);
o = oper_new("set_rgb_color", 2, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_SET_RGB_COLOR, o);
o = oper_new("cursor_visibility", 1, arg_def, V_VOID, 0, resp_def);
proto_add_oper(p, CONSOLE_CURSOR_VISIBILITY, o);
 
701,7 → 723,7
case 'i': dm = dm | DM_IPC; break;
case 'p': dm = dm | DM_SYSTEM | DM_USER; break;
default:
printf("Unexpected event type '%c'\n", *c);
printf("Unexpected event type '%c'.\n", *c);
exit(1);
}
 
776,6 → 798,7
int rc;
 
printf("System Call / IPC Tracer\n");
printf("Controls: Q - Quit, P - Pause, R - Resume\n");
 
display_mask = DM_THREAD | DM_SYSTEM | DM_USER;
 
786,11 → 809,11
 
rc = connect_task(task_id);
if (rc < 0) {
printf("Failed connecting to task %lld\n", task_id);
printf("Failed connecting to task %lld.\n", task_id);
return 1;
}
 
printf("Connected to task %lld\n", task_id);
printf("Connected to task %lld.\n", task_id);
 
if (task_ldr != NULL) {
program_run();
/branches/arm/uspace/app/trace/proto.c
35,7 → 35,7
#include <stdio.h>
#include <stdlib.h>
#include <ipc/ipc.h>
#include <libadt/hash_table.h>
#include <adt/hash_table.h>
 
#include "trace.h"
#include "proto.h"
/branches/arm/uspace/app/trace/proto.h
35,7 → 35,7
#ifndef PROTO_H_
#define PROTO_H_
 
#include <libadt/hash_table.h>
#include <adt/hash_table.h>
#include <ipc/ipc.h>
#include "trace.h"
 
/branches/arm/uspace/app/trace/ipcp.c
34,7 → 34,7
 
#include <stdio.h>
#include <stdlib.h>
#include <libadt/hash_table.h>
#include <adt/hash_table.h>
 
#include "ipc_desc.h"
#include "proto.h"
/branches/arm/uspace/app/trace/syscalls.c
59,11 → 59,14
[SYS_IPC_ANSWER_FAST] = { "ipc_answer_fast", 6, V_ERRNO },
[SYS_IPC_ANSWER_SLOW] = { "ipc_answer_slow", 2, V_ERRNO },
[SYS_IPC_FORWARD_FAST] = { "ipc_forward_fast", 6, V_ERRNO },
[SYS_IPC_FORWARD_SLOW] = { "ipc_forward_slow", 3, V_ERRNO },
[SYS_IPC_WAIT] = { "ipc_wait_for_call", 3, V_HASH },
[SYS_IPC_HANGUP] = { "ipc_hangup", 1, V_ERRNO },
[SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq", 4, V_ERRNO },
[SYS_IPC_UNREGISTER_IRQ] = { "ipc_unregister_irq", 2, V_ERRNO },
 
[SYS_EVENT_SUBSCRIBE] = { "event_subscribe", 2, V_ERRNO },
 
[SYS_CAP_GRANT] = { "cap_grant", 2, V_ERRNO },
[SYS_CAP_REVOKE] = { "cap_revoke", 2, V_ERRNO },
[SYS_PHYSMEM_MAP] = { "physmem_map", 4, V_ERRNO },
/branches/arm/uspace/app/trace/Makefile
31,6 → 31,7
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../srv/kbd/include
63,7 → 64,7
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
/branches/arm/uspace/app/klog/klog.c
27,9 → 27,9
*/
 
/** @addtogroup klog KLog
* @brief HelenOS KLog
* @brief HelenOS KLog
* @{
*/
*/
/**
* @file
*/
40,56 → 40,47
#include <ipc/services.h>
#include <as.h>
#include <sysinfo.h>
#include <io/stream.h>
#include <event.h>
#include <errno.h>
#include <io/klog.h>
 
#define NAME "klog"
#define NAME "klog"
 
#define KLOG_SIZE PAGE_SIZE
 
/* Pointer to klog area */
static char *klog;
static wchar_t *klog;
static size_t klog_length;
 
static void console_wait(void)
{
while (get_cons_phone() < 0)
usleep(50000); // FIXME
}
 
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
{
async_serialize_start();
size_t klog_start = (size_t) IPC_GET_ARG1(*call);
size_t klog_len = (size_t) IPC_GET_ARG2(*call);
size_t klog_stored = (size_t) IPC_GET_ARG3(*call);
size_t i;
for (i = klog_len - klog_stored; i < klog_len; i++)
putchar(klog[(klog_start + i) % KLOG_SIZE]);
async_serialize_end();
putchar(klog[(klog_start + i) % klog_length]);
}
 
int main(int argc, char *argv[])
{
console_wait();
size_t klog_pages = sysinfo_value("klog.pages");
size_t klog_size = klog_pages * PAGE_SIZE;
klog_length = klog_size / sizeof(wchar_t);
klog = (char *) as_get_mappable_page(KLOG_SIZE);
klog = (wchar_t *) as_get_mappable_page(klog_size);
if (klog == NULL) {
printf(NAME ": Error allocating memory area\n");
return -1;
}
int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog, KLOG_SIZE,
SERVICE_MEM_KLOG);
int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog,
klog_size, SERVICE_MEM_KLOG);
if (res != EOK) {
printf(NAME ": Error initializing memory area\n");
return -1;
}
 
int inr = sysinfo_value("klog.inr");
int devno = sysinfo_value("klog.devno");
if (ipc_register_irq(inr, devno, 0, NULL) != EOK) {
if (event_subscribe(EVENT_KLOG, 0) != EOK) {
printf(NAME ": Error registering klog notifications\n");
return -1;
}
97,7 → 88,7
async_set_interrupt_received(interrupt_received);
klog_update();
async_manager();
 
return 0;
}
 
/branches/arm/uspace/app/klog/Makefile
31,6 → 31,7
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
52,18 → 53,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/lib/libc/malloc/malloc.c
File deleted
/branches/arm/uspace/lib/libc/include/libadt/hash_table.h
File deleted
/branches/arm/uspace/lib/libc/include/libadt/list.h
File deleted
/branches/arm/uspace/lib/libc/include/libadt/fifo.h
File deleted
/branches/arm/uspace/lib/libc/include/io/io.h
File deleted
/branches/arm/uspace/lib/libc/include/io/stream.h
File deleted
/branches/arm/uspace/lib/libc/include/io/console.h
0,0 → 1,86
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_CONSOLE_H_
#define LIBC_IO_CONSOLE_H_
 
#include <ipc/ipc.h>
#include <bool.h>
 
typedef enum {
KEY_PRESS,
KEY_RELEASE
} console_ev_type_t;
 
enum {
CONSOLE_CCAP_NONE = 0,
CONSOLE_CCAP_STYLE,
CONSOLE_CCAP_INDEXED,
CONSOLE_CCAP_RGB
};
 
/** Console event structure. */
typedef struct {
/** Press or release event. */
console_ev_type_t type;
/** Keycode of the key that was pressed or released. */
unsigned int key;
/** Bitmask of modifiers held. */
unsigned int mods;
/** The character that was generated or '\0' for none. */
wchar_t c;
} console_event_t;
 
extern void console_clear(int phone);
 
extern int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols);
extern void console_goto(int phone, ipcarg_t row, ipcarg_t col);
 
extern void console_set_style(int phone, int style);
extern void console_set_color(int phone, int fg_color, int bg_color, int flags);
extern void console_set_rgb_color(int phone, int fg_color, int bg_color);
 
extern void console_cursor_visibility(int phone, bool show);
extern int console_get_color_cap(int phone, int *ccap);
extern void console_kcon_enable(int phone);
 
extern bool console_get_event(int phone, console_event_t *event);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/io/printf_core.h
39,19 → 39,20
#include <stdarg.h>
 
/** Structure for specifying output methods for different printf clones. */
struct printf_spec {
/* Output function, returns count of printed characters or EOF */
int (*write)(void *, size_t, void *);
/* Support data - output stream specification, its state, locks,... */
typedef struct printf_spec {
/* String output function, returns number of printed characters or EOF */
int (*str_write)(const char *, size_t, void *);
/* Wide string output function, returns number of printed characters or EOF */
int (*wstr_write)(const wchar_t *, size_t, void *);
/* User data - output stream specification, state, locks, etc. */
void *data;
} printf_spec_t;
 
};
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
 
int printf_core(const char *fmt, struct printf_spec *ps ,va_list ap);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/io/klog.h
0,0 → 1,46
/*
* Copyright (c) 2006 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_STREAM_H_
#define LIBC_STREAM_H_
 
#include <sys/types.h>
 
extern size_t klog_write(const void *buf, size_t size);
extern void klog_update(void);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/io/color.h
0,0 → 1,55
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_COLOR_H_
#define LIBC_IO_COLOR_H_
 
enum console_color {
COLOR_BLACK = 0,
COLOR_BLUE = 1,
COLOR_GREEN = 2,
COLOR_CYAN = 3,
COLOR_RED = 4,
COLOR_MAGENTA = 5,
COLOR_YELLOW = 6,
COLOR_WHITE = 7,
CATTR_BRIGHT = 8,
CATTR_BLINK = 8
};
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/io/style.h
0,0 → 1,46
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_STYLE_H_
#define LIBC_IO_STYLE_H_
 
enum console_style {
STYLE_NORMAL = 0,
STYLE_EMPHASIS = 1
};
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/io/keycode.h
0,0 → 1,220
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_KEYCODE_H_
#define LIBC_IO_KEYCODE_H_
 
/** Keycode definitions.
*
* A keycode identifies a key by its position on the keyboard, rather
* than by its label. For human readability, key positions are noted
* with the key label on a keyboard with US layout. This label has
* nothing to do with the character, that the key produces
* -- this is determined by the keymap.
*
* The keyboard model reflects a standard PC keyboard layout.
* Non-standard keyboards need to be mapped to this model in some
* logical way. Scancodes are mapped to keycodes with a scanmap.
*
* For easier mapping to the model and to emphasize the nature of keycodes,
* they really are organized here by position, rather than by label.
*/
enum keycode {
 
/* Main block row 1 */
 
KC_BACKTICK = 1,
 
KC_1,
KC_2,
KC_3,
KC_4,
KC_5,
KC_6,
KC_7,
KC_8,
KC_9,
KC_0,
 
KC_MINUS,
KC_EQUALS,
KC_BACKSPACE,
 
/* Main block row 2 */
 
KC_TAB,
 
KC_Q,
KC_W,
KC_E,
KC_R,
KC_T,
KC_Y,
KC_U,
KC_I,
KC_O,
KC_P,
 
KC_LBRACKET,
KC_RBRACKET,
 
/* Main block row 3 */
 
KC_CAPS_LOCK,
KC_A,
KC_S,
KC_D,
KC_F,
KC_G,
KC_H,
KC_J,
KC_K,
KC_L,
 
KC_SEMICOLON,
KC_QUOTE,
KC_BACKSLASH,
 
KC_ENTER,
 
/* Main block row 4 */
 
KC_LSHIFT,
 
KC_Z,
KC_X,
KC_C,
KC_V,
KC_B,
KC_N,
KC_M,
 
KC_COMMA,
KC_PERIOD,
KC_SLASH,
 
KC_RSHIFT,
 
/* Main block row 5 */
 
KC_LCTRL,
KC_LALT,
KC_SPACE,
KC_RALT,
KC_RCTRL,
 
/* Function keys block */
 
KC_ESCAPE,
 
KC_F1,
KC_F2,
KC_F3,
KC_F4,
KC_F5,
KC_F6,
KC_F7,
KC_F8,
KC_F9,
KC_F10,
KC_F11,
KC_F12,
 
KC_PRTSCR,
KC_SCROLL_LOCK,
KC_PAUSE,
 
/* Cursor keys block */
 
KC_INSERT,
KC_HOME,
KC_PAGE_UP,
 
KC_DELETE,
KC_END,
KC_PAGE_DOWN,
 
KC_UP,
KC_LEFT,
KC_DOWN,
KC_RIGHT,
 
/* Numeric block */
 
KC_NUM_LOCK,
KC_NSLASH,
KC_NTIMES,
KC_NMINUS,
 
KC_NPLUS,
KC_NENTER,
 
KC_N7,
KC_N8,
KC_N9,
 
KC_N4,
KC_N5,
KC_N6,
 
KC_N1,
KC_N2,
KC_N3,
 
KC_N0,
KC_NPERIOD
} keycode_t;
 
enum keymod {
KM_LSHIFT = 0x001,
KM_RSHIFT = 0x002,
KM_LCTRL = 0x004,
KM_RCTRL = 0x008,
KM_LALT = 0x010,
KM_RALT = 0x020,
KM_CAPS_LOCK = 0x040,
KM_NUM_LOCK = 0x080,
KM_SCROLL_LOCK = 0x100,
KM_SHIFT = KM_LSHIFT | KM_RSHIFT,
KM_CTRL = KM_LCTRL | KM_RCTRL,
KM_ALT = KM_LALT | KM_RALT
} keymod_t;
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/ipc/console.h
0,0 → 1,57
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libcipc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IPC_CONSOLE_H_
#define LIBC_IPC_CONSOLE_H_
 
#include <ipc/ipc.h>
#include <ipc/vfs.h>
 
typedef enum {
CONSOLE_GET_SIZE = VFS_OUT_LAST,
CONSOLE_GET_COLOR_CAP,
CONSOLE_GET_EVENT,
CONSOLE_GOTO,
CONSOLE_CLEAR,
CONSOLE_SET_STYLE,
CONSOLE_SET_COLOR,
CONSOLE_SET_RGB_COLOR,
CONSOLE_CURSOR_VISIBILITY,
CONSOLE_KCON_ENABLE
} console_request_t;
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/lib/libc/include/ipc/fb.h
41,6 → 41,7
FB_PUTCHAR = IPC_FIRST_USER_METHOD,
FB_CLEAR,
FB_GET_CSIZE,
FB_GET_COLOR_CAP,
FB_CURSOR_VISIBILITY,
FB_CURSOR_GOTO,
FB_SCROLL,
48,10 → 49,11
FB_VIEWPORT_CREATE,
FB_VIEWPORT_DELETE,
FB_SET_STYLE,
FB_SET_COLOR,
FB_SET_RGB_COLOR,
FB_GET_RESOLUTION,
FB_DRAW_TEXT_DATA,
FB_FLUSH,
FB_VIEWPORT_DB,
FB_DRAW_PPM,
FB_PREPARE_SHM,
FB_DROP_SHM,
59,7 → 61,6
FB_VP_DRAW_PIXMAP,
FB_VP2PIXMAP,
FB_DROP_PIXMAP,
FB_TRANS_PUTCHAR,
FB_ANIM_CREATE,
FB_ANIM_DROP,
FB_ANIM_ADDPIXMAP,
66,9 → 67,17
FB_ANIM_CHGVP,
FB_ANIM_START,
FB_ANIM_STOP,
FB_POINTER_MOVE
FB_POINTER_MOVE,
FB_SCREEN_YIELD,
FB_SCREEN_RECLAIM
} fb_request_t;
 
enum {
FB_CCAP_NONE = 0,
FB_CCAP_STYLE,
FB_CCAP_INDEXED,
FB_CCAP_RGB
};
 
#endif
 
/branches/arm/uspace/lib/libc/include/ipc/ns.h
35,6 → 35,15
#ifndef LIBIPC_NS_H_
#define LIBIPC_NS_H_
 
#include <ipc/ipc.h>
 
typedef enum {
NS_PING = IPC_FIRST_USER_METHOD,
NS_TASK_WAIT,
NS_ID_INTRO,
NS_RETVAL
} ns_request_t;
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/ipc/vfs.h
0,0 → 1,151
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libcipc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IPC_VFS_H_
#define LIBC_IPC_VFS_H_
 
#include <sys/types.h>
#include <ipc/ipc.h>
 
#define FS_NAME_MAXLEN 20
#define MAX_PATH_LEN (64 * 1024)
#define PLB_SIZE (2 * MAX_PATH_LEN)
 
/* Basic types. */
typedef int16_t fs_handle_t;
typedef uint32_t fs_index_t;
 
/**
* A structure like this is passed to VFS by each individual FS upon its
* registration. It assosiates a human-readable identifier with each
* registered FS.
*/
typedef struct {
/** Unique identifier of the fs. */
char name[FS_NAME_MAXLEN + 1];
} vfs_info_t;
 
typedef enum {
VFS_IN_OPEN = IPC_FIRST_USER_METHOD,
VFS_IN_OPEN_NODE,
VFS_IN_READ,
VFS_IN_WRITE,
VFS_IN_SEEK,
VFS_IN_TRUNCATE,
VFS_IN_FSTAT,
VFS_IN_CLOSE,
VFS_IN_MOUNT,
VFS_IN_UNMOUNT,
VFS_IN_SYNC,
VFS_IN_REGISTER,
VFS_IN_MKDIR,
VFS_IN_UNLINK,
VFS_IN_RENAME,
VFS_IN_STAT
} vfs_in_request_t;
 
typedef enum {
VFS_OUT_OPEN_NODE = IPC_FIRST_USER_METHOD,
VFS_OUT_READ,
VFS_OUT_WRITE,
VFS_OUT_TRUNCATE,
VFS_OUT_CLOSE,
VFS_OUT_MOUNT,
VFS_OUT_MOUNTED,
VFS_OUT_UNMOUNT,
VFS_OUT_SYNC,
VFS_OUT_STAT,
VFS_OUT_LOOKUP,
VFS_OUT_DESTROY,
VFS_OUT_LAST
} vfs_out_request_t;
 
/*
* Lookup flags.
*/
 
/**
* No lookup flags used.
*/
#define L_NONE 0
 
/**
* Lookup will succeed only if the object is a regular file. If L_CREATE is
* specified, an empty file will be created. This flag is mutually exclusive
* with L_DIRECTORY.
*/
#define L_FILE 1
 
/**
* Lookup wil succeed only if the object is a directory. If L_CREATE is
* specified, an empty directory will be created. This flag is mutually
* exclusive with L_FILE.
*/
#define L_DIRECTORY 2
 
/**
* When used with L_CREATE, L_EXCLUSIVE will cause the lookup to fail if the
* object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
*/
#define L_EXCLUSIVE 4
 
/**
* L_CREATE is used for creating both regular files and directories.
*/
#define L_CREATE 8
 
/**
* L_LINK is used for linking to an already existing nodes.
*/
#define L_LINK 16
 
/**
* L_UNLINK is used to remove leaves from the file system namespace. This flag
* cannot be passed directly by the client, but will be set by VFS during
* VFS_UNLINK.
*/
#define L_UNLINK 32
 
/**
* L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN
* call from the client. This means that the server might allocate some
* resources for the opened file. This flag cannot be passed directly by the
* client.
*/
#define L_OPEN 64
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/ipc/devmap.h
28,16 → 28,19
 
/** @addtogroup devmap
* @{
*/
*/
 
#ifndef DEVMAP_DEVMAP_H_
#define DEVMAP_DEVMAP_H_
 
#include <atomic.h>
#include <ipc/ipc.h>
#include <libadt/list.h>
#include <adt/list.h>
 
#define DEVMAP_NAME_MAXLEN 512
#define DEVMAP_NAME_MAXLEN 255
 
typedef ipcarg_t dev_handle_t;
 
typedef enum {
DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
DEVMAP_DRIVER_UNREGISTER,
44,56 → 47,32
DEVMAP_DEVICE_REGISTER,
DEVMAP_DEVICE_UNREGISTER,
DEVMAP_DEVICE_GET_NAME,
DEVMAP_DEVICE_GET_HANDLE
DEVMAP_DEVICE_GET_HANDLE,
DEVMAP_DEVICE_NULL_CREATE,
DEVMAP_DEVICE_NULL_DESTROY,
DEVMAP_DEVICE_GET_COUNT,
DEVMAP_DEVICE_GET_DEVICES
} devmap_request_t;
 
/** Representation of device driver.
* Each driver is responsible for a set of devices.
*/
typedef struct {
/** Pointers to previous and next drivers in linked list */
link_t drivers;
/** Pointer to the linked list of devices controlled by
* this driver */
link_t devices;
/** Phone asociated with this driver */
ipcarg_t phone;
/** Device driver name */
char *name;
/** Futex for list of devices owned by this driver */
atomic_t devices_futex;
} devmap_driver_t;
 
/** Info about registered device
/** Interface provided by devmap.
*
*/
typedef struct {
/** Pointer to the previous and next device in the list of all devices */
link_t devices;
/** Pointer to the previous and next device in the list of devices
owned by one driver */
link_t driver_devices;
/** Unique device identifier */
int handle;
/** Device name */
char *name;
/** Device driver handling this device */
devmap_driver_t *driver;
} devmap_device_t;
 
/** Interface provided by devmap.
* Every process that connects to devmap must ask one of following
* interfaces otherwise connection will be refused.
*
*/
typedef enum {
/** Connect as device driver */
DEVMAP_DRIVER = 1,
/** Connect as client */
/** Connect as device driver */
DEVMAP_DRIVER = 1,
/** Connect as client */
DEVMAP_CLIENT,
/** Create new connection to instance of device that
* is specified by second argument of call. */
/** Create new connection to instance of device that
is specified by second argument of call. */
DEVMAP_CONNECT_TO_DEVICE
} devmap_interface_t;
 
typedef struct {
dev_handle_t handle;
char name[DEVMAP_NAME_MAXLEN + 1];
} dev_desc_t;
 
#endif
 
/branches/arm/uspace/lib/libc/include/ipc/ipc.h
30,25 → 30,29
* @{
*/
/** @file
*/
*/
 
#ifndef LIBIPC_IPC_H_
#define LIBIPC_IPC_H_
 
#include <task.h>
#include <kernel/ipc/ipc.h>
#include <kernel/ddi/irq.h>
#include <sys/types.h>
#include <kernel/synch/synch.h>
 
#define IPC_FLAG_BLOCKING 0x01
 
typedef sysarg_t ipcarg_t;
 
typedef struct {
ipcarg_t args[IPC_CALL_LEN];
ipcarg_t in_phone_hash;
} ipc_call_t;
 
typedef sysarg_t ipc_callid_t;
 
typedef void (* ipc_async_callback_t)(void *private, int retval,
ipc_call_t *data);
typedef void (* ipc_async_callback_t)(void *, int, ipc_call_t *);
 
/*
* User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow().
57,49 → 61,51
* possible, the fast version is used.
*/
#define ipc_call_sync_0_0(phoneid, method) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
#define ipc_call_sync_0_1(phoneid, method, res1) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
#define ipc_call_sync_0_2(phoneid, method, res1, res2) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
#define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
0, 0)
#define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), 0)
#define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), (res5))
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), (res5))
 
#define ipc_call_sync_1_0(phoneid, method, arg1) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
#define ipc_call_sync_1_1(phoneid, method, arg1, res1) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
#define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
0, 0)
#define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), 0, 0)
#define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), (res4), 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), (res4), 0)
#define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \
res5) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), (res4), (res5))
 
#define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
0, 0)
#define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
0, 0)
#define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), 0, 0, 0)
#define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), (res3), 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), (res3), 0, 0)
#define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \
res4) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
108,15 → 114,16
res4, res5)\
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), (res3), (res4), (res5))
 
#define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
0, 0)
#define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
0, 0, 0, 0)
#define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
(res2), 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
(res2), 0, 0, 0)
#define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \
res3) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
129,15 → 136,16
res3, res4, res5) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
(res1), (res2), (res3), (res4), (res5))
 
#define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
0, 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
0, 0, 0, 0, 0)
#define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), 0, 0, 0, 0)
#define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), (res2), 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), (res2), 0, 0, 0)
#define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
res3) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
150,12 → 158,13
res3, res4, res5) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
(arg4), 0, (res1), (res2), (res3), (res4), (res5))
 
#define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), 0, 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), 0, 0, 0, 0, 0)
#define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (res1), 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (res1), 0, 0, 0, 0)
#define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
res2) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
173,23 → 182,23
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
(arg4), (arg5), (res1), (res2), (res3), (res4), (res5))
 
extern int ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2,
ipcarg_t *result3, ipcarg_t *result4, ipcarg_t *result5);
extern int ipc_call_sync_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *);
 
extern int ipc_call_sync_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3, ipcarg_t *result4,
ipcarg_t *result5);
extern int ipc_call_sync_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t, ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *,
ipcarg_t *);
 
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags);
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *data, uint32_t usec);
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int);
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t);
 
static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
{
return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);
}
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *data);
 
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *);
 
/*
* User-friendly wrappers for ipc_answer_fast() and ipc_answer_slow().
* They are in the form of ipc_answer_m(), where m is the number of return
197,22 → 206,22
* to m.
*/
#define ipc_answer_0(callid, retval) \
ipc_answer_fast((callid), (retval), 0, 0, 0, 0)
ipc_answer_fast((callid), (retval), 0, 0, 0, 0)
#define ipc_answer_1(callid, retval, arg1) \
ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0)
ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0)
#define ipc_answer_2(callid, retval, arg1, arg2) \
ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0)
ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0)
#define ipc_answer_3(callid, retval, arg1, arg2, arg3) \
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0)
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0)
#define ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4) \
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4))
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4))
#define ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5) \
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5))
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5))
 
extern ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval,
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4);
extern ipcarg_t ipc_answer_slow(ipc_callid_t callid, ipcarg_t retval,
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5);
extern ipcarg_t ipc_answer_fast(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t);
extern ipcarg_t ipc_answer_slow(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t, ipcarg_t);
 
/*
* User-friendly wrappers for ipc_call_async_fast() and ipc_call_async_slow().
220,8 → 229,7
* arguments. The macros decide between the fast and the slow version according
* to m.
*/
#define ipc_call_async_0(phoneid, method, private, callback, \
can_preempt) \
#define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \
ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \
(callback), (can_preempt))
#define ipc_call_async_1(phoneid, method, arg1, private, callback, \
245,53 → 253,48
ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \
(arg4), (arg5), (private), (callback), (can_preempt))
 
extern void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private,
ipc_async_callback_t callback, int can_preempt);
extern void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private,
ipc_async_callback_t callback, int can_preempt);
extern void ipc_call_async_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, void *, ipc_async_callback_t, int);
extern void ipc_call_async_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t, void *, ipc_async_callback_t, int);
 
extern int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
ipcarg_t *phone);
extern int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3);
extern int ipc_hangup(int phoneid);
extern int ipc_register_irq(int inr, int devno, int method, irq_code_t *code);
extern int ipc_unregister_irq(int inr, int devno);
extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method,
ipcarg_t arg1, ipcarg_t arg2, int mode);
extern int ipc_connect_to_me(int, int, int, int, ipcarg_t *);
extern int ipc_connect_me_to(int, int, int, int);
extern int ipc_connect_me_to_blocking(int, int, int, int);
extern int ipc_hangup(int);
extern int ipc_register_irq(int, int, int, irq_code_t *);
extern int ipc_unregister_irq(int, int);
extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int);
extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t, ipcarg_t, int);
 
 
/*
* User-friendly wrappers for ipc_share_in_start().
*/
#define ipc_share_in_start_0_0(phoneid, dst, size) \
ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
#define ipc_share_in_start_0_1(phoneid, dst, size, flags) \
ipc_share_in_start((phoneid), (dst), (size), 0, (flags))
ipc_share_in_start((phoneid), (dst), (size), 0, (flags))
#define ipc_share_in_start_1_0(phoneid, dst, size, arg) \
ipc_share_in_start((phoneid), (dst), (size), (arg), NULL)
ipc_share_in_start((phoneid), (dst), (size), (arg), NULL)
#define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
 
extern int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,
int *flags);
extern int ipc_share_in_receive(ipc_callid_t *callid, size_t *size);
extern int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags);
extern int ipc_share_out_start(int phoneid, void *src, int flags);
extern int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags);
extern int ipc_share_out_finalize(ipc_callid_t callid, void *dst);
extern int ipc_data_read_start(int phoneid, void *dst, size_t size);
extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size);
extern int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size);
extern int ipc_data_write_start(int phoneid, void *src, size_t size);
extern int ipc_data_write_receive(ipc_callid_t *callid, size_t *size);
extern int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size);
extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *);
extern int ipc_share_in_receive(ipc_callid_t *, size_t *);
extern int ipc_share_in_finalize(ipc_callid_t, void *, int );
extern int ipc_share_out_start(int, void *, int);
extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *);
extern int ipc_share_out_finalize(ipc_callid_t, void *);
extern int ipc_data_read_start(int, void *, size_t);
extern int ipc_data_read_receive(ipc_callid_t *, size_t *);
extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
extern int ipc_data_write_start(int, const void *, size_t);
extern int ipc_data_write_receive(ipc_callid_t *, size_t *);
extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
 
#include <task.h>
extern int ipc_connect_kbox(task_id_t);
 
extern int ipc_connect_kbox(task_id_t id);
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/ipc/loader.h
42,9 → 42,10
LOADER_GET_TASKID,
LOADER_SET_PATHNAME,
LOADER_SET_ARGS,
LOADER_SET_FILES,
LOADER_LOAD,
LOADER_RUN
} fb_request_t;
} loader_request_t;
 
#endif
 
/branches/arm/uspace/lib/libc/include/ipc/bd.h
0,0 → 1,48
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libcipc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IPC_BD_H_
#define LIBC_IPC_BD_H_
 
#include <ipc/ipc.h>
 
typedef enum {
BD_READ_BLOCK = IPC_FIRST_USER_METHOD,
BD_WRITE_BLOCK
} bd_request_t;
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/ipc/services.h
30,8 → 30,8
* @{
*/
/**
* @file services.h
* @brief List of all known services and their codes.
* @file services.h
* @brief List of all known services and their codes.
*/
 
#ifndef LIBIPC_SERVICES_H_
38,12 → 38,15
#define LIBIPC_SERVICES_H_
 
typedef enum {
SERVICE_PCI = 1,
SERVICE_LOAD = 1,
SERVICE_PCI,
SERVICE_KEYBOARD,
SERVICE_VIDEO,
SERVICE_CONSOLE,
SERVICE_VFS,
SERVICE_DEVMAP
SERVICE_DEVMAP,
SERVICE_FHC,
SERVICE_OBIO
} services_t;
 
/* Memory area to be received from NS */
/branches/arm/uspace/lib/libc/include/ipc/bus.h
0,0 → 1,47
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libcipc
* @{
*/
/** @file
*/
 
#ifndef LIBC_BUS_H_
#define LIBC_BUS_H_
 
#include <ipc/ipc.h>
 
typedef enum {
BUS_CLEAR_INTERRUPT = IPC_FIRST_USER_METHOD
} bus_request_t;
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/fibril.h
36,17 → 36,18
#define LIBC_FIBRIL_H_
 
#include <libarch/fibril.h>
#include <libadt/list.h>
#include <adt/list.h>
#include <libarch/tls.h>
 
#ifndef context_set
#define context_set(c, _pc, stack, size, ptls) \
(c)->pc = (sysarg_t) (_pc); \
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
(c)->tls = (sysarg_t) (ptls);
#define context_set(c, _pc, stack, size, ptls) \
(c)->pc = (sysarg_t) (_pc); \
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
(c)->tls = (sysarg_t) (ptls);
#endif /* context_set */
 
#define FIBRIL_SERIALIZED 1
#define FIBRIL_SERIALIZED 1
#define FIBRIL_WRITER 2
 
typedef enum {
FIBRIL_PREEMPT,
71,7 → 72,10
};
typedef struct fibril fibril_t;
 
extern int context_save(context_t *c);
/** Fibril-local variable specifier */
#define fibril_local __thread
 
extern int context_save(context_t *c) __attribute__ ((returns_twice));
extern void context_restore(context_t *c) __attribute__ ((noreturn));
 
extern fid_t fibril_create(int (*func)(void *), void *arg);
/branches/arm/uspace/lib/libc/include/task.h
39,9 → 39,18
 
typedef uint64_t task_id_t;
 
typedef enum {
TASK_EXIT_NORMAL,
TASK_EXIT_UNEXPECTED
} task_exit_t;
 
extern task_id_t task_get_id(void);
extern int task_set_name(const char *name);
extern task_id_t task_spawn(const char *path, char *const argv[]);
extern int task_wait(task_id_t id, task_exit_t *texit, int *retval);
extern int task_retval(int val);
 
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/getopt.h
58,7 → 58,7
};
 
/* HelenOS Port - These need to be exposed for legacy getopt() */
extern char *optarg;
extern const char *optarg;
extern int optind, opterr, optopt;
extern int optreset;
 
/branches/arm/uspace/lib/libc/include/vfs/vfs.h
36,11 → 36,36
#define LIBC_VFS_H_
 
#include <sys/types.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
#include <stdio.h>
 
/**
* This type is a libc version of the VFS triplet.
* It uniquelly identifies a file system node within a file system instance.
*/
typedef struct {
fs_handle_t fs_handle;
dev_handle_t dev_handle;
fs_index_t index;
} fdi_node_t;
 
extern char *absolutize(const char *, size_t *);
 
extern int mount(const char *, const char *, const char *);
extern int mount(const char *, const char *, const char *, const char *,
unsigned int);
 
extern void __stdio_init(int filc, fdi_node_t *filv[]);
extern void __stdio_done(void);
 
extern int open_node(fdi_node_t *, int);
extern int fd_phone(int);
extern int fd_node(int, fdi_node_t *);
 
extern FILE *fopen_node(fdi_node_t *, const char *);
extern int fphone(FILE *);
extern int fnode(FILE *, fdi_node_t *);
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/async.h
44,17 → 44,21
typedef ipc_callid_t aid_t;
typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
 
static inline void async_manager(void)
{
fibril_switch(FIBRIL_TO_MANAGER);
}
extern atomic_t async_futex;
 
ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
extern int __async_init(void);
extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
 
static inline ipc_callid_t async_get_call(ipc_call_t *data)
{
return async_get_call_timeout(data, 0);
}
 
static inline void async_manager(void)
{
fibril_switch(FIBRIL_TO_MANAGER);
}
 
/*
* User-friendly wrappers for async_send_fast() and async_send_slow(). The
* macros are in the form async_send_m(), where m denotes the number of payload
63,20 → 67,20
*/
 
#define async_send_0(phoneid, method, dataptr) \
async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
#define async_send_1(phoneid, method, arg1, dataptr) \
async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
#define async_send_2(phoneid, method, arg1, arg2, dataptr) \
async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
#define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
#define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(dataptr))
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(dataptr))
#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (dataptr))
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (dataptr))
 
extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr);
extern aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
86,12 → 90,11
extern int async_wait_timeout(aid_t amsgid, ipcarg_t *retval,
suseconds_t timeout);
 
fid_t async_new_connection(ipcarg_t in_phone_hash,ipc_callid_t callid,
ipc_call_t *call, void (*cthread)(ipc_callid_t,ipc_call_t *));
void async_usleep(suseconds_t timeout);
void async_create_manager(void);
void async_destroy_manager(void);
int _async_init(void);
extern fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *));
extern void async_usleep(suseconds_t timeout);
extern void async_create_manager(void);
extern void async_destroy_manager(void);
 
extern void async_set_client_connection(async_client_conn_t conn);
extern void async_set_interrupt_received(async_client_conn_t conn);
98,114 → 101,114
 
/* Wrappers for simple communication */
#define async_msg_0(phone, method) \
ipc_call_async_0((phone), (method), NULL, NULL, !in_interrupt_handler())
ipc_call_async_0((phone), (method), NULL, NULL, true)
#define async_msg_1(phone, method, arg1) \
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
!in_interrupt_handler())
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
true)
#define async_msg_2(phone, method, arg1, arg2) \
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
!in_interrupt_handler())
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
true)
#define async_msg_3(phone, method, arg1, arg2, arg3) \
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
!in_interrupt_handler())
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
true)
#define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, !in_interrupt_handler())
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, true)
#define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, !in_interrupt_handler())
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, true)
 
/*
* User-friendly wrappers for async_req_fast() and async_req_slow(). The macros
* are in the form async_req_m_n(), where m is the number of payload arguments
* and n is the number of return arguments. The macros decidce between the fast
* and n is the number of return arguments. The macros decide between the fast
* and slow verion based on m.
*/
#define async_req_0_0(phoneid, method) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
NULL)
#define async_req_0_1(phoneid, method, r1) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
NULL)
#define async_req_0_2(phoneid, method, r1, r2) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
NULL)
#define async_req_0_3(phoneid, method, r1, r2, r3) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
NULL)
#define async_req_0_4(phoneid, method, r1, r2, r3, r4) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
NULL)
#define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
(r5))
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
(r5))
#define async_req_1_0(phoneid, method, arg1) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
NULL, NULL)
#define async_req_1_1(phoneid, method, arg1, rc1) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
NULL, NULL)
#define async_req_1_2(phoneid, method, arg1, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
NULL, NULL)
#define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
NULL, NULL)
#define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), NULL)
#define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), (rc5))
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), (rc5))
#define async_req_2_0(phoneid, method, arg1, arg2) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
NULL, NULL, NULL)
#define async_req_2_1(phoneid, method, arg1, arg2, rc1) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
NULL, NULL, NULL)
#define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
NULL, NULL, NULL)
#define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), NULL, NULL)
#define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), NULL)
#define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), (rc5))
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), (rc5))
#define async_req_3_0(phoneid, method, arg1, arg2, arg3) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
NULL, NULL, NULL)
#define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
NULL, NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
NULL, NULL, NULL, NULL)
#define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), NULL, NULL, NULL)
#define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), NULL, NULL)
#define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), (rc4), NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), (rc4), NULL)
#define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
rc5) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), (rc4), (rc5))
#define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, NULL, NULL, NULL)
#define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
NULL, NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
NULL, NULL, NULL, NULL)
#define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), NULL, NULL, NULL)
#define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), (rc3), NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), (rc3), NULL, NULL)
#define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
rc4) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
215,14 → 218,14
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(rc1), (rc2), (rc3), (rc4), (rc5))
#define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, NULL, NULL, NULL)
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, NULL, NULL, NULL)
#define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), NULL, NULL, NULL, NULL)
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), NULL, NULL, NULL, NULL)
#define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), (rc2), NULL, NULL, NULL)
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), (rc2), NULL, NULL, NULL)
#define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
rc3) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
253,10 → 256,6
fibril_dec_sercount();
}
 
extern bool in_interrupt_handler(void);
 
extern atomic_t async_futex;
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/stdlib.h
38,10 → 38,10
#include <unistd.h>
#include <malloc.h>
 
#define abort() _exit(1)
#define exit(status) _exit((status))
#define abort() _exit(1)
#define exit(status) _exit((status))
 
#define RAND_MAX 714025
#define RAND_MAX 714025
 
extern long int random(void);
extern void srandom(unsigned int seed);
50,6 → 50,7
{
return random();
}
 
static inline void srand(unsigned int seed)
{
srandom(seed);
/branches/arm/uspace/lib/libc/include/stdio.h
37,37 → 37,115
 
#include <sys/types.h>
#include <stdarg.h>
#include <string.h>
#include <adt/list.h>
 
#define EOF (-1)
#define EOF (-1)
 
#include <string.h>
#include <io/stream.h>
/** Default size for stream I/O buffers */
#define BUFSIZ 4096
 
#define DEBUG(fmt, ...) \
{ \
char buf[256]; \
int n; \
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \
if (n > 0) \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, strlen(buf)); \
}
{ \
char _buf[256]; \
int _n = snprintf(_buf, sizeof(_buf), fmt, ##__VA_ARGS__); \
if (_n > 0) \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) _buf, str_size(_buf)); \
}
 
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
 
enum _buffer_type {
/** No buffering */
_IONBF,
/** Line buffering */
_IOLBF,
/** Full buffering */
_IOFBF
};
 
typedef struct {
/** Linked list pointer. */
link_t link;
/** Underlying file descriptor. */
int fd;
/** Error indicator. */
int error;
/** End-of-file indicator. */
int eof;
/** Klog indicator */
int klog;
/** Phone to the file provider */
int phone;
 
/** Buffering type */
enum _buffer_type btype;
/** Buffer */
uint8_t *buf;
/** Buffer size */
size_t buf_size;
/** Buffer I/O pointer */
uint8_t *buf_head;
} FILE;
 
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
 
/* Character and string input functions */
extern int fgetc(FILE *);
extern char *fgets(char *, size_t, FILE *);
 
extern int getchar(void);
extern char *gets(char *, size_t);
 
/* Character and string output functions */
extern int fputc(wchar_t, FILE *);
extern int fputs(const char *, FILE *);
 
extern int putchar(wchar_t);
extern int puts(const char *);
extern int putchar(int);
 
/* Formatted string output functions */
extern int fprintf(FILE *, const char*, ...);
extern int vfprintf(FILE *, const char *, va_list);
 
extern int printf(const char *, ...);
extern int vprintf(const char *, va_list);
 
extern int snprintf(char *, size_t , const char *, ...);
extern int asprintf(char **, const char *, ...);
extern int sprintf(char *, const char *fmt, ...);
extern int snprintf(char *, size_t , const char *, ...);
 
extern int vprintf(const char *, va_list);
extern int vsprintf(char *, const char *, va_list);
extern int vsnprintf(char *, size_t, const char *, va_list);
 
#define fprintf(f, fmt, ...) printf(fmt, ##__VA_ARGS__)
/* File stream functions */
extern FILE *fopen(const char *, const char *);
extern FILE *fdopen(int, const char *);
extern int fclose(FILE *);
 
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
 
extern int fseek(FILE *, long, int);
extern void rewind(FILE *);
extern int ftell(FILE *);
extern int feof(FILE *);
 
extern int fflush(FILE *);
extern int ferror(FILE *);
extern void clearerr(FILE *);
 
extern void setvbuf(FILE *, void *, int, size_t);
 
/* Misc file functions */
extern int rename(const char *, const char *);
 
#endif
/branches/arm/uspace/lib/libc/include/bitops.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
42,10 → 42,10
*
* If number is zero, it returns 0
*/
static inline int fnzb32(uint32_t arg)
static inline unsigned int fnzb32(uint32_t arg)
{
int n = 0;
 
unsigned int n = 0;
if (arg >> 16) {
arg >>= 16;
n += 16;
74,19 → 74,22
return n;
}
 
static inline int fnzb64(uint64_t arg)
static inline unsigned int fnzb64(uint64_t arg)
{
int n = 0;
 
unsigned int n = 0;
if (arg >> 32) {
arg >>= 32;
n += 32;
}
return n + fnzb32((uint32_t) arg);
return (n + fnzb32((uint32_t) arg));
}
 
#define fnzb(x) fnzb32(x)
static inline unsigned int fnzb(size_t arg)
{
return fnzb64(arg);
}
 
#endif
 
/branches/arm/uspace/lib/libc/include/unistd.h
39,27 → 39,32
#include <libarch/config.h>
 
#ifndef NULL
#define NULL 0
#define NULL 0
#endif
 
#define getpagesize() (PAGE_SIZE)
#define getpagesize() (PAGE_SIZE)
 
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
 
extern ssize_t write(int, const void *, size_t);
extern ssize_t read(int, void *, size_t);
 
extern off_t lseek(int, off_t, int);
extern int ftruncate(int, off_t);
 
extern int close(int);
extern int fsync(int);
extern int unlink(const char *);
 
extern char *getcwd(char *buf, size_t);
extern int rmdir(const char *);
extern int chdir(const char *);
extern char *getcwd(char *buf, size_t);
 
extern void _exit(int status);
extern void *sbrk(ssize_t incr);
extern void _exit(int status) __attribute__ ((noreturn));
extern int usleep(unsigned long usec);
extern unsigned int sleep(unsigned int seconds);
 
/branches/arm/uspace/lib/libc/include/mem.h
0,0 → 1,51
/*
* Copyright (c) 2005 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_MEM_H_
#define LIBC_MEM_H_
 
#include <sys/types.h>
 
#define bzero(ptr, len) memset((ptr), 0, (len))
 
extern void *memset(void *, int, size_t);
extern void *memcpy(void *, const void *, size_t);
extern void *memmove(void *, const void *, size_t);
 
extern int bcmp(const char *, const char *, size_t);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/lib/libc/include/adt/gcdlcm.h
0,0 → 1,73
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_GCDLCM_H_
#define LIBC_GCDLCM_H_
 
#include <sys/types.h>
 
#define DECLARE_GCD(type, name) \
static inline type name(type a, type b) \
{ \
if (a == 0) \
return b; \
\
while (b != 0) { \
if (a > b) \
a -= b; \
else \
b -= a; \
} \
\
return a; \
}
 
#define DECLARE_LCM(type, name, gcd) \
static inline type name(type a, type b) \
{ \
return (a * b) / gcd(a, b); \
}
 
DECLARE_GCD(uint32_t, gcd32);
DECLARE_GCD(uint64_t, gcd64);
DECLARE_GCD(size_t, gcd);
 
DECLARE_LCM(uint32_t, lcm32, gcd32);
DECLARE_LCM(uint64_t, lcm64, gcd64);
DECLARE_LCM(size_t, lcm, gcd);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/adt/hash_table.h
0,0 → 1,94
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_HASH_TABLE_H_
#define LIBC_HASH_TABLE_H_
 
#include <adt/list.h>
#include <unistd.h>
 
typedef unsigned long hash_count_t;
typedef unsigned long hash_index_t;
typedef struct hash_table hash_table_t;
typedef struct hash_table_operations hash_table_operations_t;
 
/** Hash table structure. */
struct hash_table {
link_t *entry;
hash_count_t entries;
hash_count_t max_keys;
hash_table_operations_t *op;
};
 
/** Set of operations for hash table. */
struct hash_table_operations {
/** Hash function.
*
* @param key Array of keys needed to compute hash index. All keys
* must be passed.
*
* @return Index into hash table.
*/
hash_index_t (* hash)(unsigned long key[]);
/** Hash table item comparison function.
*
* @param key Array of keys that will be compared with item. It is
* not necessary to pass all keys.
*
* @return true if the keys match, false otherwise.
*/
int (*compare)(unsigned long key[], hash_count_t keys, link_t *item);
 
/** Hash table item removal callback.
*
* @param item Item that was removed from the hash table.
*/
void (*remove_callback)(link_t *item);
};
 
#define hash_table_get_instance(item, type, member) \
list_get_instance((item), type, member)
 
extern int hash_table_create(hash_table_t *, hash_count_t, hash_count_t,
hash_table_operations_t *);
extern void hash_table_insert(hash_table_t *, unsigned long [], link_t *);
extern link_t *hash_table_find(hash_table_t *, unsigned long []);
extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t);
extern void hash_table_destroy(hash_table_t *);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/adt/list.h
0,0 → 1,201
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_LIST_H_
#define LIBC_LIST_H_
 
#include <unistd.h>
 
/** Doubly linked list head and link type. */
typedef struct link {
struct link *prev; /**< Pointer to the previous item in the list. */
struct link *next; /**< Pointer to the next item in the list. */
} link_t;
 
/** Declare and initialize statically allocated list.
*
* @param name Name of the new statically allocated list.
*/
#define LIST_INITIALIZE(name) link_t name = { \
.prev = &name, \
.next = &name \
}
 
/** Initialize doubly-linked circular list link
*
* Initialize doubly-linked list link.
*
* @param link Pointer to link_t structure to be initialized.
*/
static inline void link_initialize(link_t *link)
{
link->prev = NULL;
link->next = NULL;
}
 
/** Initialize doubly-linked circular list
*
* Initialize doubly-linked circular list.
*
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_initialize(link_t *head)
{
head->prev = head;
head->next = head;
}
 
/** Add item to the beginning of doubly-linked circular list
*
* Add item to the beginning of doubly-linked circular list.
*
* @param link Pointer to link_t structure to be added.
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_prepend(link_t *link, link_t *head)
{
link->next = head->next;
link->prev = head;
head->next->prev = link;
head->next = link;
}
 
/** Add item to the end of doubly-linked circular list
*
* Add item to the end of doubly-linked circular list.
*
* @param link Pointer to link_t structure to be added.
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_append(link_t *link, link_t *head)
{
link->prev = head->prev;
link->next = head;
head->prev->next = link;
head->prev = link;
}
 
/** Insert item before another item in doubly-linked circular list. */
static inline void list_insert_before(link_t *l, link_t *r)
{
list_append(l, r);
}
 
/** Insert item after another item in doubly-linked circular list. */
static inline void list_insert_after(link_t *r, link_t *l)
{
list_prepend(l, r);
}
 
/** Remove item from doubly-linked circular list
*
* Remove item from doubly-linked circular list.
*
* @param link Pointer to link_t structure to be removed from the list it is contained in.
*/
static inline void list_remove(link_t *link)
{
link->next->prev = link->prev;
link->prev->next = link->next;
link_initialize(link);
}
 
/** Query emptiness of doubly-linked circular list
*
* Query emptiness of doubly-linked circular list.
*
* @param head Pointer to link_t structure representing head of the list.
*/
static inline int list_empty(link_t *head)
{
return ((head->next == head) ? 1 : 0);
}
 
 
/** Split or concatenate headless doubly-linked circular list
*
* Split or concatenate headless doubly-linked circular list.
*
* Note that the algorithm works both directions:
* concatenates splitted lists and splits concatenated lists.
*
* @param part1 Pointer to link_t structure leading the first (half of the headless) list.
* @param part2 Pointer to link_t structure leading the second (half of the headless) list.
*/
static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
{
part1->prev->next = part2;
part2->prev->next = part1;
link_t *hlp = part1->prev;
part1->prev = part2->prev;
part2->prev = hlp;
}
 
 
/** Split headless doubly-linked circular list
*
* Split headless doubly-linked circular list.
*
* @param part1 Pointer to link_t structure leading the first half of the headless list.
* @param part2 Pointer to link_t structure leading the second half of the headless list.
*/
static inline void headless_list_split(link_t *part1, link_t *part2)
{
headless_list_split_or_concat(part1, part2);
}
 
/** Concatenate two headless doubly-linked circular lists
*
* Concatenate two headless doubly-linked circular lists.
*
* @param part1 Pointer to link_t structure leading the first headless list.
* @param part2 Pointer to link_t structure leading the second headless list.
*/
static inline void headless_list_concat(link_t *part1, link_t *part2)
{
headless_list_split_or_concat(part1, part2);
}
 
#define list_get_instance(link, type, member) ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
 
extern int list_member(const link_t *link, const link_t *head);
extern void list_concat(link_t *head1, link_t *head2);
extern unsigned int list_count(const link_t *link);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/adt/fifo.h
0,0 → 1,127
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
/*
* This implementation of FIFO stores values in an array
* (static or dynamic). As such, these FIFOs have upper bound
* on number of values they can store. Push and pop operations
* are done via accessing the array through head and tail indices.
* Because of better operation ordering in fifo_pop(), the access
* policy for these two indices is to 'increment (mod size of FIFO)
* and use'.
*/
 
#ifndef LIBC_FIFO_H_
#define LIBC_FIFO_H_
 
#include <malloc.h>
 
typedef unsigned long fifo_count_t;
typedef unsigned long fifo_index_t;
 
#define FIFO_CREATE_STATIC(name, t, itms) \
struct { \
t fifo[(itms)]; \
fifo_count_t items; \
fifo_index_t head; \
fifo_index_t tail; \
} name
 
/** Create and initialize static FIFO.
*
* FIFO is allocated statically.
* This macro is suitable for creating smaller FIFOs.
*
* @param name Name of FIFO.
* @param t Type of values stored in FIFO.
* @param itms Number of items that can be stored in FIFO.
*/
#define FIFO_INITIALIZE_STATIC(name, t, itms) \
FIFO_CREATE_STATIC(name, t, itms) = { \
.items = (itms), \
.head = 0, \
.tail = 0 \
}
 
/** Create and prepare dynamic FIFO.
*
* FIFO is allocated dynamically.
* This macro is suitable for creating larger FIFOs.
*
* @param name Name of FIFO.
* @param t Type of values stored in FIFO.
* @param itms Number of items that can be stored in FIFO.
*/
#define FIFO_INITIALIZE_DYNAMIC(name, t, itms) \
struct { \
t *fifo; \
fifo_count_t items; \
fifo_index_t head; \
fifo_index_t tail; \
} name = { \
.fifo = NULL, \
.items = (itms), \
.head = 0, \
.tail = 0 \
}
 
/** Pop value from head of FIFO.
*
* @param name FIFO name.
*
* @return Leading value in FIFO.
*/
#define fifo_pop(name) \
name.fifo[name.head = (name.head + 1) < name.items ? (name.head + 1) : 0]
 
/** Push value to tail of FIFO.
*
* @param name FIFO name.
* @param value Value to be appended to FIFO.
*
*/
#define fifo_push(name, value) \
name.fifo[name.tail = (name.tail + 1) < name.items ? (name.tail + 1) : 0] = (value)
 
/** Allocate memory for dynamic FIFO.
*
* @param name FIFO name.
*/
#define fifo_create(name) \
name.fifo = malloc(sizeof(*name.fifo) * name.items)
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/macros.h
0,0 → 1,60
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_MACROS_H_
#define LIBC_MACROS_H_
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
 
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
 
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
 
#define LOWER32(arg) ((arg) & 0xffffffff)
#define UPPER32(arg) (((arg) >> 32) & 0xffffffff)
 
#define MERGE_LOUP32(lo, up) \
((((uint64_t) (lo)) & 0xffffffff) \
| ((((uint64_t) (up)) & 0xffffffff) << 32))
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/errno.h
36,17 → 36,25
#define LIBC_ERRNO_H_
 
#include <kernel/errno.h>
#include <fibril.h>
 
#define ENAMETOOLONG (-256)
#define EISDIR (-257)
#define ENOTDIR (-258)
#define ENOSPC (-259)
#define EEXIST (-260)
#define ENOTEMPTY (-261)
#define EBADF (-262)
#define ERANGE (-263)
#define EXDEV (-264)
extern int _errno;
 
#define errno _errno
 
#define EMFILE (-17)
#define ENAMETOOLONG (-256)
#define EISDIR (-257)
#define ENOTDIR (-258)
#define ENOSPC (-259)
#define EEXIST (-260)
#define ENOTEMPTY (-261)
#define EBADF (-262)
#define ERANGE (-263)
#define EXDEV (-264)
#define EIO (-265)
#define EMLINK (-266)
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/malloc.h
1,537 → 1,51
/*
Default header file for malloc-2.8.x, written by Doug Lea
and released to the public domain, as explained at
http://creativecommons.org/licenses/publicdomain.
last update: Mon Aug 15 08:55:52 2005 Doug Lea (dl at gee)
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
This header is for ANSI C/C++ only. You can set any of
the following #defines before including:
 
* If USE_DL_PREFIX is defined, it is assumed that malloc.c
was also compiled with this option, so all routines
have names starting with "dl".
 
* If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this
file will be #included AFTER <malloc.h>. This is needed only if
your system defines a struct mallinfo that is incompatible with the
standard one declared here. Otherwise, you can include this file
INSTEAD of your system system <malloc.h>. At least on ANSI, all
declarations should be compatible with system versions
 
* If MSPACES is defined, declarations for mspace versions are included.
*/
 
#ifndef MALLOC_280_H
#define MALLOC_280_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include <stddef.h> /* for size_t */
 
#if !ONLY_MSPACES
 
#ifndef USE_DL_PREFIX
#define dlcalloc calloc
#define dlfree free
#define dlmalloc malloc
#define dlmemalign memalign
#define dlrealloc realloc
#define dlvalloc valloc
#define dlpvalloc pvalloc
#define dlmallinfo mallinfo
#define dlmallopt mallopt
#define dlmalloc_trim malloc_trim
#define dlmalloc_stats malloc_stats
#define dlmalloc_usable_size malloc_usable_size
#define dlmalloc_footprint malloc_footprint
#define dlmalloc_max_footprint malloc_max_footprint
#define dlindependent_calloc independent_calloc
#define dlindependent_comalloc independent_comalloc
#endif /* USE_DL_PREFIX */
 
 
/*
malloc(size_t n)
Returns a pointer to a newly allocated chunk of at least n bytes, or
null if no space is available, in which case errno is set to ENOMEM
on ANSI C systems.
 
If n is zero, malloc returns a minimum-sized chunk. (The minimum
size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
systems.) Note that size_t is an unsigned type, so calls with
arguments that would be negative if signed are interpreted as
requests for huge amounts of space, which will often fail. The
maximum supported value of n differs across systems, but is in all
cases less than the maximum representable value of a size_t.
*/
void* dlmalloc(size_t);
 
/*
free(void* p)
Releases the chunk of memory pointed to by p, that had been previously
allocated using malloc or a related routine such as realloc.
It has no effect if p is null. If p was not malloced or already
freed, free(p) will by default cuase the current program to abort.
*/
void dlfree(void*);
 
/*
calloc(size_t n_elements, size_t element_size);
Returns a pointer to n_elements * element_size bytes, with all locations
set to zero.
*/
void* dlcalloc(size_t, size_t);
 
/*
realloc(void* p, size_t n)
Returns a pointer to a chunk of size n that contains the same data
as does chunk p up to the minimum of (n, p's size) bytes, or null
if no space is available.
 
The returned pointer may or may not be the same as p. The algorithm
prefers extending p in most cases when possible, otherwise it
employs the equivalent of a malloc-copy-free sequence.
 
If p is null, realloc is equivalent to malloc.
 
If space is not available, realloc returns null, errno is set (if on
ANSI) and p is NOT freed.
 
if n is for fewer bytes than already held by p, the newly unused
space is lopped off and freed if possible. realloc with a size
argument of zero (re)allocates a minimum-sized chunk.
 
The old unix realloc convention of allowing the last-free'd chunk
to be used as an argument to realloc is not supported.
*/
 
void* dlrealloc(void*, size_t);
 
/*
memalign(size_t alignment, size_t n);
Returns a pointer to a newly allocated chunk of n bytes, aligned
in accord with the alignment argument.
 
The alignment argument should be a power of two. If the argument is
not a power of two, the nearest greater power is used.
8-byte alignment is guaranteed by normal malloc calls, so don't
bother calling memalign with an argument of 8 or less.
 
Overreliance on memalign is a sure way to fragment space.
*/
void* dlmemalign(size_t, size_t);
 
/*
valloc(size_t n);
Equivalent to memalign(pagesize, n), where pagesize is the page
size of the system. If the pagesize is unknown, 4096 is used.
*/
void* dlvalloc(size_t);
 
/*
mallopt(int parameter_number, int parameter_value)
Sets tunable parameters The format is to provide a
(parameter-number, parameter-value) pair. mallopt then sets the
corresponding parameter to the argument value if it can (i.e., so
long as the value is meaningful), and returns 1 if successful else
0. SVID/XPG/ANSI defines four standard param numbers for mallopt,
normally defined in malloc.h. None of these are use in this malloc,
so setting them has no effect. But this malloc also supports other
options in mallopt:
 
Symbol param # default allowed param values
M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming)
M_GRANULARITY -2 page size any power of 2 >= page size
M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support)
*/
int dlmallopt(int, int);
 
#define M_TRIM_THRESHOLD (-1)
#define M_GRANULARITY (-2)
#define M_MMAP_THRESHOLD (-3)
 
 
/*
malloc_footprint();
Returns the number of bytes obtained from the system. The total
number of bytes allocated by malloc, realloc etc., is less than this
value. Unlike mallinfo, this function returns only a precomputed
result, so can be called frequently to monitor memory consumption.
Even if locks are otherwise defined, this function does not use them,
so results might not be up to date.
*/
size_t dlmalloc_footprint(void);
size_t dlmalloc_max_footprint(void);
 
#if !NO_MALLINFO
/*
mallinfo()
Returns (by copy) a struct containing various summary statistics:
 
arena: current total non-mmapped bytes allocated from system
ordblks: the number of free chunks
smblks: always zero.
hblks: current number of mmapped regions
hblkhd: total bytes held in mmapped regions
usmblks: the maximum total allocated space. This will be greater
than current total if trimming has occurred.
fsmblks: always zero
uordblks: current total allocated space (normal or mmapped)
fordblks: total free space
keepcost: the maximum number of bytes that could ideally be released
back to system via malloc_trim. ("ideally" means that
it ignores page restrictions etc.)
 
Because these fields are ints, but internal bookkeeping may
be kept as longs, the reported values may wrap around zero and
thus be inaccurate.
*/
#ifndef HAVE_USR_INCLUDE_MALLOC_H
#ifndef _MALLOC_H
#ifndef MALLINFO_FIELD_TYPE
#define MALLINFO_FIELD_TYPE size_t
#endif /* MALLINFO_FIELD_TYPE */
struct mallinfo {
MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */
MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */
MALLINFO_FIELD_TYPE smblks; /* always 0 */
MALLINFO_FIELD_TYPE hblks; /* always 0 */
MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */
MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */
MALLINFO_FIELD_TYPE fsmblks; /* always 0 */
MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
MALLINFO_FIELD_TYPE fordblks; /* total free space */
MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
};
#endif /* _MALLOC_H */
#endif /* HAVE_USR_INCLUDE_MALLOC_H */
 
struct mallinfo dlmallinfo(void);
#endif /* NO_MALLINFO */
 
/*
independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
 
independent_calloc is similar to calloc, but instead of returning a
single cleared space, it returns an array of pointers to n_elements
independent elements that can hold contents of size elem_size, each
of which starts out cleared, and can be independently freed,
realloc'ed etc. The elements are guaranteed to be adjacently
allocated (this is not guaranteed to occur with multiple callocs or
mallocs), which may also improve cache locality in some
applications.
 
The "chunks" argument is optional (i.e., may be null, which is
probably the most typical usage). If it is null, the returned array
is itself dynamically allocated and should also be freed when it is
no longer needed. Otherwise, the chunks array must be of at least
n_elements in length. It is filled in with the pointers to the
chunks.
 
In either case, independent_calloc returns this pointer array, or
null if the allocation failed. If n_elements is zero and "chunks"
is null, it returns a chunk representing an array with zero elements
(which should be freed if not wanted).
 
Each element must be individually freed when it is no longer
needed. If you'd like to instead be able to free all at once, you
should instead use regular calloc and assign pointers into this
space to represent elements. (In this case though, you cannot
independently free elements.)
 
independent_calloc simplifies and speeds up implementations of many
kinds of pools. It may also be useful when constructing large data
structures that initially have a fixed number of fixed-sized nodes,
but the number is not known at compile time, and some of the nodes
may later need to be freed. For example:
 
struct Node { int item; struct Node* next; };
 
struct Node* build_list() {
struct Node** pool;
int n = read_number_of_nodes_needed();
if (n <= 0) return 0;
pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
if (pool == 0) die();
// organize into a linked list...
struct Node* first = pool[0];
for (i = 0; i < n-1; ++i)
pool[i]->next = pool[i+1];
free(pool); // Can now free the array (or not, if it is needed later)
return first;
}
*/
void** dlindependent_calloc(size_t, size_t, void**);
 
/*
independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
 
independent_comalloc allocates, all at once, a set of n_elements
chunks with sizes indicated in the "sizes" array. It returns
an array of pointers to these elements, each of which can be
independently freed, realloc'ed etc. The elements are guaranteed to
be adjacently allocated (this is not guaranteed to occur with
multiple callocs or mallocs), which may also improve cache locality
in some applications.
 
The "chunks" argument is optional (i.e., may be null). If it is null
the returned array is itself dynamically allocated and should also
be freed when it is no longer needed. Otherwise, the chunks array
must be of at least n_elements in length. It is filled in with the
pointers to the chunks.
 
In either case, independent_comalloc returns this pointer array, or
null if the allocation failed. If n_elements is zero and chunks is
null, it returns a chunk representing an array with zero elements
(which should be freed if not wanted).
 
Each element must be individually freed when it is no longer
needed. If you'd like to instead be able to free all at once, you
should instead use a single regular malloc, and assign pointers at
particular offsets in the aggregate space. (In this case though, you
cannot independently free elements.)
 
independent_comallac differs from independent_calloc in that each
element may have a different size, and also that it does not
automatically clear elements.
 
independent_comalloc can be used to speed up allocation in cases
where several structs or objects must always be allocated at the
same time. For example:
 
struct Head { ... }
struct Foot { ... }
 
void send_message(char* msg) {
int msglen = strlen(msg);
size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
void* chunks[3];
if (independent_comalloc(3, sizes, chunks) == 0)
die();
struct Head* head = (struct Head*)(chunks[0]);
char* body = (char*)(chunks[1]);
struct Foot* foot = (struct Foot*)(chunks[2]);
// ...
}
 
In general though, independent_comalloc is worth using only for
larger values of n_elements. For small values, you probably won't
detect enough difference from series of malloc calls to bother.
 
Overuse of independent_comalloc can increase overall memory usage,
since it cannot reuse existing noncontiguous small chunks that
might be available for some of the elements.
*/
void** dlindependent_comalloc(size_t, size_t*, void**);
 
 
/*
pvalloc(size_t n);
Equivalent to valloc(minimum-page-that-holds(n)), that is,
round up n to nearest pagesize.
/** @addtogroup libc
* @{
*/
void* dlpvalloc(size_t);
/** @file
*/
 
/*
malloc_trim(size_t pad);
#ifndef LIBC_MALLOC_H_
#define LIBC_MALLOC_H_
 
If possible, gives memory back to the system (via negative arguments
to sbrk) if there is unused memory at the `high' end of the malloc
pool or in unused MMAP segments. You can call this after freeing
large blocks of memory to potentially reduce the system-level memory
requirements of a program. However, it cannot guarantee to reduce
memory. Under some allocation patterns, some large free blocks of
memory will be locked between two used chunks, so they cannot be
given back to the system.
#include <sys/types.h>
 
The `pad' argument to malloc_trim represents the amount of free
trailing space to leave untrimmed. If this argument is zero, only
the minimum amount of memory to maintain internal data structures
will be left. Non-zero arguments can be supplied to maintain enough
trailing space to service future expected allocations without having
to re-obtain memory from the system.
extern void __heap_init(void);
extern uintptr_t get_max_heap_addr(void);
 
Malloc_trim returns 1 if it actually released any memory, else 0.
*/
int dlmalloc_trim(size_t);
extern void *malloc(const size_t size);
extern void *memalign(const size_t align, const size_t size);
extern void *realloc(const void *addr, const size_t size);
extern void free(const void *addr);
 
/*
malloc_usable_size(void* p);
 
Returns the number of bytes you can actually use in
an allocated chunk, which may be more than you requested (although
often not) due to alignment and minimum size constraints.
You can use this many bytes without worrying about
overwriting other allocated objects. This is not a particularly great
programming practice. malloc_usable_size can be more useful in
debugging and assertions, for example:
 
p = malloc(n);
assert(malloc_usable_size(p) >= 256);
*/
size_t dlmalloc_usable_size(void*);
 
/*
malloc_stats();
Prints on stderr the amount of space obtained from the system (both
via sbrk and mmap), the maximum amount (which may be more than
current if malloc_trim and/or munmap got called), and the current
number of bytes allocated via malloc (or realloc, etc) but not yet
freed. Note that this is the number of bytes allocated, not the
number requested. It will be larger than the number requested
because of alignment and bookkeeping overhead. Because it includes
alignment wastage as being in use, this figure may be greater than
zero even when no user-level chunks are allocated.
 
The reported current and maximum system memory can be inaccurate if
a program makes other calls to system memory allocation functions
(normally sbrk) outside of malloc.
 
malloc_stats prints only the most commonly interesting statistics.
More information can be obtained by calling mallinfo.
*/
void dlmalloc_stats(void);
 
#endif /* !ONLY_MSPACES */
 
#if MSPACES
 
/*
mspace is an opaque type representing an independent
region of space that supports mspace_malloc, etc.
*/
typedef void* mspace;
 
/*
create_mspace creates and returns a new independent space with the
given initial capacity, or, if 0, the default granularity size. It
returns null if there is no system memory available to create the
space. If argument locked is non-zero, the space uses a separate
lock to control access. The capacity of the space will grow
dynamically as needed to service mspace_malloc requests. You can
control the sizes of incremental increases of this space by
compiling with a different DEFAULT_GRANULARITY or dynamically
setting with mallopt(M_GRANULARITY, value).
*/
mspace create_mspace(size_t capacity, int locked);
 
/*
destroy_mspace destroys the given space, and attempts to return all
of its memory back to the system, returning the total number of
bytes freed. After destruction, the results of access to all memory
used by the space become undefined.
*/
size_t destroy_mspace(mspace msp);
 
/*
create_mspace_with_base uses the memory supplied as the initial base
of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
space is used for bookkeeping, so the capacity must be at least this
large. (Otherwise 0 is returned.) When this initial space is
exhausted, additional memory will be obtained from the system.
Destroying this space will deallocate all additionally allocated
space (if possible) but not the initial base.
*/
mspace create_mspace_with_base(void* base, size_t capacity, int locked);
 
/*
mspace_malloc behaves as malloc, but operates within
the given space.
*/
void* mspace_malloc(mspace msp, size_t bytes);
 
/*
mspace_free behaves as free, but operates within
the given space.
 
If compiled with FOOTERS==1, mspace_free is not actually needed.
free may be called instead of mspace_free because freed chunks from
any space are handled by their originating spaces.
*/
void mspace_free(mspace msp, void* mem);
 
/*
mspace_realloc behaves as realloc, but operates within
the given space.
 
If compiled with FOOTERS==1, mspace_realloc is not actually
needed. realloc may be called instead of mspace_realloc because
realloced chunks from any space are handled by their originating
spaces.
*/
void* mspace_realloc(mspace msp, void* mem, size_t newsize);
 
/*
mspace_calloc behaves as calloc, but operates within
the given space.
*/
void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
 
/*
mspace_memalign behaves as memalign, but operates within
the given space.
*/
void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
 
/*
mspace_independent_calloc behaves as independent_calloc, but
operates within the given space.
*/
void** mspace_independent_calloc(mspace msp, size_t n_elements,
size_t elem_size, void* chunks[]);
 
/*
mspace_independent_comalloc behaves as independent_comalloc, but
operates within the given space.
*/
void** mspace_independent_comalloc(mspace msp, size_t n_elements,
size_t sizes[], void* chunks[]);
 
/*
mspace_footprint() returns the number of bytes obtained from the
system for this space.
*/
size_t mspace_footprint(mspace msp);
 
 
#if !NO_MALLINFO
/*
mspace_mallinfo behaves as mallinfo, but reports properties of
the given space.
*/
struct mallinfo mspace_mallinfo(mspace msp);
#endif /* NO_MALLINFO */
 
/*
mspace_malloc_stats behaves as malloc_stats, but reports
properties of the given space.
*/
void mspace_malloc_stats(mspace msp);
 
/*
mspace_trim behaves as malloc_trim, but
operates within the given space.
*/
int mspace_trim(mspace msp, size_t pad);
 
/*
An alias for mallopt.
*/
int mspace_mallopt(int, int);
 
#endif /* MSPACES */
 
#ifdef __cplusplus
}; /* end of extern "C" */
#endif
 
#endif /* MALLOC_280_H */
 
 
/** @}
/** @}
*/
/branches/arm/uspace/lib/libc/include/devmap.h
0,0 → 1,59
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_DEVMAP_H_
#define LIBC_DEVMAP_H_
 
#include <ipc/devmap.h>
#include <async.h>
 
extern int devmap_get_phone(devmap_interface_t, unsigned int);
extern void devmap_hangup_phone(devmap_interface_t iface);
 
extern int devmap_driver_register(const char *, async_client_conn_t);
extern int devmap_device_register(const char *, dev_handle_t *);
 
extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
extern int devmap_device_connect(dev_handle_t, unsigned int);
 
extern int devmap_null_create(void);
extern void devmap_null_destroy(int);
 
extern ipcarg_t devmap_device_get_count(void);
extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/sys/stat.h
36,7 → 36,26
#define LIBC_SYS_STAT_H_
 
#include <sys/types.h>
#include <bool.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
 
struct stat {
fs_handle_t fs_handle;
dev_handle_t dev_handle;
fs_index_t index;
unsigned lnkcnt;
bool is_file;
off_t size;
union {
struct {
dev_handle_t device;
} devfs_stat;
};
};
 
extern int fstat(int, struct stat *);
extern int stat(const char *, struct stat *);
extern int mkdir(const char *, mode_t);
 
#endif
/branches/arm/uspace/lib/libc/include/sys/types.h
37,11 → 37,15
 
#include <libarch/types.h>
 
typedef unsigned long size_t;
typedef signed long ssize_t;
typedef long off_t;
typedef int mode_t;
 
typedef int32_t wchar_t;
 
typedef volatile uint8_t ioport8_t;
typedef volatile uint16_t ioport16_t;
typedef volatile uint32_t ioport32_t;
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/byteorder.h
35,33 → 35,48
#ifndef LIBC_BYTEORDER_H_
#define LIBC_BYTEORDER_H_
 
#include <libarch/byteorder.h>
#include <stdint.h>
 
#if !(defined(ARCH_IS_BIG_ENDIAN) ^ defined(ARCH_IS_LITTLE_ENDIAN))
#error The architecture must be either big-endian or little-endian.
#if !(defined(__BE__) ^ defined(__LE__))
#error The architecture must be either big-endian or little-endian.
#endif
 
#ifdef ARCH_IS_BIG_ENDIAN
#ifdef __BE__
 
#define uint16_t_le2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_le2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_le2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_le2host(n) (uint64_t_byteorder_swap(n))
 
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#define host2uint16_t_le(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_le(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_le(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_be(n) (n)
#define host2uint32_t_be(n) (n)
#define host2uint64_t_be(n) (n)
 
#else
 
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint16_t_be2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_be2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_be2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_be2host(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_le(n) (n)
#define host2uint32_t_le(n) (n)
#define host2uint64_t_le(n) (n)
 
#define host2uint16_t_be(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_be(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_be(n) (uint64_t_byteorder_swap(n))
 
#endif
 
static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
/branches/arm/uspace/lib/libc/include/string.h
35,32 → 35,59
#ifndef LIBC_STRING_H_
#define LIBC_STRING_H_
 
#include <mem.h>
#include <sys/types.h>
#include <bool.h>
 
#define bzero(ptr, len) memset((ptr), 0, (len))
#define U_SPECIAL '?'
 
extern void * memset(void *, int, size_t);
extern void * memcpy(void *, const void *, size_t);
extern void * memmove(void *, const void *, size_t);
/** No size limit constant */
#define STR_NO_LIMIT ((size_t) -1)
 
extern int bcmp(const char *, const char *, size_t);
/** Maximum size of a string containing @c length characters */
#define STR_BOUNDS(length) ((length) << 2)
 
extern int strcmp(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);
extern int stricmp(const char *, const char *);
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
 
extern char *strcpy(char *, const char *);
extern char *strncpy(char *, const char *, size_t);
extern size_t str_size(const char *str);
extern size_t wstr_size(const wchar_t *str);
 
extern char *strcat(char *, const char *);
extern size_t str_lsize(const char *str, size_t max_len);
extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
 
extern size_t strlen(const char *);
extern size_t str_length(const char *str);
extern size_t wstr_length(const wchar_t *wstr);
 
extern char *strdup(const char *);
extern size_t str_nlength(const char *str, size_t size);
extern size_t wstr_nlength(const wchar_t *str, size_t size);
 
extern char *strchr(const char *, int);
extern char *strrchr(const char *, int);
extern bool ascii_check(wchar_t ch);
extern bool chr_check(wchar_t ch);
 
extern int str_cmp(const char *s1, const char *s2);
extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
 
extern void str_cpy(char *dest, size_t size, const char *src);
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
extern void str_append(char *dest, size_t size, const char *src);
 
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
extern const char *str_chr(const char *str, wchar_t ch);
extern const char *str_rchr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
 
extern char *str_dup(const char *);
 
/*
* TODO: Get rid of this.
*/
 
extern int stricmp(const char *, const char *);
 
extern long int strtol(const char *, char **, int);
extern unsigned long strtoul(const char *, char **, int);
 
/branches/arm/uspace/lib/libc/include/fibril_sync.h
0,0 → 1,104
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_FIBRIL_SYNC_H_
#define LIBC_FIBRIL_SYNC_H_
 
#include <async.h>
#include <fibril.h>
#include <adt/list.h>
#include <libarch/tls.h>
 
typedef struct {
int counter;
link_t waiters;
} fibril_mutex_t;
 
#define FIBRIL_MUTEX_INITIALIZE(name) \
fibril_mutex_t name = { \
.counter = 1, \
.waiters = { \
.prev = &name.waiters, \
.next = &name.waiters, \
} \
}
 
typedef struct {
unsigned writers;
unsigned readers;
link_t waiters;
} fibril_rwlock_t;
 
#define FIBRIL_RWLOCK_INITIALIZE(name) \
fibril_rwlock_t name = { \
.readers = 0, \
.writers = 0, \
.waiters = { \
.prev = &name.waiters, \
.next = &name.waiters, \
} \
}
 
typedef struct {
link_t waiters;
} fibril_condvar_t;
 
#define FIBRIL_CONDVAR_INITIALIZE(name) \
fibril_condvar_t name = { \
.waiters = { \
.next = &name.waiters, \
.prev = &name.waiters, \
} \
}
 
extern void fibril_mutex_initialize(fibril_mutex_t *);
extern void fibril_mutex_lock(fibril_mutex_t *);
extern bool fibril_mutex_trylock(fibril_mutex_t *);
extern void fibril_mutex_unlock(fibril_mutex_t *);
 
extern void fibril_rwlock_initialize(fibril_rwlock_t *);
extern void fibril_rwlock_read_lock(fibril_rwlock_t *);
extern void fibril_rwlock_write_lock(fibril_rwlock_t *);
extern void fibril_rwlock_read_unlock(fibril_rwlock_t *);
extern void fibril_rwlock_write_unlock(fibril_rwlock_t *);
 
extern void fibril_condvar_initialize(fibril_condvar_t *);
extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *);
extern void fibril_condvar_signal(fibril_condvar_t *);
extern void fibril_condvar_broadcast(fibril_condvar_t *);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/loader/pcb.h
37,6 → 37,7
#define LIBC_PCB_H_
 
#include <sys/types.h>
#include <vfs/vfs.h>
 
typedef void (*entry_point_t)(void);
 
45,27 → 46,34
* Holds pointers to data passed from the program loader to the program
* and/or to the dynamic linker. This includes the program entry point,
* arguments, environment variables etc.
*
*/
typedef struct {
/** Program entry point */
/** Program entry point. */
entry_point_t entry;
 
/** Number of command-line arguments */
/** Number of command-line arguments. */
int argc;
/** Command-line arguments */
/** Command-line arguments. */
char **argv;
 
/** Number of preset files. */
int filc;
/** Preset files. */
fdi_node_t **filv;
/*
* ELF-specific data
* ELF-specific data.
*/
/** Pointer to ELF dynamic section of the program */
/** Pointer to ELF dynamic section of the program. */
void *dynamic;
/** Pointer to dynamic section of the runtime linker */
void *rtld_dynamic;
/** Runtime-linker load bias */
uintptr_t rtld_bias;
} pcb_t;
 
/**
* A pointer to the program control block. Having received the PCB pointer,
* the C library startup code stores it here for later use.
*/
extern pcb_t *__pcb;
 
#endif
/branches/arm/uspace/lib/libc/include/loader/loader.h
37,6 → 37,7
#define LIBC_LOADER_H_
 
#include <task.h>
#include <vfs/vfs.h>
 
/** Abstraction of a loader connection */
typedef struct {
44,10 → 45,12
int phone_id;
} loader_t;
 
extern loader_t *loader_spawn(void);
extern int loader_spawn(const char *);
extern loader_t *loader_connect(void);
extern int loader_get_task_id(loader_t *, task_id_t *);
extern int loader_set_pathname(loader_t *, const char *);
extern int loader_set_args(loader_t *, char *const []);
extern int loader_set_args(loader_t *, char *const[]);
extern int loader_set_files(loader_t *, fdi_node_t *const[]);
extern int loader_load_program(loader_t *);
extern int loader_run(loader_t *);
extern void loader_abort(loader_t *);
/branches/arm/uspace/lib/libc/include/fcntl.h
35,13 → 35,13
#ifndef LIBC_FCNTL_H_
#define LIBC_FCNTL_H_
 
#define O_CREAT 1
#define O_EXCL 2
#define O_TRUNC 4
#define O_APPEND 8
#define O_RDONLY 16
#define O_RDWR 32
#define O_WRONLY 64
#define O_CREAT 1
#define O_EXCL 2
#define O_TRUNC 4
#define O_APPEND 8
#define O_RDONLY 16
#define O_RDWR 32
#define O_WRONLY 64
 
extern int open(const char *, int, ...);
 
/branches/arm/uspace/lib/libc/include/dirent.h
35,7 → 35,7
#ifndef LIBC_DIRENT_H_
#define LIBC_DIRENT_H_
 
#define NAME_MAX 256
#define NAME_MAX 256
 
struct dirent {
char d_name[NAME_MAX + 1];
46,7 → 46,6
struct dirent res;
} DIR;
 
 
extern DIR *opendir(const char *);
extern struct dirent *readdir(DIR *);
extern void rewinddir(DIR *);
/branches/arm/uspace/lib/libc/include/thread.h
45,7 → 45,7
extern void __thread_main(uspace_arg_t *);
 
extern int thread_create(void (*)(void *), void *, char *, thread_id_t *);
extern void thread_exit(int);
extern void thread_exit(int) __attribute__ ((noreturn));
extern void thread_detach(thread_id_t);
extern int thread_join(thread_id_t);
extern thread_id_t thread_get_id(void);
/branches/arm/uspace/lib/libc/include/event.h
0,0 → 1,46
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_EVENT_H_
#define LIBC_EVENT_H_
 
#include <kernel/ipc/event_types.h>
#include <ipc/ipc.h>
 
extern int event_subscribe(event_type_t, ipcarg_t);
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/include/ddi.h
37,9 → 37,11
 
#include <task.h>
 
extern int physmem_map(void *pf, void *vp, unsigned long pages, int flags);
extern int iospace_enable(task_id_t id, void *ioaddr, unsigned long size);
extern int preemption_control(int enable);
extern int device_assign_devno(void);
extern int physmem_map(void *, void *, unsigned long, int);
extern int iospace_enable(task_id_t, void *, unsigned long);
extern int preemption_control(int);
extern int pio_enable(void *, size_t, void **);
 
#endif
 
/branches/arm/uspace/lib/libc/include/libc.h
39,14 → 39,20
#include <kernel/syscall/syscall.h>
#include <libarch/syscall.h>
 
#define __SYSCALL0(id) __syscall(0, 0, 0, 0, 0, 0, id)
#define __SYSCALL1(id, p1) __syscall(p1, 0, 0, 0, 0, 0, id)
#define __SYSCALL2(id, p1, p2) __syscall(p1, p2, 0, 0, 0, 0, id)
#define __SYSCALL3(id, p1, p2, p3) __syscall(p1, p2, p3, 0, 0, 0, id)
#define __SYSCALL4(id, p1, p2, p3, p4) __syscall(p1, p2, p3, p4, 0, 0, id)
#define __SYSCALL5(id, p1, p2, p3, p4, p5) __syscall(p1, p2, p3, p4, p5, 0, id)
#define __SYSCALL0(id) \
__syscall0(0, 0, 0, 0, 0, 0, id)
#define __SYSCALL1(id, p1) \
__syscall1(p1, 0, 0, 0, 0, 0, id)
#define __SYSCALL2(id, p1, p2) \
__syscall2(p1, p2, 0, 0, 0, 0, id)
#define __SYSCALL3(id, p1, p2, p3) \
__syscall3(p1, p2, p3, 0, 0, 0, id)
#define __SYSCALL4(id, p1, p2, p3, p4) \
__syscall4(p1, p2, p3, p4, 0, 0, id)
#define __SYSCALL5(id, p1, p2, p3, p4, p5) \
__syscall5(p1, p2, p3, p4, p5, 0, id)
#define __SYSCALL6(id, p1, p2, p3, p4, p5, p6) \
__syscall(p1, p2, p3, p4, p5, p6,id)
__syscall6(p1, p2, p3, p4, p5, p6, id)
 
extern void __main(void *pcb_ptr);
extern void __exit(void);
/branches/arm/uspace/lib/libc/include/ctype.h
79,11 → 79,19
static inline int tolower(int c)
{
if (isupper(c))
return (c + ('a' - 'A' > 0 ? 'a' - 'A' : 'A' - 'a'));
return (c + ('a' - 'A'));
else
return c;
}
 
static inline int toupper(int c)
{
if (islower(c))
return (c + ('A' - 'a'));
else
return c;
}
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/align.h
35,21 → 35,28
#ifndef LIBC_ALIGN_H_
#define LIBC_ALIGN_H_
 
/** Align to the nearest lower address.
/** Align to the nearest lower address which is a power of two.
*
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
 
 
/** Align to the nearest higher address.
/** Align to the nearest higher address which is a power of two.
*
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_UP(s, a) ((long)((s) + ((a) - 1)) & ~((long) (a) - 1))
 
/** Round up to the nearest higher boundary.
*
* @param n Number to be aligned.
* @param b Boundary, arbitrary unsigned number.
*/
#define ROUND_UP(n, b) (((n) / (b) + ((n) % (b) != 0)) * (b))
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/include/syscall.h
32,15 → 32,28
/**
* @file
* @brief Syscall function declaration for architectures that don't
* inline syscalls.
* inline syscalls or architectures that handle syscalls
* according to the number of arguments.
*/
 
#ifndef LIBC_SYSCALL_H_
#define LIBC_SYSCALL_H_
 
#ifndef LIBARCH_SYSCALL_GENERIC
#error "You can't include this file directly."
#endif
 
#include <sys/types.h>
#include <kernel/syscall/syscall.h>
 
#define __syscall0 __syscall
#define __syscall1 __syscall
#define __syscall2 __syscall
#define __syscall3 __syscall
#define __syscall4 __syscall
#define __syscall5 __syscall
#define __syscall6 __syscall
 
extern sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2,
const sysarg_t p3, const sysarg_t p4, const sysarg_t p5, const sysarg_t p6,
const syscall_t id);
/branches/arm/uspace/lib/libc/generic/libadt/hash_table.c
File deleted
/branches/arm/uspace/lib/libc/generic/libadt/list.c
File deleted
/branches/arm/uspace/lib/libc/generic/io/sprintf.c
File deleted
/branches/arm/uspace/lib/libc/generic/io/vsprintf.c
File deleted
/branches/arm/uspace/lib/libc/generic/io/stream.c
File deleted
/branches/arm/uspace/lib/libc/generic/io/console.c
0,0 → 1,113
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2006 Jakub Vana
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <libc.h>
#include <async.h>
#include <io/console.h>
#include <ipc/console.h>
 
void console_clear(int phone)
{
async_msg_0(phone, CONSOLE_CLEAR);
}
 
int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
{
return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);
}
 
void console_set_style(int phone, int style)
{
async_msg_1(phone, CONSOLE_SET_STYLE, style);
}
 
void console_set_color(int phone, int fg_color, int bg_color, int flags)
{
async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
}
 
void console_set_rgb_color(int phone, int fg_color, int bg_color)
{
async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
}
 
void console_cursor_visibility(int phone, bool show)
{
async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
}
 
int console_get_color_cap(int phone, int *ccap)
{
ipcarg_t ccap_tmp;
int rc;
 
rc = async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, &ccap_tmp);
*ccap = ccap_tmp;
 
return rc;
}
 
void console_kcon_enable(int phone)
{
async_msg_0(phone, CONSOLE_KCON_ENABLE);
}
 
void console_goto(int phone, ipcarg_t row, ipcarg_t col)
{
async_msg_2(phone, CONSOLE_GOTO, row, col);
}
 
bool console_get_event(int phone, console_event_t *event)
{
ipcarg_t type;
ipcarg_t key;
ipcarg_t mods;
ipcarg_t c;
int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
if (rc < 0)
return false;
event->type = type;
event->key = key;
event->mods = mods;
event->c = c;
return true;
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/io/io.c
30,78 → 30,564
* @{
*/
/** @file
*/
*/
 
#include <libc.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <io/io.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <bool.h>
#include <malloc.h>
#include <io/klog.h>
#include <vfs/vfs.h>
#include <ipc/devmap.h>
#include <adt/list.h>
 
const static char nl = '\n';
static void _fflushbuf(FILE *stream);
 
int puts(const char *str)
static FILE stdin_null = {
.fd = -1,
.error = true,
.eof = true,
.klog = false,
.phone = -1,
.btype = _IONBF,
.buf = NULL,
.buf_size = 0,
.buf_head = NULL
};
 
static FILE stdout_klog = {
.fd = -1,
.error = false,
.eof = false,
.klog = true,
.phone = -1,
.btype = _IOLBF,
.buf = NULL,
.buf_size = BUFSIZ,
.buf_head = NULL
};
 
static FILE stderr_klog = {
.fd = -1,
.error = false,
.eof = false,
.klog = true,
.phone = -1,
.btype = _IONBF,
.buf = NULL,
.buf_size = 0,
.buf_head = NULL
};
 
FILE *stdin = NULL;
FILE *stdout = NULL;
FILE *stderr = NULL;
 
static LIST_INITIALIZE(files);
 
void __stdio_init(int filc, fdi_node_t *filv[])
{
size_t count;
if (filc > 0) {
stdin = fopen_node(filv[0], "r");
} else {
stdin = &stdin_null;
list_append(&stdin->link, &files);
}
if (str == NULL)
return putnchars("(NULL)", 6);
if (filc > 1) {
stdout = fopen_node(filv[1], "w");
} else {
stdout = &stdout_klog;
list_append(&stdout->link, &files);
}
for (count = 0; str[count] != 0; count++);
if (write_stdout((void *) str, count) == count) {
if (write_stdout(&nl, 1) == 1)
return 0;
if (filc > 2) {
stderr = fopen_node(filv[2], "w");
} else {
stderr = &stderr_klog;
list_append(&stderr->link, &files);
}
}
 
void __stdio_done(void)
{
link_t *link = files.next;
return EOF;
while (link != &files) {
FILE *file = list_get_instance(link, FILE, link);
fclose(file);
link = files.next;
}
}
 
/** Put count chars from buffer to stdout without adding newline
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
* @param count
* @return 0 on succes, EOF on fail
static bool parse_mode(const char *mode, int *flags)
{
/* Parse mode except first character. */
const char *mp = mode;
if (*mp++ == 0) {
errno = EINVAL;
return false;
}
if ((*mp == 'b') || (*mp == 't'))
mp++;
bool plus;
if (*mp == '+') {
mp++;
plus = true;
} else
plus = false;
if (*mp != 0) {
errno = EINVAL;
return false;
}
/* Parse first character of mode and determine flags for open(). */
switch (mode[0]) {
case 'r':
*flags = plus ? O_RDWR : O_RDONLY;
break;
case 'w':
*flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
break;
case 'a':
/* TODO: a+ must read from beginning, append to the end. */
if (plus) {
errno = ENOTSUP;
return false;
}
*flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
default:
errno = EINVAL;
return false;
}
return true;
}
 
/** Set stream buffer. */
void setvbuf(FILE *stream, void *buf, int mode, size_t size)
{
stream->btype = mode;
stream->buf = buf;
stream->buf_size = size;
stream->buf_head = stream->buf;
}
 
static void _setvbuf(FILE *stream)
{
/* FIXME: Use more complex rules for setting buffering options. */
switch (stream->fd) {
case 1:
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
break;
case 0:
case 2:
setvbuf(stream, NULL, _IONBF, 0);
break;
default:
setvbuf(stream, NULL, _IOFBF, BUFSIZ);
}
}
 
/** Allocate stream buffer. */
static int _fallocbuf(FILE *stream)
{
assert(stream->buf == NULL);
stream->buf = malloc(stream->buf_size);
if (stream->buf == NULL) {
errno = ENOMEM;
return -1;
}
stream->buf_head = stream->buf;
return 0;
}
 
/** Open a stream.
*
* @param path Path of the file to open.
* @param mode Mode string, (r|w|a)[b|t][+].
*
*/
int putnchars(const char *buf, size_t count)
FILE *fopen(const char *path, const char *mode)
{
if (write_stdout((void *) buf, count) == count)
return 0;
int flags;
if (!parse_mode(mode, &flags))
return NULL;
return EOF;
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = open(path, flags, 0666);
if (stream->fd < 0) {
/* errno was set by open() */
free(stream);
return NULL;
}
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
_setvbuf(stream);
list_append(&stream->link, &files);
return stream;
}
 
/** Same as puts, but does not print newline at end
FILE *fdopen(int fd, const char *mode)
{
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = fd;
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
_setvbuf(stream);
list_append(&stream->link, &files);
return stream;
}
 
FILE *fopen_node(fdi_node_t *node, const char *mode)
{
int flags;
if (!parse_mode(mode, &flags))
return NULL;
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = open_node(node, flags);
if (stream->fd < 0) {
/* errno was set by open_node() */
free(stream);
return NULL;
}
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
_setvbuf(stream);
list_append(&stream->link, &files);
return stream;
}
 
int fclose(FILE *stream)
{
int rc = 0;
fflush(stream);
if (stream->phone >= 0)
ipc_hangup(stream->phone);
if (stream->fd >= 0)
rc = close(stream->fd);
list_remove(&stream->link);
if ((stream != &stdin_null)
&& (stream != &stdout_klog)
&& (stream != &stderr_klog))
free(stream);
stream = NULL;
if (rc != 0) {
/* errno was set by close() */
return EOF;
}
return 0;
}
 
/** Read from a stream.
*
* @param buf Destination buffer.
* @param size Size of each record.
* @param nmemb Number of records to read.
* @param stream Pointer to the stream.
*
*/
int putstr(const char *str)
size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
{
size_t count;
size_t left = size * nmemb;
size_t done = 0;
if (str == NULL)
return putnchars("(NULL)", 6);
/* Make sure no data is pending write. */
_fflushbuf(stream);
while ((left > 0) && (!stream->error) && (!stream->eof)) {
ssize_t rd = read(stream->fd, buf + done, left);
if (rd < 0)
stream->error = true;
else if (rd == 0)
stream->eof = true;
else {
left -= rd;
done += rd;
}
}
return (done / size);
}
 
for (count = 0; str[count] != 0; count++);
if (write_stdout((void *) str, count) == count)
return 0;
static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
{
size_t left = size * nmemb;
size_t done = 0;
return EOF;
while ((left > 0) && (!stream->error)) {
ssize_t wr;
if (stream->klog)
wr = klog_write(buf + done, left);
else
wr = write(stream->fd, buf + done, left);
if (wr <= 0)
stream->error = true;
else {
left -= wr;
done += wr;
}
}
return (done / size);
}
 
int putchar(int c)
/** Drain stream buffer, do not sync stream. */
static void _fflushbuf(FILE *stream)
{
unsigned char ch = c;
if (write_stdout((void *) &ch, 1) == 1)
return c;
size_t bytes_used;
if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error))
return;
bytes_used = stream->buf_head - stream->buf;
if (bytes_used == 0)
return;
(void) _fwrite(stream->buf, 1, bytes_used, stream);
stream->buf_head = stream->buf;
}
 
/** Write to a stream.
*
* @param buf Source buffer.
* @param size Size of each record.
* @param nmemb Number of records to write.
* @param stream Pointer to the stream.
*
*/
size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
{
uint8_t *data;
size_t bytes_left;
size_t now;
size_t buf_free;
size_t total_written;
size_t i;
uint8_t b;
bool need_flush;
/* If not buffered stream, write out directly. */
if (stream->btype == _IONBF) {
now = _fwrite(buf, size, nmemb, stream);
fflush(stream);
return now;
}
/* Perform lazy allocation of stream buffer. */
if (stream->buf == NULL) {
if (_fallocbuf(stream) != 0)
return 0; /* Errno set by _fallocbuf(). */
}
data = (uint8_t *) buf;
bytes_left = size * nmemb;
total_written = 0;
need_flush = false;
while ((!stream->error) && (bytes_left > 0)) {
buf_free = stream->buf_size - (stream->buf_head - stream->buf);
if (bytes_left > buf_free)
now = buf_free;
else
now = bytes_left;
for (i = 0; i < now; i++) {
b = data[i];
stream->buf_head[i] = b;
if ((b == '\n') && (stream->btype == _IOLBF))
need_flush = true;
}
buf += now;
stream->buf_head += now;
buf_free -= now;
bytes_left -= now;
total_written += now;
if (buf_free == 0) {
/* Only need to drain buffer. */
_fflushbuf(stream);
need_flush = false;
}
}
if (need_flush)
fflush(stream);
return (total_written / size);
}
 
int fputc(wchar_t c, FILE *stream)
{
char buf[STR_BOUNDS(1)];
size_t sz = 0;
if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
size_t wr = fwrite(buf, sz, 1, stream);
if (wr < sz)
return EOF;
return (int) c;
}
return EOF;
}
 
int putchar(wchar_t c)
{
return fputc(c, stdout);
}
 
int fputs(const char *str, FILE *stream)
{
return fwrite(str, str_size(str), 1, stream);
}
 
int puts(const char *str)
{
return fputs(str, stdout);
}
 
int fgetc(FILE *stream)
{
char c;
/* This could be made faster by only flushing when needed. */
if (stdout)
fflush(stdout);
if (stderr)
fflush(stderr);
if (fread(&c, sizeof(char), 1, stream) < sizeof(char))
return EOF;
return (int) c;
}
 
int getchar(void)
{
unsigned char c;
if (read_stdin((void *) &c, 1) == 1)
return c;
return fgetc(stdin);
}
 
int fseek(FILE *stream, long offset, int origin)
{
off_t rc = lseek(stream->fd, offset, origin);
if (rc == (off_t) (-1)) {
/* errno has been set by lseek. */
return -1;
}
return EOF;
stream->eof = false;
return 0;
}
 
void rewind(FILE *stream)
{
(void) fseek(stream, 0, SEEK_SET);
}
 
int fflush(FILE *stream)
{
_fflushbuf(stream);
if (stream->klog) {
klog_update();
return EOK;
}
if (stream->fd >= 0)
return fsync(stream->fd);
return ENOENT;
}
 
int feof(FILE *stream)
{
return stream->eof;
}
 
int ferror(FILE *stream)
{
return stream->error;
}
 
int fphone(FILE *stream)
{
if (stream->fd >= 0) {
if (stream->phone < 0)
stream->phone = fd_phone(stream->fd);
return stream->phone;
}
return -1;
}
 
int fnode(FILE *stream, fdi_node_t *node)
{
if (stream->fd >= 0)
return fd_node(stream->fd, node);
return ENOENT;
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/io/printf_core.c
1,6 → 1,7
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
27,12 → 28,12
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
/** @addtogroup generic
* @{
*/
/**
* @file
* @brief Printing functions.
* @brief Printing functions.
*/
 
#include <unistd.h>
41,20 → 42,30
#include <ctype.h>
#include <string.h>
 
#define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/
#define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */
#define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /**< align to left */
#define __PRINTF_FLAG_SHOWPLUS 0x00000020 /**< always show + sign */
#define __PRINTF_FLAG_SPACESIGN 0x00000040 /**< print space instead of plus */
#define __PRINTF_FLAG_BIGCHARS 0x00000080 /**< show big characters */
#define __PRINTF_FLAG_NEGATIVE 0x00000100 /**< number has - sign */
/** show prefixes 0x or 0 */
#define __PRINTF_FLAG_PREFIX 0x00000001
/** signed / unsigned number */
#define __PRINTF_FLAG_SIGNED 0x00000002
/** print leading zeroes */
#define __PRINTF_FLAG_ZEROPADDED 0x00000004
/** align to left */
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010
/** always show + sign */
#define __PRINTF_FLAG_SHOWPLUS 0x00000020
/** print space instead of plus */
#define __PRINTF_FLAG_SPACESIGN 0x00000040
/** show big characters */
#define __PRINTF_FLAG_BIGCHARS 0x00000080
/** number has - sign */
#define __PRINTF_FLAG_NEGATIVE 0x00000100
 
#define PRINT_NUMBER_BUFFER_SIZE (64+5) /**< Buffer big enought for 64 bit number
* printed in base 2, sign, prefix and
* 0 to terminate string.. (last one is only for better testing
* end of buffer by zero-filling subroutine)
*/
/**
* Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0
* to terminate string... (last one is only for better testing end of buffer by
* zero-filling subroutine)
*/
#define PRINT_NUMBER_BUFFER_SIZE (64 + 5)
 
/** Enumeration of possible arguments types.
*/
typedef enum {
63,171 → 74,296
PrintfQualifierInt,
PrintfQualifierLong,
PrintfQualifierLongLong,
PrintfQualifierSizeT,
PrintfQualifierPointer
} qualifier_t;
 
static char digits_small[] = "0123456789abcdef"; /**< Small hexadecimal characters */
static char digits_big[] = "0123456789ABCDEF"; /**< Big hexadecimal characters */
static char nullstr[] = "(NULL)";
static char digits_small[] = "0123456789abcdef";
static char digits_big[] = "0123456789ABCDEF";
static char invalch = U_SPECIAL;
 
/** Print count chars from buffer without adding newline
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
* @param count
* @param ps output method and its data
* @return number of printed characters
/** Print one or more characters without adding newline.
*
* @param buf Buffer holding characters with size of
* at least size bytes. NULL is not allowed!
* @param size Size of the buffer in bytes.
* @param ps Output method and its data.
*
* @return Number of characters printed.
*
*/
static int printf_putnchars(const char * buf, size_t count,
struct printf_spec *ps)
static int printf_putnchars(const char *buf, size_t size,
printf_spec_t *ps)
{
return ps->write((void *)buf, count, ps->data);
return ps->str_write((void *) buf, size, ps->data);
}
 
/** Print string without added newline
* @param str string to print
* @param ps write function specification and support data
* @return number of printed characters
/** Print one or more wide characters without adding newline.
*
* @param buf Buffer holding wide characters with size of
* at least size bytes. NULL is not allowed!
* @param size Size of the buffer in bytes.
* @param ps Output method and its data.
*
* @return Number of wide characters printed.
*
*/
static int printf_putstr(const char * str, struct printf_spec *ps)
static int printf_wputnchars(const wchar_t *buf, size_t size,
printf_spec_t *ps)
{
size_t count;
return ps->wstr_write((void *) buf, size, ps->data);
}
 
/** Print string without adding a newline.
*
* @param str String to print.
* @param ps Write function specification and support data.
*
* @return Number of characters printed.
*
*/
static int printf_putstr(const char *str, printf_spec_t *ps)
{
if (str == NULL)
return printf_putnchars(nullstr, str_size(nullstr), ps);
if (str == NULL)
return printf_putnchars("(NULL)", 6, ps);
return ps->str_write((void *) str, str_size(str), ps->data);
}
 
count = strlen(str);
 
return ps->write((void *) str, count, ps->data);
/** Print one ASCII character.
*
* @param c ASCII character to be printed.
* @param ps Output method.
*
* @return Number of characters printed.
*
*/
static int printf_putchar(const char ch, printf_spec_t *ps)
{
if (!ascii_check(ch))
return ps->str_write((void *) &invalch, 1, ps->data);
return ps->str_write(&ch, 1, ps->data);
}
 
/** Print one character to output
* @param c one character
* @param ps output method
* @return number of printed characters
/** Print one wide character.
*
* @param c Wide character to be printed.
* @param ps Output method.
*
* @return Number of characters printed.
*
*/
static int printf_putchar(int c, struct printf_spec *ps)
static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
{
unsigned char ch = c;
if (!chr_check(ch))
return ps->str_write((void *) &invalch, 1, ps->data);
return ps->write((void *) &ch, 1, ps->data);
return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
}
 
/** Print one formatted character
* @param c character to print
* @param width
* @param flags
* @return number of printed characters
/** Print one formatted ASCII character.
*
* @param ch Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
*
* @return Number of characters printed, negative value on failure.
*
*/
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
{
int counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
/*
* One space is consumed by the character itself, hence the
* predecrement.
*/
while (--width > 0) {
if (printf_putchar(' ', ps) > 0)
++counter;
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
}
if (printf_putchar(c, ps) > 0)
if (printf_putchar(ch, ps) > 0)
counter++;
/*
* One space is consumed by the character itself, hence the
* predecrement.
*/
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
++counter;
counter++;
}
return ++counter;
return (int) (counter + 1);
}
 
/** Print one string
* @param s string
* @param width
* @param precision
* @param flags
* @return number of printed characters
/** Print one formatted wide character.
*
* @param ch Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
*
* @return Number of characters printed, negative value on failure.
*
*/
static int print_string(char *s, int width, int precision, uint64_t flags,
struct printf_spec *ps)
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
{
int counter = 0;
size_t size;
int retval;
 
if (s == NULL) {
return printf_putstr("(NULL)", ps);
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
}
size = strlen(s);
if (printf_putwchar(ch, ps) > 0)
counter++;
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
return (int) (counter + 1);
}
 
/* print leading spaces */
/** Print string.
*
* @param str String to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
*
* @return Number of characters printed, negative value on failure.
*/
static int print_str(char *str, int width, unsigned int precision,
uint32_t flags, printf_spec_t *ps)
{
if (str == NULL)
return printf_putstr(nullstr, ps);
 
if (precision == 0)
precision = size;
/* Print leading spaces. */
size_t strw = str_length(str);
if (precision == 0)
precision = strw;
 
/* Left padding */
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
 
if ((retval = printf_putnchars(s, size < precision ? size : precision,
ps)) < 0) {
/* Part of @a str fitting into the alloted space. */
int retval;
size_t size = str_lsize(str, precision);
if ((retval = printf_putnchars(str, size, ps)) < 0)
return -counter;
 
counter += retval;
 
/* Right padding */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
 
counter += retval;
return ((int) counter);
 
}
 
/** Print wide string.
*
* @param str Wide string to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
*
* @return Number of wide characters printed, negative value on failure.
*/
static int print_wstr(wchar_t *str, int width, unsigned int precision,
uint32_t flags, printf_spec_t *ps)
{
if (str == NULL)
return printf_putstr(nullstr, ps);
/* Print leading spaces. */
size_t strw = wstr_length(str);
if (precision == 0)
precision = strw;
/* Left padding */
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
/* Part of @a wstr fitting into the alloted space. */
int retval;
size_t size = wstr_lsize(str, precision);
if ((retval = printf_wputnchars(str, size, ps)) < 0)
return -counter;
counter += retval;
/* Right padding */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
++counter;
if (printf_putchar(' ', ps) == 1)
counter++;
}
return counter;
 
return ((int) counter);
}
 
 
/** Print number in given base
/** Print a number in a given base.
*
* Print significant digits of a number in given
* base.
* Print significant digits of a number in given base.
*
* @param num Number to print.
* @param width
* @param precision
* @param base Base to print the number in (should
* be in range 2 .. 16).
* @param flags output modifiers
* @return number of printed characters
* @param num Number to print.
* @param width Width modifier.
* @param precision Precision modifier.
* @param base Base to print the number in (must be between 2 and 16).
* @param flags Flags that modify the way the number is printed.
*
* @return Number of characters printed.
*
*/
static int print_number(uint64_t num, int width, int precision, int base,
uint64_t flags, struct printf_spec *ps)
uint32_t flags, printf_spec_t *ps)
{
char *digits = digits_small;
char d[PRINT_NUMBER_BUFFER_SIZE]; /* this is good enough even for
* base == 2, prefix and sign */
char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
int size = 0; /* size of number with all prefixes and signs */
int number_size; /* size of plain number */
char sgn;
int retval;
int counter = 0;
char *digits;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
else
digits = digits_small;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
char data[PRINT_NUMBER_BUFFER_SIZE];
char *ptr = &data[PRINT_NUMBER_BUFFER_SIZE - 1];
*ptr-- = 0; /* Put zero at end of string */
 
/* Size of number with all prefixes and signs */
int size = 0;
/* Put zero at end of string */
*ptr-- = 0;
if (num == 0) {
*ptr-- = '0';
size++;
238,15 → 374,17
} while (num /= base);
}
number_size = size;
 
/* Size of plain number */
int number_size = size;
/*
* Collect sum of all prefixes/signs/... to calculate padding and
* leading zeroes
* Collect the sum of all prefixes/signs/etc. to calculate padding and
* leading zeroes.
*/
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
case 2:
/* Binary formating is not standard, but usefull */
size += 2;
break;
case 8:
257,8 → 395,8
break;
}
}
 
sgn = 0;
char sgn = 0;
if (flags & __PRINTF_FLAG_SIGNED) {
if (flags & __PRINTF_FLAG_NEGATIVE) {
sgn = '-';
271,47 → 409,46
size++;
}
}
 
if (flags & __PRINTF_FLAG_LEFTALIGNED) {
if (flags & __PRINTF_FLAG_LEFTALIGNED)
flags &= ~__PRINTF_FLAG_ZEROPADDED;
}
 
/*
* If number is leftaligned or precision is specified then zeropadding
* is ignored.
* If the number is left-aligned or precision is specified then
* padding with zeros is ignored.
*/
if (flags & __PRINTF_FLAG_ZEROPADDED) {
if ((precision == 0) && (width > size)) {
if ((precision == 0) && (width > size))
precision = width - size + number_size;
}
}
 
/* print leading spaces */
 
/* We must print whole number not only a part. */
if (number_size > precision)
/* Print leading spaces */
if (number_size > precision) {
/* Print the whole number, not only a part */
precision = number_size;
 
}
width -= precision + size - number_size;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
/* print sign */
/* Print sign */
if (sgn) {
if (printf_putchar(sgn, ps) == 1)
counter++;
}
/* print prefix */
/* Print prefix */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
case 2:
/* Binary formating is not standard, but usefull */
if (printf_putchar('0', ps) == 1)
counter++;
if (flags & __PRINTF_FLAG_BIGCHARS) {
339,152 → 476,154
break;
}
}
 
/* print leading zeroes */
/* Print leading zeroes */
precision -= number_size;
while (precision-- > 0) {
while (precision-- > 0) {
if (printf_putchar('0', ps) == 1)
counter++;
}
 
/* print number itself */
 
if ((retval = printf_putstr(++ptr, ps)) > 0) {
/* Print the number itself */
int retval;
if ((retval = printf_putstr(++ptr, ps)) > 0)
counter += retval;
}
/* print ending spaces */
/* Print tailing spaces */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
 
return counter;
return ((int) counter);
}
 
 
/** Print formatted string.
*
* Print string formatted according to the fmt parameter and variadic arguments.
* Each formatting directive must have the following form:
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* FLAGS:@n
* - "#" Force to print prefix.
* For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and
* 0X and for conversion \%b the prefix is 0b.
* - "#" Force to print prefix. For \%o conversion, the prefix is 0, for
* \%x and \%X prefixes are 0x and 0X and for conversion \%b the
* prefix is 0b.
*
* - "-" Align to left.
* - "-" Align to left.
*
* - "+" Print positive sign just as negative.
* - "+" Print positive sign just as negative.
*
* - " " If the printed number is positive and "+" flag is not set,
* print space in place of sign.
* - " " If the printed number is positive and "+" flag is not set,
* print space in place of sign.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between
* sign and the rest of the number. This flag is ignored if "-"
* flag is specified.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between
* sign and the rest of the number. This flag is ignored if "-"
* flag is specified.
*
* WIDTH:@n
* - Specify minimal width of printed argument. If it is bigger, width is
* ignored. If width is specified with a "*" character instead of number,
* width is taken from parameter list. And integer parameter is expected
* before parameter for processed conversion specification. If this value
* is negative its absolute value is taken and the "-" flag is set.
* - Specify the minimal width of a printed argument. If it is bigger,
* width is ignored. If width is specified with a "*" character instead of
* number, width is taken from parameter list. And integer parameter is
* expected before parameter for processed conversion specification. If
* this value is negative its absolute value is taken and the "-" flag is
* set.
*
* PRECISION:@n
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are
* not affected. Strings with more than precision characters are cut off.
* Just as with width, an "*" can be used used instead of a number. An
* integer value is then expected in parameters. When both width and
* precision are specified using "*", the first parameter is used for
* width and the second one for precision.
*
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are not
* affected. Strings with more than precision characters are cut off. Just
* as with width, an "*" can be used used instead of a number. An integer
* value is then expected in parameters. When both width and precision are
* specified using "*", the first parameter is used for width and the
* second one for precision.
*
* TYPE:@n
* - "hh" Signed or unsigned char.@n
* - "h" Signed or usigned short.@n
* - "" Signed or usigned int (default value).@n
* - "l" Signed or usigned long int.@n
* - "ll" Signed or usigned long long int.@n
* - "z" Type size_t.@n
*
*
* - "hh" Signed or unsigned char.@n
* - "h" Signed or unsigned short.@n
* - "" Signed or unsigned int (default value).@n
* - "l" Signed or unsigned long int.@n
* If conversion is "c", the character is wchar_t (wide character).@n
* If conversion is "s", the string is wchar_t * (wide string).@n
* - "ll" Signed or unsigned long long int.@n
*
* CONVERSION:@n
* - % Print percentile character itself.
* - % Print percentile character itself.
*
* - c Print single character.
* - c Print single character. The character is expected to be plain
* ASCII (e.g. only values 0 .. 127 are valid).@n
* If type is "l", then the character is expected to be wide character
* (e.g. values 0 .. 0x10ffff are valid).
*
* - s Print zero terminated string. If a NULL value is passed as
* value, "(NULL)" is printed instead.
*
* - P, p Print value of a pointer. Void * value is expected and it is
* printed in hexadecimal notation with prefix (as with '\%#X' or
* '\%#x' for 32bit or '\%#X' or '\%#x' for 64bit long pointers).
* - s Print zero terminated string. If a NULL value is passed as
* value, "(NULL)" is printed instead.@n
* If type is "l", then the string is expected to be wide string.
*
* - b Print value as unsigned binary number. Prefix is not printed by
* default. (Nonstandard extension.)
*
* - o Print value as unsigned octal number. Prefix is not printed by
* default.
* - P, p Print value of a pointer. Void * value is expected and it is
* printed in hexadecimal notation with prefix (as with \%#X / \%#x
* for 32-bit or \%#X / \%#x for 64-bit long pointers).
*
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
* - b Print value as unsigned binary number. Prefix is not printed by
* default. (Nonstandard extension.)
*
* - u Print unsigned decimal number.
* - o Print value as unsigned octal number. Prefix is not printed by
* default.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
* not printed by default.
*
* All other characters from fmt except the formatting directives are printed in
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
*
* - u Print unsigned decimal number.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
* not printed by default.
*
* All other characters from fmt except the formatting directives are printed
* verbatim.
*
* @param fmt Formatting NULL terminated string.
* @return Number of printed characters or negative value on failure.
* @param fmt Format NULL-terminated string.
*
* @return Number of characters printed, negative value on failure.
*
*/
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
{
/* i is the index of the currently processed char from fmt */
int i = 0;
/* j is the index to the first not printed nonformating character */
int j = 0;
 
int end;
int counter; /* counter of printed characters */
int retval; /* used to store return values from called functions */
char c;
qualifier_t qualifier; /* type of argument */
int base; /* base in which will be a numeric parameter printed */
uint64_t number; /* argument value */
size_t size; /* byte size of integer parameter */
int width, precision;
uint64_t flags;
size_t i; /* Index of the currently processed character from fmt */
size_t nxt = 0; /* Index of the next character from fmt */
size_t j = 0; /* Index to the first not printed nonformating character */
counter = 0;
size_t counter = 0; /* Number of characters printed */
int retval; /* Return values from nested functions */
while ((c = fmt[i])) {
/* control character */
if (c == '%' ) {
/* print common characters if any processed */
while (true) {
i = nxt;
wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
/* Control character */
if (uc == '%') {
/* Print common characters if any processed */
if (i > j) {
if ((retval = printf_putnchars(&fmt[j],
(size_t)(i - j), ps)) < 0) { /* error */
goto minus_out;
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
/* Error */
counter = -counter;
goto out;
}
counter += retval;
}
j = i;
/* parse modifiers */
flags = 0;
end = 0;
/* Parse modifiers */
uint32_t flags = 0;
bool end = false;
do {
++i;
switch (c = fmt[i]) {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
switch (uc) {
case '#':
flags |= __PRINTF_FLAG_PREFIX;
break;
501,114 → 640,145
flags |= __PRINTF_FLAG_ZEROPADDED;
break;
default:
end = 1;
};
} while (end == 0);
end = true;
};
} while (!end);
/* width & '*' operator */
width = 0;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
/* Width & '*' operator */
int width = 0;
if (isdigit(uc)) {
while (true) {
width *= 10;
width += fmt[i++] - '0';
width += uc - '0';
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
if (!isdigit(uc))
break;
}
} else if (fmt[i] == '*') {
/* get width value from argument list*/
i++;
width = (int)va_arg(ap, int);
} else if (uc == '*') {
/* Get width value from argument list */
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
width = (int) va_arg(ap, int);
if (width < 0) {
/* negative width sets '-' flag */
/* Negative width sets '-' flag */
width *= -1;
flags |= __PRINTF_FLAG_LEFTALIGNED;
}
}
/* precision and '*' operator */
precision = 0;
if (fmt[i] == '.') {
++i;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
/* Precision and '*' operator */
int precision = 0;
if (uc == '.') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (isdigit(uc)) {
while (true) {
precision *= 10;
precision += fmt[i++] - '0';
precision += uc - '0';
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
if (!isdigit(uc))
break;
}
} else if (fmt[i] == '*') {
/* get precision value from argument */
i++;
precision = (int)va_arg(ap, int);
} else if (uc == '*') {
/* Get precision value from the argument list */
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
precision = (int) va_arg(ap, int);
if (precision < 0) {
/* negative precision ignored */
/* Ignore negative precision */
precision = 0;
}
}
}
 
switch (fmt[i++]) {
/** @todo unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
qualifier_t qualifier;
switch (uc) {
/** @todo Unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
*/
case 'h': /* char or short */
case 'h':
/* Char or short */
qualifier = PrintfQualifierShort;
if (fmt[i] == 'h') {
i++;
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 'h') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
qualifier = PrintfQualifierByte;
}
break;
case 'l': /* long or long long*/
case 'l':
/* Long or long long */
qualifier = PrintfQualifierLong;
if (fmt[i] == 'l') {
i++;
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 'l') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
qualifier = PrintfQualifierLongLong;
}
break;
case 'z': /* size_t */
qualifier = PrintfQualifierSizeT;
break;
default:
/* set default type */
/* Default type */
qualifier = PrintfQualifierInt;
--i;
}
}
base = 10;
 
switch (c = fmt[i]) {
 
unsigned int base = 10;
switch (uc) {
/*
* String and character conversions.
*/
case 's':
if ((retval = print_string(va_arg(ap, char*),
width, precision, flags, ps)) < 0) {
goto minus_out;
if (qualifier == PrintfQualifierLong)
retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
else
retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
if (retval < 0) {
counter = -counter;
goto out;
}
counter += retval;
j = i + 1;
j = nxt;
goto next_char;
case 'c':
c = va_arg(ap, unsigned int);
retval = print_char(c, width, flags, ps);
if (qualifier == PrintfQualifierLong)
retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps);
else
retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
if (retval < 0) {
goto minus_out;
}
 
counter = -counter;
goto out;
};
counter += retval;
j = i + 1;
j = nxt;
goto next_char;
 
/*
/*
* Integer values
*/
case 'P': /* pointer */
flags |= __PRINTF_FLAG_BIGCHARS;
case 'P':
/* Pointer */
flags |= __PRINTF_FLAG_BIGCHARS;
case 'p':
flags |= __PRINTF_FLAG_PREFIX;
base = 16;
qualifier = PrintfQualifierPointer;
break;
case 'b':
break;
case 'b':
base = 2;
break;
case 'o':
616,7 → 786,7
break;
case 'd':
case 'i':
flags |= __PRINTF_FLAG_SIGNED;
flags |= __PRINTF_FLAG_SIGNED;
case 'u':
break;
case 'X':
624,66 → 794,63
case 'x':
base = 16;
break;
/* percentile itself */
case '%':
/* Percentile itself */
case '%':
j = i;
goto next_char;
/*
* Bad formatting.
*/
default:
/*
* Unknown format. Now, j is the index of '%',
* so we will print the whole bad format
* sequence.
* Unknown format. Now, j is the index of '%'
* so we will print whole bad format sequence.
*/
goto next_char;
goto next_char;
}
/* Print integers */
size_t size;
uint64_t number;
switch (qualifier) {
case PrintfQualifierByte:
size = sizeof(unsigned char);
number = (uint64_t)va_arg(ap, unsigned int);
number = (uint64_t) va_arg(ap, unsigned int);
break;
case PrintfQualifierShort:
size = sizeof(unsigned short);
number = (uint64_t)va_arg(ap, unsigned int);
number = (uint64_t) va_arg(ap, unsigned int);
break;
case PrintfQualifierInt:
size = sizeof(unsigned int);
number = (uint64_t)va_arg(ap, unsigned int);
number = (uint64_t) va_arg(ap, unsigned int);
break;
case PrintfQualifierLong:
size = sizeof(unsigned long);
number = (uint64_t)va_arg(ap, unsigned long);
number = (uint64_t) va_arg(ap, unsigned long);
break;
case PrintfQualifierLongLong:
size = sizeof(unsigned long long);
number = (uint64_t)va_arg(ap,
unsigned long long);
number = (uint64_t) va_arg(ap, unsigned long long);
break;
case PrintfQualifierPointer:
size = sizeof(void *);
number = (uint64_t)(unsigned long)va_arg(ap,
void *);
number = (uint64_t) (unsigned long) va_arg(ap, void *);
break;
case PrintfQualifierSizeT:
size = sizeof(size_t);
number = (uint64_t)va_arg(ap, size_t);
break;
default: /* Unknown qualifier */
goto minus_out;
default:
/* Unknown qualifier */
counter = -counter;
goto out;
}
if (flags & __PRINTF_FLAG_SIGNED) {
if (number & (0x1 << (size * 8 - 1))) {
flags |= __PRINTF_FLAG_NEGATIVE;
if (size == sizeof(uint64_t)) {
number = -((int64_t)number);
number = -((int64_t) number);
} else {
number = ~number;
number &=
693,31 → 860,31
}
}
}
 
if ((retval = print_number(number, width, precision,
base, flags, ps)) < 0 ) {
goto minus_out;
base, flags, ps)) < 0) {
counter = -counter;
goto out;
}
 
counter += retval;
j = i + 1;
}
j = nxt;
}
next_char:
++i;
;
}
if (i > j) {
retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps);
if (retval < 0) { /* error */
goto minus_out;
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
/* Error */
counter = -counter;
goto out;
}
counter += retval;
}
return counter;
minus_out:
return -counter;
out:
return ((int) counter);
}
 
/** @}
/branches/arm/uspace/lib/libc/generic/io/vprintf.c
38,39 → 38,81
#include <io/printf_core.h>
#include <futex.h>
#include <async.h>
#include <string.h>
 
static atomic_t printf_futex = FUTEX_INITIALIZER;
 
static int vprintf_write(const char *str, size_t count, void *unused)
static int vprintf_str_write(const char *str, size_t size, void *stream)
{
return write_stdout(str, count);
size_t wr = fwrite(str, 1, size, (FILE *) stream);
return str_nlength(str, wr);
}
 
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream)
{
size_t offset = 0;
size_t chars = 0;
while (offset < size) {
if (fputc(str[chars], (FILE *) stream) <= 0)
break;
chars++;
offset += sizeof(wchar_t);
}
return chars;
}
 
/** Print formatted text.
* @param fmt format string
* @param ap format parameters
*
* @param stream Output stream
* @param fmt Format string
* @param ap Format parameters
*
* \see For more details about format string see printf_core.
*
*/
int vprintf(const char *fmt, va_list ap)
int vfprintf(FILE *stream, const char *fmt, va_list ap)
{
struct printf_spec ps = {
(int (*)(void *, size_t, void *)) vprintf_write,
NULL
vprintf_str_write,
vprintf_wstr_write,
stream
};
/*
* Prevent other threads to execute printf_core()
*/
futex_down(&printf_futex);
/*
* Prevent other pseudo threads of the same thread
* Prevent other fibrils of the same thread
* to execute printf_core()
*/
async_serialize_start();
int ret = printf_core(fmt, &ps, ap);
async_serialize_end();
futex_up(&printf_futex);
return ret;
}
 
/** Print formatted text to stdout.
*
* @param file Output stream
* @param fmt Format string
* @param ap Format parameters
*
* \see For more details about format string see printf_core.
*
*/
int vprintf(const char *fmt, va_list ap)
{
return vfprintf(stdout, fmt, ap);
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/io/printf.c
34,23 → 34,43
 
#include <io/printf_core.h>
#include <stdio.h>
#include <stdio.h>
 
/** Print formatted text.
* @param fmt format string
*
* @param stream Output stream
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int fprintf(FILE *stream, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vfprintf(stream, fmt, args);
va_end(args);
return ret;
}
 
/** Print formatted text to stdout.
*
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int printf(const char *fmt, ...)
{
int ret;
va_list args;
 
va_start(args, fmt);
 
ret = vprintf(fmt, args);
int ret = vprintf(fmt, args);
va_end(args);
 
return ret;
}
 
/branches/arm/uspace/lib/libc/generic/io/snprintf.c
37,21 → 37,23
#include <io/printf_core.h>
 
/** Print formatted to the given buffer with limited size.
* @param str buffer
* @param size buffer size
* @param fmt format string
*
* @param str Buffer
* @param size Buffer size
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int snprintf(char *str, size_t size, const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
va_start(args, fmt);
ret = vsnprintf(str, size, fmt, args);
 
int ret = vsnprintf(str, size, fmt, args);
va_end(args);
 
return ret;
}
 
/branches/arm/uspace/lib/libc/generic/io/asprintf.c
36,42 → 36,52
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io/printf_core.h>
 
static int asprintf_prewrite(const char *str, size_t count, void *unused)
static int asprintf_str_write(const char *str, size_t count, void *unused)
{
return count;
return str_nlength(str, count);
}
 
static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused)
{
return wstr_nlength(str, count);
}
 
/** Allocate and print to string.
*
* @param strp Address of the pointer where to store the address of
* the newly allocated string.
* @fmt Format strin.
* @param strp Address of the pointer where to store the address of
* the newly allocated string.
* @fmt Format string.
*
* @return Number of characters printed or a negative error code.
* @return Number of characters printed or a negative error code.
*
*/
int asprintf(char **strp, const char *fmt, ...)
{
struct printf_spec ps = {
asprintf_prewrite,
NULL
asprintf_str_write,
asprintf_wstr_write,
NULL
};
int ret;
va_list args;
 
va_start(args, fmt);
ret = printf_core(fmt, &ps, args);
int ret = printf_core(fmt, &ps, args);
va_end(args);
if (ret > 0) {
*strp = malloc(ret + 20);
if (!*strp)
*strp = malloc(STR_BOUNDS(ret) + 1);
if (*strp == NULL)
return -1;
va_start(args, fmt);
vsprintf(*strp, fmt, args);
va_end(args);
vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args);
va_end(args);
}
 
return ret;
}
 
/branches/arm/uspace/lib/libc/generic/io/vsnprintf.c
36,87 → 36,145
#include <stdio.h>
#include <string.h>
#include <io/printf_core.h>
#include <errno.h>
 
struct vsnprintf_data {
size_t size; /* total space for string */
size_t len; /* count of currently used characters */
char *string; /* destination string */
};
typedef struct {
size_t size; /* Total size of the buffer (in bytes) */
size_t len; /* Number of already used bytes */
char *dst; /* Destination */
} vsnprintf_data_t;
 
/** Write string to given buffer.
* Write at most data->size characters including trailing zero. According to C99
* has snprintf to return number of characters that would have been written if
* enough space had been available. Hence the return value is not number of
* really printed characters but size of input string. Number of really used
* characters is stored in data->len.
*
* @param str Source string to print.
* @param count Size of the source string.
* @param data Structure with destination string, counter of used space
* and total string size.
* @return Number of characters to print (not characters really
* printed!)
* Write at most data->size plain characters including trailing zero.
* According to C99, snprintf() has to return number of characters that
* would have been written if enough space had been available. Hence
* the return value is not the number of actually printed characters
* but size of the input string.
*
* @param str Source string to print.
* @param size Number of plain characters in str.
* @param data Structure describing destination string, counter
* of used space and total string size.
*
* @return Number of characters to print (not characters actually
* printed).
*
*/
static int
vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data)
{
size_t i;
i = data->size - data->len;
 
if (i == 0) {
return count;
}
size_t left = data->size - data->len;
if (i == 1) {
/*
* We have only one free byte left in buffer => write there
* trailing zero.
if (left == 0)
return ((int) size);
if (left == 1) {
/* We have only one free byte left in buffer
* -> store trailing zero
*/
data->string[data->size - 1] = 0;
data->dst[data->size - 1] = 0;
data->len = data->size;
return count;
return ((int) size);
}
if (i <= count) {
/*
* We have not enought space for whole string with the trailing
* zero => print only a part of string.
if (left <= size) {
/* We do not have enough space for the whole string
* with the trailing zero => print only a part
* of string
*/
memcpy((void *)(data->string + data->len), (void *)str, i - 1);
data->string[data->size - 1] = 0;
data->len = data->size;
return count;
size_t index = 0;
while (index < size) {
wchar_t uc = str_decode(str, &index, size);
if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
break;
}
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
/* Buffer is big enought to print whole string */
memcpy((void *)(data->string + data->len), (void *)str, count);
data->len += count;
/*
* Put trailing zero at end, but not count it into data->len so it could
* be rewritten next time.
/* Buffer is big enought to print the whole string */
memcpy((void *)(data->dst + data->len), (void *) str, size);
data->len += size;
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->string[data->len] = 0;
data->dst[data->len] = 0;
return ((int) size);
}
 
return count;
/** Write wide string to given buffer.
*
* Write at most data->size plain characters including trailing zero.
* According to C99, snprintf() has to return number of characters that
* would have been written if enough space had been available. Hence
* the return value is not the number of actually printed characters
* but size of the input string.
*
* @param str Source wide string to print.
* @param size Number of bytes in str.
* @param data Structure describing destination string, counter
* of used space and total string size.
*
* @return Number of wide characters to print (not characters actually
* printed).
*
*/
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
{
size_t index = 0;
while (index < (size / sizeof(wchar_t))) {
size_t left = data->size - data->len;
if (left == 0)
return ((int) size);
if (left == 1) {
/* We have only one free byte left in buffer
* -> store trailing zero
*/
data->dst[data->size - 1] = 0;
data->len = data->size;
return ((int) size);
}
if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK)
break;
index++;
}
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
 
/** Print formatted to the given buffer with limited size.
* @param str Buffer.
* @param size Bffer size.
* @param fmt Format string.
* \see For more details about format string see printf_core.
*/
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
struct vsnprintf_data data = {size, 0, str};
struct printf_spec ps = {
(int(*)(void *, size_t, void *)) vsnprintf_write,
vsnprintf_data_t data = {
size,
0,
str
};
printf_spec_t ps = {
(int(*) (const char *, size_t, void *)) vsnprintf_str_write,
(int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
&data
};
 
/*
* Print 0 at end of string - fix the case that nothing will be printed.
*/
/* Print 0 at end of string - fix the case that nothing will be printed */
if (size > 0)
str[0] = 0;
/branches/arm/uspace/lib/libc/generic/io/klog.c
0,0 → 1,53
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2006 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <libc.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <io/klog.h>
 
size_t klog_write(const void *buf, size_t size)
{
return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
}
 
void klog_update(void)
{
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/malloc.c
0,0 → 1,475
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Petr Tuma
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <malloc.h>
#include <bool.h>
#include <as.h>
#include <align.h>
#include <macros.h>
#include <assert.h>
#include <errno.h>
#include <bitops.h>
#include <mem.h>
#include <adt/gcdlcm.h>
 
/* Magic used in heap headers. */
#define HEAP_BLOCK_HEAD_MAGIC 0xBEEF0101
 
/* Magic used in heap footers. */
#define HEAP_BLOCK_FOOT_MAGIC 0xBEEF0202
 
/** Allocation alignment (this also covers the alignment of fields
in the heap header and footer) */
#define BASE_ALIGN 16
 
/**
* Either 4 * 256M on 32-bit architecures or 16 * 256M on 64-bit architectures
*/
#define MAX_HEAP_SIZE (sizeof(uintptr_t) << 28)
 
/**
*
*/
#define STRUCT_OVERHEAD (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
 
/**
* Calculate real size of a heap block (with header and footer)
*/
#define GROSS_SIZE(size) ((size) + STRUCT_OVERHEAD)
 
/**
* Calculate net size of a heap block (without header and footer)
*/
#define NET_SIZE(size) ((size) - STRUCT_OVERHEAD)
 
 
/** Header of a heap block
*
*/
typedef struct {
/* Size of the block (including header and footer) */
size_t size;
/* Indication of a free block */
bool free;
/* A magic value to detect overwrite of heap header */
uint32_t magic;
} heap_block_head_t;
 
/** Footer of a heap block
*
*/
typedef struct {
/* Size of the block (including header and footer) */
size_t size;
/* A magic value to detect overwrite of heap footer */
uint32_t magic;
} heap_block_foot_t;
 
/** Linker heap symbol */
extern char _heap;
 
/** Address of heap start */
static void *heap_start = 0;
 
/** Address of heap end */
static void *heap_end = 0;
 
/** Maximum heap size */
static size_t max_heap_size = (size_t) -1;
 
/** Current number of pages of heap area */
static size_t heap_pages = 0;
 
/** Initialize a heap block
*
* Fills in the structures related to a heap block.
*
* @param addr Address of the block.
* @param size Size of the block including the header and the footer.
* @param free Indication of a free block.
*
*/
static void block_init(void *addr, size_t size, bool free)
{
/* Calculate the position of the header and the footer */
heap_block_head_t *head = (heap_block_head_t *) addr;
heap_block_foot_t *foot =
(heap_block_foot_t *) (addr + size - sizeof(heap_block_foot_t));
head->size = size;
head->free = free;
head->magic = HEAP_BLOCK_HEAD_MAGIC;
foot->size = size;
foot->magic = HEAP_BLOCK_FOOT_MAGIC;
}
 
/** Check a heap block
*
* Verifies that the structures related to a heap block still contain
* the magic constants. This helps detect heap corruption early on.
*
* @param addr Address of the block.
*
*/
static void block_check(void *addr)
{
heap_block_head_t *head = (heap_block_head_t *) addr;
assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
heap_block_foot_t *foot =
(heap_block_foot_t *) (addr + head->size - sizeof(heap_block_foot_t));
assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
assert(head->size == foot->size);
}
 
static bool grow_heap(size_t size)
{
if (size == 0)
return false;
size_t heap_size = (size_t) (heap_end - heap_start);
if ((max_heap_size != (size_t) -1) && (heap_size + size > max_heap_size))
return false;
size_t pages = (size - 1) / PAGE_SIZE + 1;
if (as_area_resize((void *) &_heap, (heap_pages + pages) * PAGE_SIZE, 0)
== EOK) {
void *end = (void *) ALIGN_DOWN(((uintptr_t) &_heap) +
(heap_pages + pages) * PAGE_SIZE, BASE_ALIGN);
block_init(heap_end, end - heap_end, true);
heap_pages += pages;
heap_end = end;
return true;
}
return false;
}
 
static void shrink_heap(void)
{
// TODO
}
 
/** Initialize the heap allocator
*
* Finds how much physical memory we have and creates
* the heap management structures that mark the whole
* physical memory as a single free block.
*
*/
void __heap_init(void)
{
if (as_area_create((void *) &_heap, PAGE_SIZE,
AS_AREA_WRITE | AS_AREA_READ)) {
heap_pages = 1;
heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN);
heap_end =
(void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN);
/* Make the entire area one large block. */
block_init(heap_start, heap_end - heap_start, true);
}
}
 
uintptr_t get_max_heap_addr(void)
{
if (max_heap_size == (size_t) -1)
max_heap_size =
max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
return ((uintptr_t) heap_start + max_heap_size);
}
 
static void split_mark(heap_block_head_t *cur, const size_t size)
{
assert(cur->size >= size);
/* See if we should split the block. */
size_t split_limit = GROSS_SIZE(size);
if (cur->size > split_limit) {
/* Block big enough -> split. */
void *next = ((void *) cur) + size;
block_init(next, cur->size - size, true);
block_init(cur, size, false);
} else {
/* Block too small -> use as is. */
cur->free = false;
}
}
 
/** Allocate a memory block
*
* @param size The size of the block to allocate.
* @param align Memory address alignment.
*
* @return the address of the block or NULL when not enough memory.
*
*/
static void *malloc_internal(const size_t size, const size_t align)
{
if (align == 0)
return NULL;
size_t falign = lcm(align, BASE_ALIGN);
size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
bool grown = false;
void *result;
loop:
result = NULL;
heap_block_head_t *cur = (heap_block_head_t *) heap_start;
while ((result == NULL) && ((void *) cur < heap_end)) {
block_check(cur);
/* Try to find a block that is free and large enough. */
if ((cur->free) && (cur->size >= real_size)) {
/* We have found a suitable block.
Check for alignment properties. */
void *addr = ((void *) cur) + sizeof(heap_block_head_t);
void *aligned = (void *) ALIGN_UP(addr, falign);
if (addr == aligned) {
/* Exact block start including alignment. */
split_mark(cur, real_size);
result = addr;
} else {
/* Block start has to be aligned */
size_t excess = (size_t) (aligned - addr);
if (cur->size >= real_size + excess) {
/* The current block is large enough to fit
data in including alignment */
if ((void *) cur > heap_start) {
/* There is a block before the current block.
This previous block can be enlarged to compensate
for the alignment excess */
heap_block_foot_t *prev_foot =
((void *) cur) - sizeof(heap_block_foot_t);
heap_block_head_t *prev_head =
(heap_block_head_t *) (((void *) cur) - prev_foot->size);
block_check(prev_head);
size_t reduced_size = cur->size - excess;
heap_block_head_t *next_head = ((void *) cur) + excess;
if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) {
/* The previous block is not free and there is enough
space to fill in a new free block between the previous
and current block */
block_init(cur, excess, true);
} else {
/* The previous block is free (thus there is no need to
induce additional fragmentation to the heap) or the
excess is small, thus just enlarge the previous block */
block_init(prev_head, prev_head->size + excess, prev_head->free);
}
block_init(next_head, reduced_size, true);
split_mark(next_head, real_size);
result = aligned;
cur = next_head;
} else {
/* The current block is the first block on the heap.
We have to make sure that the alignment excess
is large enough to fit a new free block just
before the current block */
while (excess < STRUCT_OVERHEAD) {
aligned += falign;
excess += falign;
}
/* Check for current block size again */
if (cur->size >= real_size + excess) {
size_t reduced_size = cur->size - excess;
cur = (heap_block_head_t *) (heap_start + excess);
block_init(heap_start, excess, true);
block_init(cur, reduced_size, true);
split_mark(cur, real_size);
result = aligned;
}
}
}
}
}
/* Advance to the next block. */
cur = (heap_block_head_t *) (((void *) cur) + cur->size);
}
if ((result == NULL) && (!grown)) {
if (grow_heap(real_size)) {
grown = true;
goto loop;
}
}
return result;
}
 
void *malloc(const size_t size)
{
return malloc_internal(size, BASE_ALIGN);
}
 
void *memalign(const size_t align, const size_t size)
{
if (align == 0)
return NULL;
size_t palign =
1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
return malloc_internal(size, palign);
}
 
void *realloc(const void *addr, const size_t size)
{
if (addr == NULL)
return malloc(size);
/* Calculate the position of the header. */
heap_block_head_t *head =
(heap_block_head_t *) (addr - sizeof(heap_block_head_t));
assert((void *) head >= heap_start);
assert((void *) head < heap_end);
block_check(head);
assert(!head->free);
void *ptr = NULL;
size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN));
size_t orig_size = head->size;
if (orig_size > real_size) {
/* Shrink */
if (orig_size - real_size >= STRUCT_OVERHEAD) {
/* Split the original block to a full block
and a tailing free block */
block_init((void *) head, real_size, false);
block_init((void *) head + real_size,
orig_size - real_size, true);
shrink_heap();
}
ptr = ((void *) head) + sizeof(heap_block_head_t);
} else {
/* Look at the next block. If it is free and the size is
sufficient then merge the two. */
heap_block_head_t *next_head =
(heap_block_head_t *) (((void *) head) + head->size);
if (((void *) next_head < heap_end) &&
(head->size + next_head->size >= real_size) &&
(next_head->free)) {
block_check(next_head);
block_init(head, head->size + next_head->size, false);
split_mark(head, ALIGN_UP(size, BASE_ALIGN));
ptr = ((void *) head) + sizeof(heap_block_head_t);
} else {
ptr = malloc(size);
if (ptr != NULL) {
memcpy(ptr, addr, NET_SIZE(orig_size));
free(addr);
}
}
}
return ptr;
}
 
/** Free a memory block
*
* @param addr The address of the block.
*/
void free(const void *addr)
{
/* Calculate the position of the header. */
heap_block_head_t *head
= (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
assert((void *) head >= heap_start);
assert((void *) head < heap_end);
block_check(head);
assert(!head->free);
/* Mark the block itself as free. */
head->free = true;
/* Look at the next block. If it is free, merge the two. */
heap_block_head_t *next_head
= (heap_block_head_t *) (((void *) head) + head->size);
if ((void *) next_head < heap_end) {
block_check(next_head);
if (next_head->free)
block_init(head, head->size + next_head->size, true);
}
/* Look at the previous block. If it is free, merge the two. */
if ((void *) head > heap_start) {
heap_block_foot_t *prev_foot =
(heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
heap_block_head_t *prev_head =
(heap_block_head_t *) (((void *) head) - prev_foot->size);
block_check(prev_head);
if (prev_head->free)
block_init(prev_head, prev_head->size + head->size, true);
}
shrink_heap();
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/fibril.c
33,7 → 33,7
/** @file
*/
 
#include <libadt/list.h>
#include <adt/list.h>
#include <fibril.h>
#include <thread.h>
#include <tls.h>
49,7 → 49,8
#define FIBRIL_INITIAL_STACK_PAGES_NO 1
#endif
 
/** This futex serializes access to ready_list, serialized_list and manage_list.
/**
* This futex serializes access to ready_list, serialized_list and manager_list.
*/
static atomic_t fibril_futex = FUTEX_INITIALIZER;
 
59,12 → 60,12
 
static void fibril_main(void);
 
/** Number of fibrils that are in async_serialized mode */
static int serialized_fibrils; /* Protected by async_futex */
/** Thread-local count of serialization. If >0, we must not preempt */
static __thread int serialization_count;
/** Counter for fibrils residing in async_manager */
static int fibrils_in_manager;
/** Number of threads that are executing a manager fibril. */
static int threads_in_manager;
/** Number of threads that are executing a manager fibril and are serialized. */
static int serialized_threads; /* Protected by async_futex */
/** Fibril-local count of serialization. If > 0, we must not preempt */
static fibril_local int serialization_count;
 
/** Setup fibril information into TCB structure */
fibril_t *fibril_setup(void)
143,11 → 144,11
if (list_empty(&ready_list) && list_empty(&serialized_list))
goto ret_0;
/*
* Do not preempt if there is not sufficient count of fibril
* managers.
* Do not preempt if there is not enough threads to run the
* ready fibrils which are not serialized.
*/
if (list_empty(&serialized_list) &&
fibrils_in_manager <= serialized_fibrils) {
threads_in_manager <= serialized_threads) {
goto ret_0;
}
}
194,7 → 195,7
list_append(&srcf->link, &ready_list);
else if (stype == FIBRIL_FROM_MANAGER) {
list_append(&srcf->link, &manager_list);
fibrils_in_manager--;
threads_in_manager--;
} else {
/*
* If stype == FIBRIL_TO_MANAGER, don't put ourselves to
208,10 → 209,10
if (stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) {
dstf = list_get_instance(manager_list.next, fibril_t, link);
if (serialization_count && stype == FIBRIL_TO_MANAGER) {
serialized_fibrils++;
serialized_threads++;
srcf->flags |= FIBRIL_SERIALIZED;
}
fibrils_in_manager++;
threads_in_manager++;
 
if (stype == FIBRIL_FROM_DEAD)
dstf->clean_after_me = srcf;
219,7 → 220,7
if (!list_empty(&serialized_list)) {
dstf = list_get_instance(serialized_list.next, fibril_t,
link);
serialized_fibrils--;
serialized_threads--;
} else {
dstf = list_get_instance(ready_list.next, fibril_t,
link);
269,7 → 270,7
 
/** Add a fibril to the ready list.
*
* @param fid Pinter to the fibril structure of the fibril to be
* @param fid Pointer to the fibril structure of the fibril to be
* added.
*/
void fibril_add_ready(fid_t fid)
287,7 → 288,8
 
/** Add a fibril to the manager list.
*
* @param fid Pinter to the fibril structure of the fibril to be added.
* @param fid Pointer to the fibril structure of the fibril to be
* added.
*/
void fibril_add_manager(fid_t fid)
{
314,7 → 316,8
 
/** Return fibril id of the currently running fibril.
*
* @return Fibril ID of the currently running pseudo thread.
* @return fibril ID of the currently running fibril.
*
*/
fid_t fibril_get_id(void)
{
321,13 → 324,14
return (fid_t) __tcb_get()->fibril_data;
}
 
/** Disable preemption
/** Disable preemption
*
* If the fibril wants to send several message in a row and does not want to be
* preempted, it should start async_serialize_start() in the beginning of
* communication and async_serialize_end() in the end. If it is a true
* multithreaded application, it should protect the communication channel by a
* futex as well. Interrupt messages can still be preempted.
* futex as well.
*
*/
void fibril_inc_sercount(void)
{
/branches/arm/uspace/lib/libc/generic/task.c
31,7 → 31,7
* @{
*/
/** @file
*/
*/
 
#include <task.h>
#include <libc.h>
38,74 → 38,133
#include <stdlib.h>
#include <errno.h>
#include <loader/loader.h>
#include <string.h>
#include <ipc/ns.h>
#include <macros.h>
#include <async.h>
 
task_id_t task_get_id(void)
{
task_id_t task_id;
 
(void) __SYSCALL1(SYS_TASK_GET_ID, (sysarg_t) &task_id);
 
return task_id;
}
 
/** Set the task name.
*
* @param name The new name, typically the command used to execute the
* program.
*
* @return Zero on success or negative error code.
*
*/
int task_set_name(const char *name)
{
return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name));
}
 
/** Create a new task by running an executable from the filesystem.
*
* This is really just a convenience wrapper over the more complicated
* loader API.
*
* @param path pathname of the binary to execute
* @param argv command-line arguments
* @return ID of the newly created task or zero on error.
* @param path pathname of the binary to execute
* @param argv command-line arguments
*
* @return ID of the newly created task or zero on error.
*
*/
task_id_t task_spawn(const char *path, char *const argv[])
task_id_t task_spawn(const char *path, char *const args[])
{
loader_t *ldr;
task_id_t task_id;
int rc;
 
/* Spawn a program loader. */
ldr = loader_spawn();
/* Connect to a program loader. */
loader_t *ldr = loader_connect();
if (ldr == NULL)
return 0;
 
/* Get task ID. */
rc = loader_get_task_id(ldr, &task_id);
task_id_t task_id;
int rc = loader_get_task_id(ldr, &task_id);
if (rc != EOK)
goto error;
 
/* Send program pathname. */
rc = loader_set_pathname(ldr, path);
if (rc != EOK)
goto error;
 
/* Send arguments. */
rc = loader_set_args(ldr, argv);
rc = loader_set_args(ldr, args);
if (rc != EOK)
goto error;
 
/* Send default files */
fdi_node_t *files[4];
fdi_node_t stdin_node;
fdi_node_t stdout_node;
fdi_node_t stderr_node;
if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK))
files[0] = &stdin_node;
else
files[0] = NULL;
if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK))
files[1] = &stdout_node;
else
files[1] = NULL;
if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK))
files[2] = &stderr_node;
else
files[2] = NULL;
files[3] = NULL;
rc = loader_set_files(ldr, files);
if (rc != EOK)
goto error;
/* Load the program. */
rc = loader_load_program(ldr);
if (rc != EOK)
goto error;
 
/* Run it. */
/* Load the program. */
rc = loader_run(ldr);
if (rc != EOK)
goto error;
 
/* Success */
 
free(ldr);
return task_id;
 
error:
/* Error exit */
error:
loader_abort(ldr);
free(ldr);
 
return 0;
}
 
int task_wait(task_id_t id, task_exit_t *texit, int *retval)
{
ipcarg_t te, rv;
int rc;
 
rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
UPPER32(id), &te, &rv);
*texit = te;
*retval = rv;
 
return rc;
}
 
int task_retval(int val)
{
return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/libc.c
27,30 → 27,31
*/
 
/** @addtogroup lc Libc
* @brief HelenOS C library
* @brief HelenOS C library
* @{
* @}
*/
 
/** @addtogroup libc generic
* @ingroup lc
* @{
*/
 
/** @file
*/
*/
 
#include <libc.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <tls.h>
#include <thread.h>
#include <fibril.h>
#include <io/stream.h>
#include <ipc/ipc.h>
#include <async.h>
#include <as.h>
#include <loader/pcb.h>
 
extern char _heap;
extern int main(int argc, char *argv[]);
 
void _exit(int status)
60,29 → 61,33
 
void __main(void *pcb_ptr)
{
fibril_t *f;
int retval;
 
__heap_init();
__async_init();
fibril_t *fibril = fibril_setup();
__tcb_set(fibril->tcb);
/* Save the PCB pointer */
__pcb = (pcb_t *) pcb_ptr;
int argc;
char **argv;
 
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
_async_init();
f = fibril_setup();
__tcb_set(f->tcb);
open_console();
 
/* Save the PCB pointer */
__pcb = (pcb_t *)pcb_ptr;
 
if (__pcb == NULL) {
argc = 0;
argv = NULL;
__stdio_init(0, NULL);
} else {
argc = __pcb->argc;
argv = __pcb->argv;
__stdio_init(__pcb->filc, __pcb->filv);
}
retval = main(argc, argv);
 
main(argc, argv);
__stdio_done();
(void) task_retval(retval);
}
 
void __exit(void)
/branches/arm/uspace/lib/libc/generic/getopt.c
47,7 → 47,7
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
const char *optarg; /* argument associated with option */
 
 
#define IGNORE_FIRST (*options == '-' || *options == '+')
162,7 → 162,7
char **nargv;
const char *options;
{
char *oli; /* option letter list index */
const char *oli; /* option letter list index */
int optchar;
 
assert(nargv != NULL);
241,7 → 241,7
}
}
if ((optchar = (int)*place++) == (int)':' ||
(oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
(oli = str_chr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
/* option letter unknown or ':' */
if (!*place)
++optind;
275,7 → 275,7
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = *place;
optarg = place;
/* XXX: disable test for :: if PC? (GNU doesn't) */
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
353,7 → 353,8
 
retval = getopt_internal(nargc, (char **)nargv, options);
if (retval == -2) {
char *current_argv, *has_equal;
char *current_argv;
const char *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
 
377,20 → 378,20
nonopt_start = nonopt_end = -1;
return -1;
}
if ((has_equal = strchr(current_argv, '=')) != NULL) {
if ((has_equal = str_chr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
current_argv_len = str_size(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
if (str_lcmp(current_argv, long_options[i].name,
str_nlength(current_argv, current_argv_len)))
continue;
 
if (strlen(long_options[i].name) ==
if (str_size(long_options[i].name) ==
(unsigned)current_argv_len) {
/* exact match */
match = i;
/branches/arm/uspace/lib/libc/generic/as.c
30,7 → 30,7
* @{
*/
/** @file
*/
*/
 
#include <as.h>
#include <libc.h>
38,23 → 38,23
#include <align.h>
#include <sys/types.h>
#include <bitops.h>
#include <malloc.h>
 
/**
* Either 4*256M on 32-bit architecures or 16*256M on 64-bit architectures.
*/
#define MAX_HEAP_SIZE (sizeof(uintptr_t)<<28)
/** Last position allocated by as_get_mappable_page */
static uintptr_t last_allocated = 0;
 
/** Create address space area.
*
* @param address Virtual address where to place new address space area.
* @param size Size of the area.
* @param flags Flags describing type of the area.
* @param size Size of the area.
* @param flags Flags describing type of the area.
*
* @return address on success, (void *) -1 otherwise.
*
*/
void *as_area_create(void *address, size_t size, int flags)
{
return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t ) address,
return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address,
(sysarg_t) size, (sysarg_t) flags);
}
 
61,15 → 61,16
/** Resize address space area.
*
* @param address Virtual address pointing into already existing address space
* area.
* @param size New requested size of the area.
* @param flags Currently unused.
* area.
* @param size New requested size of the area.
* @param flags Currently unused.
*
* @return Zero on success or a code from @ref errno.h on failure.
* @return zero on success or a code from @ref errno.h on failure.
*
*/
int as_area_resize(void *address, size_t size, int flags)
{
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address,
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t) address,
(sysarg_t) size, (sysarg_t) flags);
}
 
76,22 → 77,24
/** Destroy address space area.
*
* @param address Virtual address pointing into the address space area being
* destroyed.
* destroyed.
*
* @return Zero on success or a code from @ref errno.h on failure.
* @return zero on success or a code from @ref errno.h on failure.
*
*/
int as_area_destroy(void *address)
{
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t) address);
}
 
/** Change address-space area flags.
*
* @param address Virtual address pointing into the address space area being
* modified.
* @param flags New flags describing type of the area.
* modified.
* @param flags New flags describing type of the area.
*
* @return Zero on success or a code from @ref errno.h on failure.
* @return zero on success or a code from @ref errno.h on failure.
*
*/
int as_area_change_flags(void *address, int flags)
{
99,101 → 102,29
(sysarg_t) flags);
}
 
static size_t heapsize = 0;
static size_t maxheapsize = (size_t) (-1);
 
static void * last_allocated = 0;
 
/* Start of heap linker symbol */
extern char _heap;
 
/** Sbrk emulation
*
* @param incr New area that should be allocated or negative,
if it should be shrinked
* @return Pointer to newly allocated area
*/
void *sbrk(ssize_t incr)
{
int rc;
void *res;
/* Check for invalid values */
if (incr < 0 && -incr > heapsize)
return NULL;
/* Check for too large value */
if (incr > 0 && incr+heapsize < heapsize)
return NULL;
/* Check for too small values */
if (incr < 0 && incr+heapsize > heapsize)
return NULL;
/* Check for user limit */
if ((maxheapsize != (size_t) (-1)) && (heapsize + incr) > maxheapsize)
return NULL;
rc = as_area_resize(&_heap, heapsize + incr, 0);
if (rc != 0)
return NULL;
/* Compute start of new area */
res = (void *) &_heap + heapsize;
 
heapsize += incr;
 
return res;
}
 
/** Set maximum heap size and return pointer just after the heap */
void *set_maxheapsize(size_t mhs)
{
maxheapsize = mhs;
/* Return pointer to area not managed by sbrk */
return ((void *) &_heap + maxheapsize);
}
 
/** Return pointer to some unmapped area, where fits new as_area
*
* @param sz Requested size of the allocation.
* @param size Requested size of the allocation.
*
* @return Pointer to the beginning
* @return pointer to the beginning
*
* TODO: make some first_fit/... algorithm, we are now just incrementing
* the pointer to last area
*/
void *as_get_mappable_page(size_t sz)
void *as_get_mappable_page(size_t size)
{
void *res;
uint64_t asz;
int i;
if (size == 0)
return NULL;
if (!sz)
return NULL;
 
asz = 1 << (fnzb64(sz - 1) + 1);
 
/* Set heapsize to some meaningful value */
if (maxheapsize == -1)
set_maxheapsize(MAX_HEAP_SIZE);
size_t sz = 1 << (fnzb(size - 1) + 1);
if (last_allocated == 0)
last_allocated = get_max_heap_addr();
/*
* Make sure we allocate from naturally aligned address.
*/
i = 0;
if (!last_allocated) {
last_allocated = (void *) ALIGN_UP((void *) &_heap +
maxheapsize, asz);
} else {
last_allocated = (void *) ALIGN_UP(((uintptr_t)
last_allocated) + (int) (i > 0), asz);
}
 
res = last_allocated;
last_allocated += ALIGN_UP(sz, PAGE_SIZE);
 
return res;
uintptr_t res = ALIGN_UP(last_allocated, sz);
last_allocated = res + ALIGN_UP(size, PAGE_SIZE);
return ((void *) res);
}
 
/** @}
/branches/arm/uspace/lib/libc/generic/async.c
30,64 → 30,65
* @{
*/
/** @file
*/
*/
 
/**
* Asynchronous library
*
* The aim of this library is facilitating writing programs utilizing the
* asynchronous nature of HelenOS IPC, yet using a normal way of programming.
* The aim of this library is to provide a facility for writing programs which
* utilize the asynchronous nature of HelenOS IPC, yet using a normal way of
* programming.
*
* You should be able to write very simple multithreaded programs, the async
* framework will automatically take care of most synchronization problems.
*
* Default semantics:
* - async_send_*(): send asynchronously. If the kernel refuses to send
* more messages, [ try to get responses from kernel, if
* nothing found, might try synchronous ]
* - async_send_*(): Send asynchronously. If the kernel refuses to send
* more messages, [ try to get responses from kernel, if
* nothing found, might try synchronous ]
*
* Example of use (pseudo C):
*
*
* 1) Multithreaded client application
*
* fibril_create(fibril1, ...);
* fibril_create(fibril2, ...);
* ...
*
* int fibril1(void *arg)
* {
* conn = ipc_connect_me_to();
* c1 = async_send(conn);
* c2 = async_send(conn);
* async_wait_for(c1);
* async_wait_for(c2);
* ...
* }
* fibril_create(fibril1, ...);
* fibril_create(fibril2, ...);
* ...
*
* int fibril1(void *arg)
* {
* conn = ipc_connect_me_to();
* c1 = async_send(conn);
* c2 = async_send(conn);
* async_wait_for(c1);
* async_wait_for(c2);
* ...
* }
*
*
* 2) Multithreaded server application
* main()
* {
* async_manager();
* }
*
*
* my_client_connection(icallid, *icall)
* {
* if (want_refuse) {
* ipc_answer_0(icallid, ELIMIT);
* return;
* }
* ipc_answer_0(icallid, EOK);
* main()
* {
* async_manager();
* }
*
* callid = async_get_call(&call);
* handle_call(callid, call);
* ipc_answer_2(callid, 1, 2, 3);
* my_client_connection(icallid, *icall)
* {
* if (want_refuse) {
* ipc_answer_0(icallid, ELIMIT);
* return;
* }
* ipc_answer_0(icallid, EOK);
*
* callid = async_get_call(&call);
* ....
* }
* callid = async_get_call(&call);
* handle_call(callid, call);
* ipc_answer_2(callid, 1, 2, 3);
*
* callid = async_get_call(&call);
* ...
* }
*
*/
 
#include <futex.h>
94,8 → 95,8
#include <async.h>
#include <fibril.h>
#include <stdio.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <adt/hash_table.h>
#include <adt/list.h>
#include <ipc/ipc.h>
#include <assert.h>
#include <errno.h>
104,24 → 105,26
#include <bool.h>
 
atomic_t async_futex = FUTEX_INITIALIZER;
static hash_table_t conn_hash_table;
static LIST_INITIALIZE(timeout_list);
 
/** Structures of this type represent a waiting fibril. */
typedef struct {
/** Expiration time. */
struct timeval expires;
struct timeval expires;
/** If true, this struct is in the timeout list. */
int inlist;
bool inlist;
/** Timeout list link. */
link_t link;
 
/** Identification of and link to the waiting fibril. */
fid_t fid;
/** If true, this fibril is currently active. */
int active;
bool active;
/** If true, we have timed out. */
int timedout;
bool timedout;
} awaiter_t;
 
typedef struct {
128,10 → 131,11
awaiter_t wdata;
/** If reply was received. */
int done;
bool done;
/** Pointer to where the answer data is stored. */
ipc_call_t *dataptr;
 
ipc_call_t *dataptr;
ipcarg_t retval;
} amsg_t;
 
147,37 → 151,31
 
typedef struct {
awaiter_t wdata;
 
/** Hash table link. */
link_t link;
 
/** Incoming phone hash. */
ipcarg_t in_phone_hash;
 
ipcarg_t in_phone_hash;
/** Messages that should be delivered to this fibril. */
link_t msg_queue;
link_t msg_queue;
/** Identification of the opening call. */
ipc_callid_t callid;
/** Call data of the opening call. */
ipc_call_t call;
 
/** Identification of the closing call. */
ipc_callid_t close_callid;
 
/** Fibril function that will be used to handle the connection. */
void (*cfibril)(ipc_callid_t, ipc_call_t *);
} connection_t;
 
/** Identifier of the incoming connection handled by the current fibril. */
__thread connection_t *FIBRIL_connection;
fibril_local connection_t *FIBRIL_connection;
 
/**
* If true, it is forbidden to use async_req functions and all preemption is
* disabled.
*/
__thread int _in_interrupt_handler;
 
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
 
185,6 → 183,7
* Pointer to a fibril function that will be used to handle connections.
*/
static async_client_conn_t client_connection = default_client_connection;
 
/**
* Pointer to a fibril function that will be used to handle interrupt
* notifications.
191,46 → 190,37
*/
static async_client_conn_t interrupt_received = default_interrupt_received;
 
/*
* Getter for _in_interrupt_handler. We need to export the value of this thread
* local variable to other modules, but the binutils 2.18 linkers die on an
* attempt to export this symbol in the header file. For now, consider this as a
* workaround.
*/
bool in_interrupt_handler(void)
{
return _in_interrupt_handler;
}
static hash_table_t conn_hash_table;
static LIST_INITIALIZE(timeout_list);
 
#define CONN_HASH_TABLE_CHAINS 32
#define CONN_HASH_TABLE_CHAINS 32
 
/** Compute hash into the connection hash table based on the source phone hash.
*
* @param key Pointer to source phone hash.
* @param key Pointer to source phone hash.
*
* @return Index into the connection hash table.
* @return Index into the connection hash table.
*
*/
static hash_index_t conn_hash(unsigned long *key)
{
assert(key);
return ((*key) >> 4) % CONN_HASH_TABLE_CHAINS;
return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS);
}
 
/** Compare hash table item with a key.
*
* @param key Array containing the source phone hash as the only item.
* @param keys Expected 1 but ignored.
* @param item Connection hash table item.
* @param key Array containing the source phone hash as the only item.
* @param keys Expected 1 but ignored.
* @param item Connection hash table item.
*
* @return True on match, false otherwise.
* @return True on match, false otherwise.
*
*/
static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
connection_t *hs;
 
hs = hash_table_get_instance(item, connection_t, link);
return key[0] == hs->in_phone_hash;
connection_t *hs = hash_table_get_instance(item, connection_t, link);
return (key[0] == hs->in_phone_hash);
}
 
/** Connection hash table removal callback function.
238,7 → 228,8
* This function is called whenever a connection is removed from the connection
* hash table.
*
* @param item Connection hash table item being removed.
* @param item Connection hash table item being removed.
*
*/
static void conn_remove(link_t *item)
{
255,23 → 246,24
 
/** Sort in current fibril's timeout request.
*
* @param wd Wait data of the current fibril.
* @param wd Wait data of the current fibril.
*
*/
static void insert_timeout(awaiter_t *wd)
{
link_t *tmp;
awaiter_t *cur;
 
wd->timedout = 0;
wd->inlist = 1;
 
tmp = timeout_list.next;
wd->timedout = false;
wd->inlist = true;
link_t *tmp = timeout_list.next;
while (tmp != &timeout_list) {
cur = list_get_instance(tmp, awaiter_t, link);
awaiter_t *cur = list_get_instance(tmp, awaiter_t, link);
if (tv_gteq(&cur->expires, &wd->expires))
break;
tmp = tmp->next;
}
list_append(&wd->link, tmp);
}
 
281,93 → 273,146
* its message queue. If the fibril was not active, it is activated and all
* timeouts are unregistered.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
* @return Zero if the call doesn't match any connection.
* One if the call was passed to the respective connection
* fibril.
* @return False if the call doesn't match any connection.
* True if the call was passed to the respective connection fibril.
*
*/
static int route_call(ipc_callid_t callid, ipc_call_t *call)
static bool route_call(ipc_callid_t callid, ipc_call_t *call)
{
connection_t *conn;
msg_t *msg;
link_t *hlp;
unsigned long key;
 
futex_down(&async_futex);
 
key = call->in_phone_hash;
hlp = hash_table_find(&conn_hash_table, &key);
unsigned long key = call->in_phone_hash;
link_t *hlp = hash_table_find(&conn_hash_table, &key);
if (!hlp) {
futex_up(&async_futex);
return 0;
return false;
}
conn = hash_table_get_instance(hlp, connection_t, link);
 
msg = malloc(sizeof(*msg));
connection_t *conn = hash_table_get_instance(hlp, connection_t, link);
msg_t *msg = malloc(sizeof(*msg));
if (!msg) {
futex_up(&async_futex);
return false;
}
msg->callid = callid;
msg->call = *call;
list_append(&msg->link, &conn->msg_queue);
 
if (IPC_GET_METHOD(*call) == IPC_M_PHONE_HUNGUP)
conn->close_callid = callid;
/* If the connection fibril is waiting for an event, activate it */
if (!conn->wdata.active) {
/* If in timeout list, remove it */
if (conn->wdata.inlist) {
conn->wdata.inlist = 0;
conn->wdata.inlist = false;
list_remove(&conn->wdata.link);
}
conn->wdata.active = 1;
conn->wdata.active = true;
fibril_add_ready(conn->wdata.fid);
}
 
futex_up(&async_futex);
return true;
}
 
return 1;
/** Notification fibril.
*
* When a notification arrives, a fibril with this implementing function is
* created. It calls interrupt_received() and does the final cleanup.
*
* @param arg Message structure pointer.
*
* @return Always zero.
*
*/
static int notification_fibril(void *arg)
{
msg_t *msg = (msg_t *) arg;
interrupt_received(msg->callid, &msg->call);
free(msg);
return 0;
}
 
/** Process interrupt notification.
*
* A new fibril is created which would process the notification.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
* @return False if an error occured.
* True if the call was passed to the notification fibril.
*
*/
static bool process_notification(ipc_callid_t callid, ipc_call_t *call)
{
futex_down(&async_futex);
msg_t *msg = malloc(sizeof(*msg));
if (!msg) {
futex_up(&async_futex);
return false;
}
msg->callid = callid;
msg->call = *call;
fid_t fid = fibril_create(notification_fibril, msg);
fibril_add_ready(fid);
futex_up(&async_futex);
return true;
}
 
/** Return new incoming message for the current (fibril-local) connection.
*
* @param call Storage where the incoming call data will be stored.
* @param usecs Timeout in microseconds. Zero denotes no timeout.
* @param call Storage where the incoming call data will be stored.
* @param usecs Timeout in microseconds. Zero denotes no timeout.
*
* @return If no timeout was specified, then a hash of the
* incoming call is returned. If a timeout is specified,
* then a hash of the incoming call is returned unless
* the timeout expires prior to receiving a message. In
* that case zero is returned.
* @return If no timeout was specified, then a hash of the
* incoming call is returned. If a timeout is specified,
* then a hash of the incoming call is returned unless
* the timeout expires prior to receiving a message. In
* that case zero is returned.
*
*/
ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
{
msg_t *msg;
ipc_callid_t callid;
connection_t *conn;
assert(FIBRIL_connection);
assert(FIBRIL_connection);
/* GCC 4.1.0 coughs on FIBRIL_connection-> dereference,
/* Why doing this?
* GCC 4.1.0 coughs on FIBRIL_connection-> dereference.
* GCC 4.1.1 happilly puts the rdhwr instruction in delay slot.
* I would never expect to find so many errors in
* a compiler *($&$(*&$
* I would never expect to find so many errors in
* a compiler.
*/
conn = FIBRIL_connection;
 
connection_t *conn = FIBRIL_connection;
futex_down(&async_futex);
 
if (usecs) {
gettimeofday(&conn->wdata.expires, NULL);
tv_add(&conn->wdata.expires, usecs);
} else {
conn->wdata.inlist = 0;
}
} else
conn->wdata.inlist = false;
/* If nothing in queue, wait until something arrives */
while (list_empty(&conn->msg_queue)) {
if (usecs)
insert_timeout(&conn->wdata);
 
conn->wdata.active = 0;
conn->wdata.active = false;
/*
* Note: the current fibril will be rescheduled either due to a
* timeout or due to an arriving message destined to it. In the
375,13 → 420,14
* case, route_call() will perform the wakeup.
*/
fibril_switch(FIBRIL_TO_MANAGER);
/*
* Futex is up after getting back from async_manager get it
* again.
* Futex is up after getting back from async_manager.
* Get it again.
*/
futex_down(&async_futex);
if (usecs && conn->wdata.timedout &&
list_empty(&conn->msg_queue)) {
if ((usecs) && (conn->wdata.timedout)
&& (list_empty(&conn->msg_queue))) {
/* If we timed out -> exit */
futex_up(&async_futex);
return 0;
388,9 → 434,10
}
}
msg = list_get_instance(conn->msg_queue.next, msg_t, link);
msg_t *msg = list_get_instance(conn->msg_queue.next, msg_t, link);
list_remove(&msg->link);
callid = msg->callid;
ipc_callid_t callid = msg->callid;
*call = msg->call;
free(msg);
402,8 → 449,9
*
* This function is defined as a weak symbol - to be redefined in user code.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
*/
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
{
412,8 → 460,11
 
/** Default fibril function that gets called to handle interrupt notifications.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* This function is defined as a weak symbol - to be redefined in user code.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
*/
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
{
424,17 → 475,17
* When a new connection arrives, a fibril with this implementing function is
* created. It calls client_connection() and does the final cleanup.
*
* @param arg Connection structure pointer.
* @param arg Connection structure pointer.
*
* @return Always zero.
* @return Always zero.
*
*/
static int connection_fibril(void *arg)
static int connection_fibril(void *arg)
{
unsigned long key;
msg_t *msg;
int close_answered = 0;
 
/* Setup fibril-local connection pointer */
/*
* Setup fibril-local connection pointer and call client_connection().
*
*/
FIBRIL_connection = (connection_t *) arg;
FIBRIL_connection->cfibril(FIBRIL_connection->callid,
&FIBRIL_connection->call);
441,20 → 492,21
/* Remove myself from the connection hash table */
futex_down(&async_futex);
key = FIBRIL_connection->in_phone_hash;
unsigned long key = FIBRIL_connection->in_phone_hash;
hash_table_remove(&conn_hash_table, &key, 1);
futex_up(&async_futex);
/* Answer all remaining messages with EHANGUP */
while (!list_empty(&FIBRIL_connection->msg_queue)) {
msg_t *msg;
msg = list_get_instance(FIBRIL_connection->msg_queue.next,
msg_t, link);
list_remove(&msg->link);
if (msg->callid == FIBRIL_connection->close_callid)
close_answered = 1;
ipc_answer_0(msg->callid, EHANGUP);
free(msg);
}
if (FIBRIL_connection->close_callid)
ipc_answer_0(FIBRIL_connection->close_callid, EOK);
463,43 → 515,45
 
/** Create a new fibril for a new connection.
*
* Creates new fibril for connection, fills in connection structures and inserts
* Create new fibril for connection, fill in connection structures and inserts
* it into the hash table, so that later we can easily do routing of messages to
* particular fibrils.
*
* @param in_phone_hash Identification of the incoming connection.
* @param callid Hash of the opening IPC_M_CONNECT_ME_TO call.
* If callid is zero, the connection was opened by
* accepting the IPC_M_CONNECT_TO_ME call and this function
* is called directly by the server.
* @param call Call data of the opening call.
* @param cfibril Fibril function that should be called upon opening the
* connection.
* @param in_phone_hash Identification of the incoming connection.
* @param callid Hash of the opening IPC_M_CONNECT_ME_TO call.
* If callid is zero, the connection was opened by
* accepting the IPC_M_CONNECT_TO_ME call and this function
* is called directly by the server.
* @param call Call data of the opening call.
* @param cfibril Fibril function that should be called upon opening the
* connection.
*
* @return New fibril id or NULL on failure.
* @return New fibril id or NULL on failure.
*
*/
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
{
connection_t *conn;
unsigned long key;
 
conn = malloc(sizeof(*conn));
connection_t *conn = malloc(sizeof(*conn));
if (!conn) {
if (callid)
ipc_answer_0(callid, ENOMEM);
return NULL;
}
conn->in_phone_hash = in_phone_hash;
list_initialize(&conn->msg_queue);
conn->callid = callid;
conn->close_callid = 0;
conn->close_callid = false;
if (call)
conn->call = *call;
conn->wdata.active = 1; /* We will activate the fibril ASAP */
/* We will activate the fibril ASAP */
conn->wdata.active = true;
conn->cfibril = cfibril;
 
conn->wdata.fid = fibril_create(connection_fibril, conn);
if (!conn->wdata.fid) {
free(conn);
if (callid)
506,14 → 560,16
ipc_answer_0(callid, ENOMEM);
return NULL;
}
/* Add connection to the connection hash table */
key = conn->in_phone_hash;
unsigned long key = conn->in_phone_hash;
futex_down(&async_futex);
hash_table_insert(&conn_hash_table, &key, &conn->link);
futex_up(&async_futex);
 
fibril_add_ready(conn->wdata.fid);
 
return conn->wdata.fid;
}
 
522,33 → 578,37
* If the call has the IPC_M_CONNECT_ME_TO method, a new connection is created.
* Otherwise the call is routed to its connection fibril.
*
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
* @param callid Hash of the incoming call.
* @param call Data of the incoming call.
*
*/
static void handle_call(ipc_callid_t callid, ipc_call_t *call)
{
/* Unrouted call - do some default behaviour */
if ((callid & IPC_CALLID_NOTIFICATION)) {
_in_interrupt_handler = 1;
(*interrupt_received)(callid, call);
_in_interrupt_handler = 0;
return;
}
 
process_notification(callid, call);
goto out;
}
switch (IPC_GET_METHOD(*call)) {
case IPC_M_CONNECT_ME:
case IPC_M_CONNECT_ME_TO:
/* Open new connection with fibril etc. */
async_new_connection(IPC_GET_ARG5(*call), callid, call,
client_connection);
return;
goto out;
}
 
/* Try to route the call through the connection hash table */
if (route_call(callid, call))
return;
 
goto out;
/* Unknown call from unknown phone - hang it up */
ipc_answer_0(callid, EHANGUP);
return;
out:
;
}
 
/** Fire all timeouts that expired. */
555,47 → 615,44
static void handle_expired_timeouts(void)
{
struct timeval tv;
awaiter_t *waiter;
link_t *cur;
 
gettimeofday(&tv, NULL);
futex_down(&async_futex);
 
cur = timeout_list.next;
link_t *cur = timeout_list.next;
while (cur != &timeout_list) {
waiter = list_get_instance(cur, awaiter_t, link);
awaiter_t *waiter = list_get_instance(cur, awaiter_t, link);
if (tv_gt(&waiter->expires, &tv))
break;
cur = cur->next;
list_remove(&waiter->link);
waiter->inlist = 0;
waiter->timedout = 1;
waiter->inlist = false;
waiter->timedout = true;
/*
* Redundant condition?
* The fibril should not be active when it gets here.
* Redundant condition?
* The fibril should not be active when it gets here.
*/
if (!waiter->active) {
waiter->active = 1;
waiter->active = true;
fibril_add_ready(waiter->fid);
}
}
 
futex_up(&async_futex);
}
 
/** Endless loop dispatching incoming calls and answers.
*
* @return Never returns.
* @return Never returns.
*
*/
static int async_manager_worker(void)
{
ipc_call_t call;
ipc_callid_t callid;
int timeout;
awaiter_t *waiter;
struct timeval tv;
 
while (1) {
while (true) {
if (fibril_switch(FIBRIL_FROM_MANAGER)) {
futex_up(&async_futex);
/*
604,11 → 661,17
*/
continue;
}
futex_down(&async_futex);
suseconds_t timeout;
if (!list_empty(&timeout_list)) {
waiter = list_get_instance(timeout_list.next, awaiter_t,
link);
awaiter_t *waiter = list_get_instance(timeout_list.next,
awaiter_t, link);
struct timeval tv;
gettimeofday(&tv, NULL);
if (tv_gteq(&tv, &waiter->expires)) {
futex_up(&async_futex);
handle_expired_timeouts();
617,19 → 680,21
timeout = tv_sub(&waiter->expires, &tv);
} else
timeout = SYNCH_NO_TIMEOUT;
futex_up(&async_futex);
 
callid = ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE);
 
ipc_call_t call;
ipc_callid_t callid = ipc_wait_cycle(&call, timeout,
SYNCH_FLAGS_NONE);
if (!callid) {
handle_expired_timeouts();
continue;
}
 
if (callid & IPC_CALLID_ANSWERED) {
if (callid & IPC_CALLID_ANSWERED)
continue;
}
 
handle_call(callid, &call);
}
637,16 → 702,17
}
 
/** Function to start async_manager as a standalone fibril.
*
*
* When more kernel threads are used, one async manager should exist per thread.
*
* @param arg Unused.
* @param arg Unused.
* @return Never returns.
*
* @return Never returns.
*/
static int async_manager_fibril(void *arg)
{
futex_up(&async_futex);
/*
* async_futex is always locked when entering manager
*/
658,9 → 724,7
/** Add one manager to manager list. */
void async_create_manager(void)
{
fid_t fid;
 
fid = fibril_create(async_manager_fibril, NULL);
fid_t fid = fibril_create(async_manager_fibril, NULL);
fibril_add_manager(fid);
}
 
672,9 → 736,9
 
/** Initialize the async framework.
*
* @return Zero on success or an error code.
* @return Zero on success or an error code.
*/
int _async_init(void)
int __async_init(void)
{
if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
&conn_hash_table_ops)) {
692,30 → 756,33
*
* Notify the fibril which is waiting for this message that it has arrived.
*
* @param private Pointer to the asynchronous message record.
* @param retval Value returned in the answer.
* @param data Call data of the answer.
* @param arg Pointer to the asynchronous message record.
* @param retval Value returned in the answer.
* @param data Call data of the answer.
*/
static void reply_received(void *private, int retval, ipc_call_t *data)
static void reply_received(void *arg, int retval, ipc_call_t *data)
{
amsg_t *msg = (amsg_t *) private;
 
futex_down(&async_futex);
amsg_t *msg = (amsg_t *) arg;
msg->retval = retval;
 
futex_down(&async_futex);
/* Copy data after futex_down, just in case the call was detached */
if (msg->dataptr)
*msg->dataptr = *data;
 
if ((msg->dataptr) && (data))
*msg->dataptr = *data;
write_barrier();
/* Remove message from timeout list */
if (msg->wdata.inlist)
list_remove(&msg->wdata.link);
msg->done = 1;
msg->done = true;
if (!msg->wdata.active) {
msg->wdata.active = 1;
msg->wdata.active = true;
fibril_add_ready(msg->wdata.fid);
}
futex_up(&async_futex);
}
 
724,38 → 791,36
* The return value can be used as input for async_wait() to wait for
* completion.
*
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
*
* @return Hash of the sent message.
* @return Hash of the sent message or 0 on error.
*
*/
aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
{
amsg_t *msg;
 
if (_in_interrupt_handler) {
printf("Cannot send asynchronous request in interrupt "
"handler.\n");
_exit(1);
}
 
msg = malloc(sizeof(*msg));
msg->done = 0;
amsg_t *msg = malloc(sizeof(*msg));
if (!msg)
return 0;
msg->done = false;
msg->dataptr = dataptr;
 
msg->wdata.inlist = false;
/* We may sleep in the next method, but it will use its own mechanism */
msg->wdata.active = 1;
msg->wdata.active = true;
ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg,
reply_received, 1);
 
reply_received, true);
return (aid_t) msg;
}
 
764,113 → 829,119
* The return value can be used as input for async_wait() to wait for
* completion.
*
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
* @param phoneid Handle of the phone that will be used for the send.
* @param method Service-defined method.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param dataptr If non-NULL, storage where the reply data will be
* stored.
*
* @return Hash of the sent message.
* @return Hash of the sent message or 0 on error.
*
*/
aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
ipc_call_t *dataptr)
{
amsg_t *msg;
 
if (_in_interrupt_handler) {
printf("Cannot send asynchronous request in interrupt "
"handler.\n");
_exit(1);
}
 
msg = malloc(sizeof(*msg));
msg->done = 0;
amsg_t *msg = malloc(sizeof(*msg));
if (!msg)
return 0;
msg->done = false;
msg->dataptr = dataptr;
 
msg->wdata.inlist = false;
/* We may sleep in next method, but it will use its own mechanism */
msg->wdata.active = 1;
 
msg->wdata.active = true;
ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,
reply_received, 1);
 
reply_received, true);
return (aid_t) msg;
}
 
/** Wait for a message sent by the async framework.
*
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
*
*/
void async_wait_for(aid_t amsgid, ipcarg_t *retval)
{
amsg_t *msg = (amsg_t *) amsgid;
 
futex_down(&async_futex);
if (msg->done) {
futex_up(&async_futex);
goto done;
}
 
msg->wdata.fid = fibril_get_id();
msg->wdata.active = 0;
msg->wdata.inlist = 0;
msg->wdata.active = false;
msg->wdata.inlist = false;
/* Leave the async_futex locked when entering this function */
fibril_switch(FIBRIL_TO_MANAGER);
/* futex is up automatically after fibril_switch...*/
/* Futex is up automatically after fibril_switch */
done:
if (retval)
*retval = msg->retval;
free(msg);
}
 
/** Wait for a message sent by the async framework, timeout variant.
*
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
* @param timeout Timeout in microseconds.
* @param amsgid Hash of the message to wait for.
* @param retval Pointer to storage where the retval of the answer will
* be stored.
* @param timeout Timeout in microseconds.
*
* @return Zero on success, ETIMEOUT if the timeout has expired.
* @return Zero on success, ETIMEOUT if the timeout has expired.
*
*/
int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, suseconds_t timeout)
{
amsg_t *msg = (amsg_t *) amsgid;
 
/* TODO: Let it go through the event read at least once */
if (timeout < 0)
return ETIMEOUT;
 
futex_down(&async_futex);
if (msg->done) {
futex_up(&async_futex);
goto done;
}
 
gettimeofday(&msg->wdata.expires, NULL);
tv_add(&msg->wdata.expires, timeout);
 
msg->wdata.fid = fibril_get_id();
msg->wdata.active = 0;
msg->wdata.active = false;
insert_timeout(&msg->wdata);
 
/* Leave the async_futex locked when entering this function */
fibril_switch(FIBRIL_TO_MANAGER);
/* futex is up automatically after fibril_switch...*/
 
/* Futex is up automatically after fibril_switch */
if (!msg->done)
return ETIMEOUT;
 
done:
if (retval)
*retval = msg->retval;
free(msg);
 
return 0;
}
 
878,38 → 949,38
*
* The current fibril is suspended but the thread continues to execute.
*
* @param timeout Duration of the wait in microseconds.
* @param timeout Duration of the wait in microseconds.
*
*/
void async_usleep(suseconds_t timeout)
{
amsg_t *msg;
amsg_t *msg = malloc(sizeof(*msg));
if (_in_interrupt_handler) {
printf("Cannot call async_usleep in interrupt handler.\n");
_exit(1);
}
 
msg = malloc(sizeof(*msg));
if (!msg)
return;
 
msg->wdata.fid = fibril_get_id();
msg->wdata.active = 0;
 
msg->wdata.active = false;
gettimeofday(&msg->wdata.expires, NULL);
tv_add(&msg->wdata.expires, timeout);
 
futex_down(&async_futex);
insert_timeout(&msg->wdata);
/* Leave the async_futex locked when entering this function */
fibril_switch(FIBRIL_TO_MANAGER);
/* futex is up automatically after fibril_switch()...*/
/* Futex is up automatically after fibril_switch() */
free(msg);
}
 
/** Setter for client_connection function pointer.
*
* @param conn Function that will implement a new connection fibril.
* @param conn Function that will implement a new connection fibril.
*
*/
void async_set_client_connection(async_client_conn_t conn)
{
918,12 → 989,12
 
/** Setter for interrupt_received function pointer.
*
* @param conn Function that will implement a new interrupt
* notification fibril.
* @param intr Function that will implement a new interrupt
* notification fibril.
*/
void async_set_interrupt_received(async_client_conn_t conn)
void async_set_interrupt_received(async_client_conn_t intr)
{
interrupt_received = conn;
interrupt_received = intr;
}
 
/** Pseudo-synchronous message sending - fast version.
933,18 → 1004,20
* This function can only transfer 4 register payload arguments. For
* transferring more arguments, see the slower async_req_slow().
*
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
* @return Return code of the reply or a negative error code.
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
*
* @return Return code of the reply or a negative error code.
*
*/
ipcarg_t async_req_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t *r1, ipcarg_t *r2,
951,21 → 1024,27
ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5)
{
ipc_call_t result;
ipcarg_t rc;
 
aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4,
&result);
ipcarg_t rc;
async_wait_for(eid, &rc);
if (r1)
if (r1)
*r1 = IPC_GET_ARG1(result);
if (r2)
*r2 = IPC_GET_ARG2(result);
if (r3)
*r3 = IPC_GET_ARG3(result);
if (r4)
*r4 = IPC_GET_ARG4(result);
if (r5)
*r5 = IPC_GET_ARG5(result);
return rc;
}
 
973,19 → 1052,21
*
* Send message asynchronously and return only after the reply arrives.
*
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
* @return Return code of the reply or a negative error code.
* @param phoneid Hash of the phone through which to make the call.
* @param method Method of the call.
* @param arg1 Service-defined payload argument.
* @param arg2 Service-defined payload argument.
* @param arg3 Service-defined payload argument.
* @param arg4 Service-defined payload argument.
* @param arg5 Service-defined payload argument.
* @param r1 If non-NULL, storage for the 1st reply argument.
* @param r2 If non-NULL, storage for the 2nd reply argument.
* @param r3 If non-NULL, storage for the 3rd reply argument.
* @param r4 If non-NULL, storage for the 4th reply argument.
* @param r5 If non-NULL, storage for the 5th reply argument.
*
* @return Return code of the reply or a negative error code.
*
*/
ipcarg_t async_req_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t *r1,
992,21 → 1073,27
ipcarg_t *r2, ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5)
{
ipc_call_t result;
ipcarg_t rc;
 
aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5,
&result);
ipcarg_t rc;
async_wait_for(eid, &rc);
if (r1)
if (r1)
*r1 = IPC_GET_ARG1(result);
if (r2)
*r2 = IPC_GET_ARG2(result);
if (r3)
*r3 = IPC_GET_ARG3(result);
if (r4)
*r4 = IPC_GET_ARG4(result);
if (r5)
*r5 = IPC_GET_ARG5(result);
return rc;
}
 
/branches/arm/uspace/lib/libc/generic/errno.c
0,0 → 1,41
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <errno.h>
#include <fibril.h>
 
int _errno;
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/mman.c
37,17 → 37,18
#include <as.h>
#include <unistd.h>
 
void *mmap(void *start, size_t length, int prot, int flags, int fd,
void *mmap(void *start, size_t length, int prot, int flags, int fd,
off_t offset)
{
if (!start)
start = as_get_mappable_page(length);
// if (! ((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
// if (!((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
// return MAP_FAILED;
if (! (flags & MAP_ANONYMOUS))
if (!(flags & MAP_ANONYMOUS))
return MAP_FAILED;
 
return as_area_create(start, length, prot);
}
 
/branches/arm/uspace/lib/libc/generic/devmap.c
0,0 → 1,289
/*
* Copyright (c) 2007 Josef Cejka
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <string.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/devmap.h>
#include <devmap.h>
#include <async.h>
#include <errno.h>
 
static int devmap_phone_driver = -1;
static int devmap_phone_client = -1;
 
/** Get phone to device mapper task. */
int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
{
switch (iface) {
case DEVMAP_DRIVER:
if (devmap_phone_driver >= 0)
return devmap_phone_driver;
if (flags & IPC_FLAG_BLOCKING)
devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
else
devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
return devmap_phone_driver;
case DEVMAP_CLIENT:
if (devmap_phone_client >= 0)
return devmap_phone_client;
if (flags & IPC_FLAG_BLOCKING)
devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
else
devmap_phone_client = ipc_connect_me_to(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
return devmap_phone_client;
default:
return -1;
}
}
 
void devmap_hangup_phone(devmap_interface_t iface)
{
switch (iface) {
case DEVMAP_DRIVER:
if (devmap_phone_driver >= 0) {
ipc_hangup(devmap_phone_driver);
devmap_phone_driver = -1;
}
break;
case DEVMAP_CLIENT:
if (devmap_phone_client >= 0) {
ipc_hangup(devmap_phone_client);
devmap_phone_client = -1;
}
break;
default:
break;
}
}
 
/** Register new driver with devmap. */
int devmap_driver_register(const char *name, async_client_conn_t conn)
{
int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
if (phone < 0)
return phone;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return -1;
}
async_set_client_connection(conn);
ipcarg_t callback_phonehash;
ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
async_wait_for(req, &retval);
async_serialize_end();
return retval;
}
 
/** Register new device.
*
* @param name Device name.
* @param handle Output: Handle to the created instance of device.
*
*/
int devmap_device_register(const char *name, dev_handle_t *handle)
{
int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
if (phone < 0)
return phone;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
&answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return retval;
}
async_wait_for(req, &retval);
async_serialize_end();
if (retval != EOK) {
if (handle != NULL)
*handle = -1;
return retval;
}
if (handle != NULL)
*handle = (dev_handle_t) IPC_GET_ARG1(answer);
return retval;
}
 
int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
if (phone < 0)
return phone;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
&answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return retval;
}
async_wait_for(req, &retval);
async_serialize_end();
if (retval != EOK) {
if (handle != NULL)
*handle = (dev_handle_t) -1;
return retval;
}
if (handle != NULL)
*handle = (dev_handle_t) IPC_GET_ARG1(answer);
return retval;
}
 
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
{
int phone;
if (flags & IPC_FLAG_BLOCKING) {
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, handle);
} else {
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, handle);
}
return phone;
}
 
int devmap_null_create(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return -1;
ipcarg_t null_id;
int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
if (retval != EOK)
return -1;
return (int) null_id;
}
 
void devmap_null_destroy(int null_id)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return;
async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
}
 
ipcarg_t devmap_device_get_count(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return 0;
ipcarg_t count;
int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
if (retval != EOK)
return 0;
return count;
}
 
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return 0;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return 0;
}
async_wait_for(req, &retval);
async_serialize_end();
if (retval != EOK)
return 0;
return IPC_GET_ARG1(answer);
}
/branches/arm/uspace/lib/libc/generic/vfs/vfs.c
31,7 → 31,7
*/
/** @file
*/
 
#include <vfs/vfs.h>
#include <vfs/canonify.h>
#include <stdlib.h>
38,8 → 38,8
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
48,16 → 48,17
#include <futex.h>
#include <errno.h>
#include <string.h>
#include <devmap.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
#include "../../srv/vfs/vfs.h"
 
int vfs_phone = -1;
futex_t vfs_phone_futex = FUTEX_INITIALIZER;
static int vfs_phone = -1;
static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
static futex_t cwd_futex = FUTEX_INITIALIZER;
 
futex_t cwd_futex = FUTEX_INITIALIZER;
DIR *cwd_dir = NULL;
char *cwd_path = NULL;
size_t cwd_len = 0;
size_t cwd_size = 0;
 
char *absolutize(const char *path, size_t *retlen)
{
65,22 → 66,22
char *ncwd_path_nc;
 
futex_down(&cwd_futex);
size_t len = strlen(path);
size_t size = str_size(path);
if (*path != '/') {
if (!cwd_path) {
futex_up(&cwd_futex);
return NULL;
}
ncwd_path_nc = malloc(cwd_len + 1 + len + 1);
ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
if (!ncwd_path_nc) {
futex_up(&cwd_futex);
return NULL;
}
strcpy(ncwd_path_nc, cwd_path);
ncwd_path_nc[cwd_len] = '/';
ncwd_path_nc[cwd_len + 1] = '\0';
str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
ncwd_path_nc[cwd_size] = '/';
ncwd_path_nc[cwd_size + 1] = '\0';
} else {
ncwd_path_nc = malloc(len + 1);
ncwd_path_nc = malloc(size + 1);
if (!ncwd_path_nc) {
futex_up(&cwd_futex);
return NULL;
87,7 → 88,7
}
ncwd_path_nc[0] = '\0';
}
strcat(ncwd_path_nc, path);
str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
ncwd_path = canonify(ncwd_path_nc, retlen);
if (!ncwd_path) {
futex_up(&cwd_futex);
99,7 → 100,7
* the address in ncwd_path need not be the same as ncwd_path_nc, even
* though they both point into the same dynamically allocated buffer.
*/
ncwd_path = strdup(ncwd_path);
ncwd_path = str_dup(ncwd_path);
free(ncwd_path_nc);
if (!ncwd_path) {
futex_up(&cwd_futex);
109,75 → 110,44
return ncwd_path;
}
 
static int vfs_connect(void)
static void vfs_connect(void)
{
if (vfs_phone < 0)
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
return vfs_phone;
while (vfs_phone < 0)
vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
}
 
static int device_get_handle(char *name, dev_handle_t *handle)
int mount(const char *fs_name, const char *mp, const char *dev,
const char *opts, unsigned int flags)
{
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT,
0);
if (phone < 0)
return phone;
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0,
&answer);
ipcarg_t retval = ipc_data_write_start(phone, name, strlen(name) + 1);
 
if (retval != EOK) {
async_wait_for(req, NULL);
ipc_hangup(phone);
return retval;
}
 
async_wait_for(req, &retval);
 
if (handle != NULL)
*handle = -1;
if (retval == EOK) {
if (handle != NULL)
*handle = (dev_handle_t) IPC_GET_ARG1(answer);
}
ipc_hangup(phone);
return retval;
}
 
int mount(const char *fs_name, const char *mp, const char *dev)
{
int res;
ipcarg_t rc;
aid_t req;
dev_handle_t dev_handle;
res = device_get_handle(dev, &dev_handle);
res = devmap_device_get_handle(dev, &dev_handle, flags);
if (res != EOK)
return res;
size_t mpa_len;
char *mpa = absolutize(mp, &mpa_len);
size_t mpa_size;
char *mpa = absolutize(mp, &mpa_size);
if (!mpa)
return ENOMEM;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
free(mpa);
return res;
}
vfs_connect();
req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(mpa);
return (int) rc;
}
req = async_send_1(vfs_phone, VFS_MOUNT, dev_handle, NULL);
rc = ipc_data_write_start(vfs_phone, (void *)fs_name, strlen(fs_name));
rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
185,8 → 155,8
free(mpa);
return (int) rc;
}
/* Ask VFS whether it likes fs_name. */
rc = async_req_0_0(vfs_phone, IPC_M_PING);
 
rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
194,7 → 164,9
free(mpa);
return (int) rc;
}
rc = ipc_data_write_start(vfs_phone, (void *)mpa, mpa_len);
 
/* Ask VFS whether it likes fs_name. */
rc = async_req_0_0(vfs_phone, IPC_M_PING);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
202,38 → 174,32
free(mpa);
return (int) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(mpa);
return (int) rc;
}
 
static int _open(const char *path, int lflag, int oflag, ...)
{
int res;
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
size_t pa_len;
char *pa = absolutize(path, &pa_len);
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return res;
}
}
req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
rc = ipc_data_write_start(vfs_phone, pa, pa_len);
vfs_connect();
req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
245,9 → 211,10
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
 
if (rc != EOK)
return (int) rc;
return (int) IPC_GET_ARG1(answer);
}
 
256,24 → 223,37
return _open(path, L_FILE, oflag);
}
 
int open_node(fdi_node_t *node, int oflag)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipc_call_t answer;
aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
node->dev_handle, node->index, oflag, &answer);
ipcarg_t rc;
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc != EOK)
return (int) rc;
return (int) IPC_GET_ARG1(answer);
}
 
int close(int fildes)
{
int res;
ipcarg_t rc;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
return res;
}
}
rc = async_req_1_0(vfs_phone, VFS_CLOSE, fildes);
 
vfs_connect();
rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
282,7 → 262,6
 
ssize_t read(int fildes, void *buf, size_t nbyte)
{
int res;
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
289,15 → 268,9
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
return res;
}
}
req = async_send_1(vfs_phone, VFS_READ, fildes, &answer);
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
if (rc != EOK) {
async_wait_for(req, NULL);
316,7 → 289,6
 
ssize_t write(int fildes, const void *buf, size_t nbyte)
{
int res;
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
323,15 → 295,9
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
return res;
}
}
req = async_send_1(vfs_phone, VFS_WRITE, fildes, &answer);
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);
if (rc != EOK) {
async_wait_for(req, NULL);
348,25 → 314,31
return -1;
}
 
int fsync(int fildes)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
}
 
off_t lseek(int fildes, off_t offset, int whence)
{
int res;
ipcarg_t rc;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
return res;
}
}
off_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence,
(ipcarg_t)&newoffs);
vfs_connect();
ipcarg_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
&newoffs);
 
async_serialize_end();
futex_up(&vfs_phone_futex);
374,30 → 346,86
if (rc != EOK)
return (off_t) -1;
return newoffs;
return (off_t) newoffs;
}
 
int ftruncate(int fildes, off_t length)
{
int res;
ipcarg_t rc;
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
return res;
}
}
rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length);
vfs_connect();
rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
}
 
int fstat(int fildes, struct stat *stat)
{
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (ssize_t) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
 
return rc;
}
 
int stat(const char *path, struct stat *stat)
{
ipcarg_t rc;
aid_t req;
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return (int) rc;
}
rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return (int) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return rc;
}
 
DIR *opendir(const char *dirname)
{
DIR *dirp = malloc(sizeof(DIR));
433,28 → 461,20
 
int mkdir(const char *path, mode_t mode)
{
int res;
ipcarg_t rc;
aid_t req;
size_t pa_len;
char *pa = absolutize(path, &pa_len);
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return res;
}
}
req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_len);
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
466,33 → 486,25
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return rc;
return rc;
}
 
static int _unlink(const char *path, int lflag)
{
int res;
ipcarg_t rc;
aid_t req;
size_t pa_len;
char *pa = absolutize(path, &pa_len);
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return res;
}
}
req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_len);
vfs_connect();
req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
504,7 → 516,7
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return rc;
return rc;
}
 
int unlink(const char *path)
519,17 → 531,16
 
int rename(const char *old, const char *new)
{
int res;
ipcarg_t rc;
aid_t req;
size_t olda_len;
char *olda = absolutize(old, &olda_len);
size_t olda_size;
char *olda = absolutize(old, &olda_size);
if (!olda)
return ENOMEM;
 
size_t newa_len;
char *newa = absolutize(new, &newa_len);
size_t newa_size;
char *newa = absolutize(new, &newa_size);
if (!newa) {
free(olda);
return ENOMEM;
537,18 → 548,10
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
free(olda);
free(newa);
return res;
}
}
req = async_send_0(vfs_phone, VFS_RENAME, NULL);
rc = ipc_data_write_start(vfs_phone, olda, olda_len);
vfs_connect();
req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
rc = ipc_data_write_start(vfs_phone, olda, olda_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
557,7 → 560,7
free(newa);
return (int) rc;
}
rc = ipc_data_write_start(vfs_phone, newa, newa_len);
rc = ipc_data_write_start(vfs_phone, newa, newa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
576,8 → 579,8
 
int chdir(const char *path)
{
size_t pa_len;
char *pa = absolutize(path, &pa_len);
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
 
593,11 → 596,11
cwd_dir = NULL;
free(cwd_path);
cwd_path = NULL;
cwd_len = 0;
cwd_size = 0;
}
cwd_dir = d;
cwd_path = pa;
cwd_len = pa_len;
cwd_size = pa_size;
futex_up(&cwd_futex);
return EOK;
}
607,14 → 610,43
if (!size)
return NULL;
futex_down(&cwd_futex);
if (size < cwd_len + 1) {
if (size < cwd_size + 1) {
futex_up(&cwd_futex);
return NULL;
}
strcpy(buf, cwd_path);
str_cpy(buf, size, cwd_path);
futex_up(&cwd_futex);
return buf;
}
 
int fd_phone(int fildes)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
 
if (!stat.devfs_stat.device)
return -1;
return devmap_device_connect(stat.devfs_stat.device, 0);
}
 
int fd_node(int fildes, fdi_node_t *node)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
if (rc == EOK) {
node->fs_handle = stat.fs_handle;
node->dev_handle = stat.dev_handle;
node->index = stat.index;
}
return rc;
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/vfs/canonify.c
36,6 → 36,7
*/
 
#include <stdlib.h>
#include <vfs/canonify.h>
 
/** Token types used for tokenization of path. */
typedef enum {
/branches/arm/uspace/lib/libc/generic/fibril_sync.c
0,0 → 1,219
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <fibril_sync.h>
#include <fibril.h>
#include <async.h>
#include <adt/list.h>
#include <futex.h>
#include <assert.h>
 
void fibril_mutex_initialize(fibril_mutex_t *fm)
{
fm->counter = 1;
list_initialize(&fm->waiters);
}
 
void fibril_mutex_lock(fibril_mutex_t *fm)
{
futex_down(&async_futex);
if (fm->counter-- <= 0) {
fibril_t *f = (fibril_t *) fibril_get_id();
list_append(&f->link, &fm->waiters);
fibril_switch(FIBRIL_TO_MANAGER);
} else {
futex_up(&async_futex);
}
}
 
bool fibril_mutex_trylock(fibril_mutex_t *fm)
{
bool locked = false;
futex_down(&async_futex);
if (fm->counter > 0) {
fm->counter--;
locked = true;
}
futex_up(&async_futex);
return locked;
}
 
static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm)
{
assert(fm->counter <= 0);
if (fm->counter++ < 0) {
link_t *tmp;
fibril_t *f;
assert(!list_empty(&fm->waiters));
tmp = fm->waiters.next;
f = list_get_instance(tmp, fibril_t, link);
list_remove(&f->link);
fibril_add_ready((fid_t) f);
}
}
 
void fibril_mutex_unlock(fibril_mutex_t *fm)
{
futex_down(&async_futex);
_fibril_mutex_unlock_unsafe(fm);
futex_up(&async_futex);
}
 
void fibril_rwlock_initialize(fibril_rwlock_t *frw)
{
frw->writers = 0;
frw->readers = 0;
list_initialize(&frw->waiters);
}
 
void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
{
futex_down(&async_futex);
if (frw->writers) {
fibril_t *f = (fibril_t *) fibril_get_id();
f->flags &= ~FIBRIL_WRITER;
list_append(&f->link, &frw->waiters);
fibril_switch(FIBRIL_TO_MANAGER);
} else {
frw->readers++;
futex_up(&async_futex);
}
}
 
void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
{
futex_down(&async_futex);
if (frw->writers || frw->readers) {
fibril_t *f = (fibril_t *) fibril_get_id();
f->flags |= FIBRIL_WRITER;
list_append(&f->link, &frw->waiters);
fibril_switch(FIBRIL_TO_MANAGER);
} else {
frw->writers++;
futex_up(&async_futex);
}
}
 
static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw)
{
futex_down(&async_futex);
assert(frw->readers || (frw->writers == 1));
if (frw->readers) {
if (--frw->readers)
goto out;
} else {
frw->writers--;
}
assert(!frw->readers && !frw->writers);
while (!list_empty(&frw->waiters)) {
link_t *tmp = frw->waiters.next;
fibril_t *f = list_get_instance(tmp, fibril_t, link);
if (f->flags & FIBRIL_WRITER) {
if (frw->readers)
break;
list_remove(&f->link);
fibril_add_ready((fid_t) f);
frw->writers++;
break;
} else {
list_remove(&f->link);
fibril_add_ready((fid_t) f);
frw->readers++;
}
}
out:
futex_up(&async_futex);
}
 
void fibril_rwlock_read_unlock(fibril_rwlock_t *frw)
{
_fibril_rwlock_common_unlock(frw);
}
 
void fibril_rwlock_write_unlock(fibril_rwlock_t *frw)
{
_fibril_rwlock_common_unlock(frw);
}
 
void fibril_condvar_initialize(fibril_condvar_t *fcv)
{
list_initialize(&fcv->waiters);
}
 
void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm)
{
fibril_t *f = (fibril_t *) fibril_get_id();
 
futex_down(&async_futex);
list_append(&f->link, &fcv->waiters);
_fibril_mutex_unlock_unsafe(fm);
fibril_switch(FIBRIL_TO_MANAGER);
fibril_mutex_lock(fm);
}
 
static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once)
{
link_t *tmp;
fibril_t *f;
 
futex_down(&async_futex);
while (!list_empty(&fcv->waiters)) {
tmp = fcv->waiters.next;
f = list_get_instance(tmp, fibril_t, link);
list_remove(&f->link);
fibril_add_ready((fid_t) f);
if (once)
break;
}
futex_up(&async_futex);
}
 
void fibril_condvar_signal(fibril_condvar_t *fcv)
{
_fibril_condvar_wakeup_common(fcv, true);
}
 
void fibril_condvar_broadcast(fibril_condvar_t *fcv)
{
_fibril_condvar_wakeup_common(fcv, false);
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/ipc.c
43,7 → 43,7
#include <libc.h>
#include <malloc.h>
#include <errno.h>
#include <libadt/list.h>
#include <adt/list.h>
#include <stdio.h>
#include <unistd.h>
#include <futex.h>
232,7 → 232,7
return;
}
 
if (callid == IPC_CALLRET_FATAL) {
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
futex_up(&ipc_futex);
/* Call asynchronous handler with error code */
if (call->callback)
241,7 → 241,7
return;
}
 
if (callid == IPC_CALLRET_TEMPORARY) {
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
futex_up(&ipc_futex);
 
call->u.msg.phoneid = phoneid;
309,7 → 309,7
callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
arg2, arg3, arg4);
 
if (callid == IPC_CALLRET_TEMPORARY) {
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
if (!call) {
call = ipc_prepare_async(private, callback);
if (!call)
442,7 → 442,7
call = list_get_instance(queued_calls.next, async_call_t, list);
callid = _ipc_call_async(call->u.msg.phoneid,
&call->u.msg.data);
if (callid == IPC_CALLRET_TEMPORARY) {
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
break;
}
list_remove(&call->list);
451,7 → 451,7
if (call->fid)
fibril_add_ready(call->fid);
if (callid == IPC_CALLRET_FATAL) {
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
if (call->callback)
call->callback(call->private, ENOENT, NULL);
free(call);
598,7 → 598,7
ipcarg_t newphid;
int res;
 
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
NULL, NULL, NULL, NULL, &newphid);
if (res)
return res;
605,6 → 605,30
return newphid;
}
 
/** Ask through phone for a new connection to some service.
*
* If the connection is not available at the moment, the
* call will block.
*
* @param phoneid Phone handle used for contacting the other side.
* @param arg1 User defined argument.
* @param arg2 User defined argument.
* @param arg3 User defined argument.
*
* @return New phone handle on success or a negative error code.
*/
int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3)
{
ipcarg_t newphid;
int res;
 
res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
if (res)
return res;
return newphid;
}
 
/** Hang up a phone.
*
* @param phoneid Handle of the phone to be hung up.
666,6 → 690,23
arg2, mode);
}
 
 
int ipc_forward_slow(ipc_callid_t callid, int phoneid, int method,
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
int mode)
{
ipc_call_t data;
 
IPC_SET_METHOD(data, method);
IPC_SET_ARG1(data, arg1);
IPC_SET_ARG2(data, arg2);
IPC_SET_ARG3(data, arg3);
IPC_SET_ARG4(data, arg4);
IPC_SET_ARG5(data, arg5);
 
return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
}
 
/** Wrapper for making IPC_M_SHARE_IN calls.
*
* @param phoneid Phone that will be used to contact the receiving side.
847,7 → 888,7
*
* @return Zero on success or a value from @ref errno.h on failure.
*/
int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size)
int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
{
return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) size);
}
860,7 → 901,7
*
* @return Zero on success or a negative error code from errno.h.
*/
int ipc_data_write_start(int phoneid, void *src, size_t size)
int ipc_data_write_start(int phoneid, const void *src, size_t size)
{
return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,
(ipcarg_t) size);
/branches/arm/uspace/lib/libc/generic/adt/hash_table.c
0,0 → 1,196
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
/*
* This is an implementation of generic chained hash table.
*/
 
#include <adt/hash_table.h>
#include <adt/list.h>
#include <unistd.h>
#include <malloc.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
 
/** Create chained hash table.
*
* @param h Hash table structure. Will be initialized by this call.
* @param m Number of hash table buckets.
* @param max_keys Maximal number of keys needed to identify an item.
* @param op Hash table operations structure.
* @return True on success
*/
int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
hash_table_operations_t *op)
{
hash_count_t i;
 
assert(h);
assert(op && op->hash && op->compare);
assert(max_keys > 0);
h->entry = malloc(m * sizeof(link_t));
if (!h->entry) {
printf("cannot allocate memory for hash table\n");
return false;
}
memset((void *) h->entry, 0, m * sizeof(link_t));
for (i = 0; i < m; i++)
list_initialize(&h->entry[i]);
h->entries = m;
h->max_keys = max_keys;
h->op = op;
return true;
}
 
/** Destroy a hash table instance.
*
* @param h Hash table to be destroyed.
*/
void hash_table_destroy(hash_table_t *h)
{
assert(h);
assert(h->entry);
free(h->entry);
}
 
/** Insert item into a hash table.
*
* @param h Hash table.
* @param key Array of all keys necessary to compute hash index.
* @param item Item to be inserted into the hash table.
*/
void hash_table_insert(hash_table_t *h, unsigned long key[], link_t *item)
{
hash_index_t chain;
 
assert(item);
assert(h && h->op && h->op->hash && h->op->compare);
 
chain = h->op->hash(key);
assert(chain < h->entries);
list_append(item, &h->entry[chain]);
}
 
/** Search hash table for an item matching keys.
*
* @param h Hash table.
* @param key Array of all keys needed to compute hash index.
*
* @return Matching item on success, NULL if there is no such item.
*/
link_t *hash_table_find(hash_table_t *h, unsigned long key[])
{
link_t *cur;
hash_index_t chain;
 
assert(h && h->op && h->op->hash && h->op->compare);
 
chain = h->op->hash(key);
assert(chain < h->entries);
for (cur = h->entry[chain].next; cur != &h->entry[chain];
cur = cur->next) {
if (h->op->compare(key, h->max_keys, cur)) {
/*
* The entry is there.
*/
return cur;
}
}
return NULL;
}
 
/** Remove all matching items from hash table.
*
* For each removed item, h->remove_callback() is called.
*
* @param h Hash table.
* @param key Array of keys that will be compared against items of
* the hash table.
* @param keys Number of keys in the 'key' array.
*/
void hash_table_remove(hash_table_t *h, unsigned long key[], hash_count_t keys)
{
hash_index_t chain;
link_t *cur;
 
assert(h && h->op && h->op->hash && h->op->compare &&
h->op->remove_callback);
assert(keys <= h->max_keys);
if (keys == h->max_keys) {
 
/*
* All keys are known, hash_table_find() can be used to find the
* entry.
*/
cur = hash_table_find(h, key);
if (cur) {
list_remove(cur);
h->op->remove_callback(cur);
}
return;
}
/*
* Fewer keys were passed.
* Any partially matching entries are to be removed.
*/
for (chain = 0; chain < h->entries; chain++) {
for (cur = h->entry[chain].next; cur != &h->entry[chain];
cur = cur->next) {
if (h->op->compare(key, keys, cur)) {
link_t *hlp;
hlp = cur;
cur = cur->prev;
list_remove(hlp);
h->op->remove_callback(hlp);
continue;
}
}
}
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/adt/list.c
0,0 → 1,112
/*
* Copyright (c) 2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <adt/list.h>
 
 
/** Check for membership
*
* Check whether link is contained in the list head.
* The membership is defined as pointer equivalence.
*
* @param link Item to look for.
* @param head List to look in.
*
* @return true if link is contained in head, false otherwise.
*
*/
int list_member(const link_t *link, const link_t *head)
{
int found = 0;
link_t *hlp = head->next;
while (hlp != head) {
if (hlp == link) {
found = 1;
break;
}
hlp = hlp->next;
}
return found;
}
 
 
/** Concatenate two lists
*
* Concatenate lists head1 and head2, producing a single
* list head1 containing items from both (in head1, head2
* order) and empty list head2.
*
* @param head1 First list and concatenated output
* @param head2 Second list and empty output.
*
*/
void list_concat(link_t *head1, link_t *head2)
{
if (list_empty(head2))
return;
head2->next->prev = head1->prev;
head2->prev->next = head1;
head1->prev->next = head2->next;
head1->prev = head2->prev;
list_initialize(head2);
}
 
 
/** Count list items
*
* Return the number of items in the list.
*
* @param link List to count.
*
* @return Number of items in the list.
*
*/
unsigned int list_count(const link_t *link)
{
unsigned int count = 0;
link_t *hlp = link->next;
while (hlp != link) {
count++;
hlp = hlp->next;
}
return count;
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/mem.c
0,0 → 1,239
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <mem.h>
#include <stdlib.h>
#include <sys/types.h>
 
/** Fill memory block with a constant value. */
void *memset(void *dest, int b, size_t n)
{
char *pb;
unsigned long *pw;
size_t word_size;
size_t n_words;
 
unsigned long pattern;
size_t i;
size_t fill;
 
/* Fill initial segment. */
word_size = sizeof(unsigned long);
fill = word_size - ((uintptr_t) dest & (word_size - 1));
if (fill > n) fill = n;
 
pb = dest;
 
i = fill;
while (i-- != 0)
*pb++ = b;
 
/* Compute remaining size. */
n -= fill;
if (n == 0) return dest;
 
n_words = n / word_size;
n = n % word_size;
pw = (unsigned long *) pb;
 
/* Create word-sized pattern for aligned segment. */
pattern = 0;
i = word_size;
while (i-- != 0)
pattern = (pattern << 8) | (uint8_t) b;
 
/* Fill aligned segment. */
i = n_words;
while (i-- != 0)
*pw++ = pattern;
 
pb = (char *) pw;
 
/* Fill final segment. */
i = n;
while (i-- != 0)
*pb++ = b;
 
return dest;
}
 
struct along {
unsigned long n;
} __attribute__ ((packed));
 
static void *unaligned_memcpy(void *dst, const void *src, size_t n)
{
size_t i, j;
struct along *adst = dst;
const struct along *asrc = src;
 
for (i = 0; i < n / sizeof(unsigned long); i++)
adst[i].n = asrc[i].n;
for (j = 0; j < n % sizeof(unsigned long); j++)
((unsigned char *) (((unsigned long *) dst) + i))[j] =
((unsigned char *) (((unsigned long *) src) + i))[j];
return (char *) dst;
}
 
/** Copy memory block. */
void *memcpy(void *dst, const void *src, size_t n)
{
size_t i;
size_t mod, fill;
size_t word_size;
size_t n_words;
 
const unsigned long *srcw;
unsigned long *dstw;
const uint8_t *srcb;
uint8_t *dstb;
 
word_size = sizeof(unsigned long);
 
/*
* Are source and destination addresses congruent modulo word_size?
* If not, use unaligned_memcpy().
*/
 
if (((uintptr_t) dst & (word_size - 1)) !=
((uintptr_t) src & (word_size - 1)))
return unaligned_memcpy(dst, src, n);
 
/*
* mod is the address modulo word size. fill is the length of the
* initial buffer segment before the first word boundary.
* If the buffer is very short, use unaligned_memcpy(), too.
*/
 
mod = (uintptr_t) dst & (word_size - 1);
fill = word_size - mod;
if (fill > n) fill = n;
 
/* Copy the initial segment. */
 
srcb = src;
dstb = dst;
 
i = fill;
while (i-- != 0)
*dstb++ = *srcb++;
 
/* Compute remaining length. */
 
n -= fill;
if (n == 0) return dst;
 
/* Pointers to aligned segment. */
 
dstw = (unsigned long *) dstb;
srcw = (const unsigned long *) srcb;
 
n_words = n / word_size; /* Number of whole words to copy. */
n -= n_words * word_size; /* Remaining bytes at the end. */
 
/* "Fast" copy. */
i = n_words;
while (i-- != 0)
*dstw++ = *srcw++;
 
/*
* Copy the rest.
*/
 
srcb = (const uint8_t *) srcw;
dstb = (uint8_t *) dstw;
 
i = n;
while (i-- != 0)
*dstb++ = *srcb++;
 
return dst;
}
 
/** Move memory block with possible overlapping. */
void *memmove(void *dst, const void *src, size_t n)
{
const uint8_t *sp;
uint8_t *dp;
 
/* Nothing to do? */
if (src == dst)
return dst;
 
/* Non-overlapping? */
if (dst >= src + n || src >= dst + n) {
return memcpy(dst, src, n);
}
 
/* Which direction? */
if (src > dst) {
/* Forwards. */
sp = src;
dp = dst;
 
while (n-- != 0)
*dp++ = *sp++;
} else {
/* Backwards. */
sp = src + (n - 1);
dp = dst + (n - 1);
 
while (n-- != 0)
*dp-- = *sp--;
}
 
return dst;
}
 
/** Compare two memory areas.
*
* @param s1 Pointer to the first area to compare.
* @param s2 Pointer to the second area to compare.
* @param len Size of the first area in bytes. Both areas must have
* the same length.
* @return If len is 0, return zero. If the areas match, return
* zero. Otherwise return non-zero.
*/
int bcmp(const char *s1, const char *s2, size_t len)
{
for (; len && *s1++ == *s2++; len--)
;
return len;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/lib/libc/generic/loader.c
30,10 → 30,11
* @{
*/
/** @file
*/
*/
 
#include <ipc/ipc.h>
#include <ipc/loader.h>
#include <ipc/services.h>
#include <libc.h>
#include <task.h>
#include <string.h>
46,33 → 47,29
/** Connect to a new program loader.
*
* Spawns a new program loader task and returns the connection structure.
* @return Pointer to the loader connection structure (should be
* de-allocated using free() after use).
*
* @param name Symbolic name to set on the newly created task.
*
* @return Pointer to the loader connection structure (should be
* deallocated using free() after use).
*
*/
loader_t *loader_spawn(void)
int loader_spawn(const char *name)
{
int phone_id, rc;
loader_t *ldr;
return __SYSCALL2(SYS_PROGRAM_SPAWN_LOADER,
(sysarg_t) name, str_size(name));
}
 
/*
* Ask kernel to spawn a new loader task.
*/
rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
if (rc != 0)
loader_t *loader_connect(void)
{
int phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
if (phone_id < 0)
return NULL;
 
/*
* Say hello so that the loader knows the incoming connection's
* phone hash.
*/
rc = async_req_0_0(phone_id, LOADER_HELLO);
if (rc != EOK)
return NULL;
 
ldr = malloc(sizeof(loader_t));
loader_t *ldr = malloc(sizeof(loader_t));
if (ldr == NULL)
return NULL;
 
ldr->phone_id = phone_id;
return ldr;
}
81,27 → 78,26
*
* Retrieves the ID of the new task from the loader.
*
* @param ldr Loader connection structure.
* @param task_id Points to a variable where the ID should be stored.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
* @param task_id Points to a variable where the ID should be stored.
*
* @return Zero on success or negative error code.
*
*/
int loader_get_task_id(loader_t *ldr, task_id_t *task_id)
{
/* Get task ID. */
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
/* Get task ID. */
req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
ipcarg_t retval;
async_wait_for(req, &retval);
return (int)retval;
return (int) retval;
}
 
/** Set pathname of the program to load.
110,39 → 106,35
* to the current working directory (it will be absolutized before
* sending to the loader).
*
* @param ldr Loader connection structure.
* @param path Pathname of the program file.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
* @param path Pathname of the program file.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_pathname(loader_t *ldr, const char *path)
{
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
char *pa;
size_t pa_len;
 
pa = absolutize(path, &pa_len);
char *pa = absolutize(path, &pa_len);
if (!pa)
return 0;
 
/* Send program pathname */
req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
rc = ipc_data_write_start(ldr->phone_id, (void *)pa, pa_len);
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
free(pa);
 
ipcarg_t retval;
async_wait_for(req, &retval);
return (int)retval;
return (int) retval;
}
 
 
/** Set command-line arguments for the program.
*
* Sets the vector of command-line arguments to be passed to the loaded
149,60 → 141,110
* program. By convention, the very first argument is typically the same as
* the command used to execute the program.
*
* @param ldr Loader connection structure.
* @param argv NULL-terminated array of pointers to arguments.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
* @param argv NULL-terminated array of pointers to arguments.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_args(loader_t *ldr, char *const argv[])
{
aid_t req;
ipc_call_t answer;
ipcarg_t rc;
 
char *const *ap;
char *dp;
char *arg_buf;
size_t buffer_size;
 
/*
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
ap = argv;
buffer_size = 0;
char *const *ap = argv;
size_t buffer_size = 0;
while (*ap != NULL) {
buffer_size += strlen(*ap) + 1;
++ap;
buffer_size += str_size(*ap) + 1;
ap++;
}
 
arg_buf = malloc(buffer_size);
if (arg_buf == NULL) return ENOMEM;
 
char *arg_buf = malloc(buffer_size);
if (arg_buf == NULL)
return ENOMEM;
/* Now fill the buffer with null-terminated argument strings */
ap = argv;
dp = arg_buf;
char *dp = arg_buf;
while (*ap != NULL) {
strcpy(dp, *ap);
dp += strlen(*ap) + 1;
 
++ap;
str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
dp += str_size(*ap) + 1;
ap++;
}
 
/* Send serialized arguments to the loader */
 
req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
rc = ipc_data_write_start(ldr->phone_id, (void *)arg_buf, buffer_size);
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
async_wait_for(req, &rc);
if (rc != EOK) return rc;
 
if (rc != EOK)
return rc;
/* Free temporary buffer */
free(arg_buf);
return EOK;
}
 
/** Set preset files for the program.
*
* Sets the vector of preset files to be passed to the loaded
* program. By convention, the first three files represent stdin,
* stdout and stderr respectively.
*
* @param ldr Loader connection structure.
* @param files NULL-terminated array of pointers to files.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_files(loader_t *ldr, fdi_node_t *const files[])
{
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
fdi_node_t *const *ap = files;
size_t count = 0;
while (*ap != NULL) {
count++;
ap++;
}
fdi_node_t *files_buf;
files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t));
if (files_buf == NULL)
return ENOMEM;
/* Fill the buffer */
size_t i;
for (i = 0; i < count; i++)
files_buf[i] = *files[i];
/* Send serialized files to the loader */
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,
count * sizeof(fdi_node_t));
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
/* Free temporary buffer */
free(files_buf);
return EOK;
}
 
211,18 → 253,14
* If this function succeeds, the program has been successfully loaded
* and is ready to be executed.
*
* @param ldr Loader connection structure.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
int loader_load_program(loader_t *ldr)
{
int rc;
 
rc = async_req_0_0(ldr->phone_id, LOADER_LOAD);
if (rc != EOK)
return rc;
 
return EOK;
return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
}
 
/** Instruct loader to execute the program.
234,17 → 272,19
* After using this function, no further operations must be performed
* on the loader structure. It should be de-allocated using free().
*
* @param ldr Loader connection structure.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
int loader_run(loader_t *ldr)
{
int rc;
 
rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
if (rc != EOK)
return rc;
 
ipc_hangup(ldr->phone_id);
ldr->phone_id = 0;
return EOK;
}
 
254,8 → 294,10
* After using this function, no further operations must be performed
* on the loader structure. It should be de-allocated using free().
*
* @param ldr Loader connection structure.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
void loader_abort(loader_t *ldr)
{
/branches/arm/uspace/lib/libc/generic/string.c
1,7 → 1,6
/*
* Copyright (c) 2005 Martin Decky
* Copyright (C) 1998 by Wes Peters <wes@softweyr.com>
* Copyright (c) 1988, 1993 The Regents of the University of California.
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
35,180 → 34,665
*/
 
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <ctype.h>
#include <limits.h>
#include <malloc.h>
#include <errno.h>
#include <align.h>
#include <sys/types.h>
#include <malloc.h>
#include <mem.h>
#include <string.h>
 
/* Dummy implementation of mem/ functions */
/** Byte mask consisting of lowest @n bits (out of 8) */
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1))
 
void *memset(void *s, int c, size_t n)
/** Byte mask consisting of lowest @n bits (out of 32) */
#define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of highest @n bits (out of 8) */
#define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))
 
/** Number of data bits in a UTF-8 continuation byte */
#define CONT_BITS 6
 
/** Decode a single character from a string.
*
* Decode a single character from a string of size @a size. Decoding starts
* at @a offset and this offset is moved to the beginning of the next
* character. In case of decoding error, offset generally advances at least
* by one. However, offset is never moved beyond size.
*
* @param str String (not necessarily NULL-terminated).
* @param offset Byte offset in string where to start decoding.
* @param size Size of the string (in bytes).
*
* @return Value of decoded character, U_SPECIAL on decoding error or
* NULL if attempt to decode beyond @a size.
*
*/
wchar_t str_decode(const char *str, size_t *offset, size_t size)
{
char *os = s;
if (*offset + 1 > size)
return 0;
while (n--)
*(os++) = c;
/* First byte read from string */
uint8_t b0 = (uint8_t) str[(*offset)++];
return s;
/* Determine code length */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((b0 & 0x80) == 0) {
/* 0xxxxxxx (Plain ASCII) */
b0_bits = 7;
cbytes = 0;
} else if ((b0 & 0xe0) == 0xc0) {
/* 110xxxxx 10xxxxxx */
b0_bits = 5;
cbytes = 1;
} else if ((b0 & 0xf0) == 0xe0) {
/* 1110xxxx 10xxxxxx 10xxxxxx */
b0_bits = 4;
cbytes = 2;
} else if ((b0 & 0xf8) == 0xf0) {
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
b0_bits = 3;
cbytes = 3;
} else {
/* 10xxxxxx -- unexpected continuation byte */
return U_SPECIAL;
}
if (*offset + cbytes > size)
return U_SPECIAL;
wchar_t ch = b0 & LO_MASK_8(b0_bits);
/* Decode continuation bytes */
while (cbytes > 0) {
uint8_t b = (uint8_t) str[(*offset)++];
/* Must be 10xxxxxx */
if ((b & 0xc0) != 0x80)
return U_SPECIAL;
/* Shift data bits to ch */
ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
cbytes--;
}
return ch;
}
 
struct along {
unsigned long n;
} __attribute__ ((packed));
/** Encode a single character to string representation.
*
* Encode a single character to string representation (i.e. UTF-8) and store
* it into a buffer at @a offset. Encoding starts at @a offset and this offset
* is moved to the position where the next character can be written to.
*
* @param ch Input character.
* @param str Output buffer.
* @param offset Byte offset where to start writing.
* @param size Size of the output buffer (in bytes).
*
* @return EOK if the character was encoded successfully, EOVERFLOW if there
* was not enough space in the output buffer or EINVAL if the character
* code was invalid.
*/
int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
{
if (*offset >= size)
return EOVERFLOW;
if (!chr_check(ch))
return EINVAL;
/* Unsigned version of ch (bit operations should only be done
on unsigned types). */
uint32_t cc = (uint32_t) ch;
/* Determine how many continuation bytes are needed */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((cc & ~LO_MASK_32(7)) == 0) {
b0_bits = 7;
cbytes = 0;
} else if ((cc & ~LO_MASK_32(11)) == 0) {
b0_bits = 5;
cbytes = 1;
} else if ((cc & ~LO_MASK_32(16)) == 0) {
b0_bits = 4;
cbytes = 2;
} else if ((cc & ~LO_MASK_32(21)) == 0) {
b0_bits = 3;
cbytes = 3;
} else {
/* Codes longer than 21 bits are not supported */
return EINVAL;
}
/* Check for available space in buffer */
if (*offset + cbytes >= size)
return EOVERFLOW;
/* Encode continuation bytes */
unsigned int i;
for (i = cbytes; i > 0; i--) {
str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
cc = cc >> CONT_BITS;
}
/* Encode first byte */
str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
/* Advance offset */
*offset += cbytes + 1;
return EOK;
}
 
static void *unaligned_memcpy(void *dst, const void *src, size_t n)
/** Get size of string.
*
* Get the number of bytes which are used by the string @a str (excluding the
* NULL-terminator).
*
* @param str String to consider.
*
* @return Number of bytes used by the string
*
*/
size_t str_size(const char *str)
{
int i, j;
struct along *adst = dst;
const struct along *asrc = src;
size_t size = 0;
while (*str++ != 0)
size++;
return size;
}
 
for (i = 0; i < n / sizeof(unsigned long); i++)
adst[i].n = asrc[i].n;
/** Get size of wide string.
*
* Get the number of bytes which are used by the wide string @a str (excluding the
* NULL-terminator).
*
* @param str Wide string to consider.
*
* @return Number of bytes used by the wide string
*
*/
size_t wstr_size(const wchar_t *str)
{
return (wstr_length(str) * sizeof(wchar_t));
}
 
/** Get size of string with length limit.
*
* Get the number of bytes which are used by up to @a max_len first
* characters in the string @a str. If @a max_len is greater than
* the length of @a str, the entire string is measured (excluding the
* NULL-terminator).
*
* @param str String to consider.
* @param max_len Maximum number of characters to measure.
*
* @return Number of bytes used by the characters.
*
*/
size_t str_lsize(const char *str, size_t max_len)
{
size_t len = 0;
size_t offset = 0;
while (len < max_len) {
if (str_decode(str, &offset, STR_NO_LIMIT) == 0)
break;
for (j = 0; j < n % sizeof(unsigned long); j++)
((unsigned char *) (((unsigned long *) dst) + i))[j] =
((unsigned char *) (((unsigned long *) src) + i))[j];
return (char *) dst;
len++;
}
return offset;
}
 
void *memcpy(void *dst, const void *src, size_t n)
/** Get size of wide string with length limit.
*
* Get the number of bytes which are used by up to @a max_len first
* wide characters in the wide string @a str. If @a max_len is greater than
* the length of @a str, the entire wide string is measured (excluding the
* NULL-terminator).
*
* @param str Wide string to consider.
* @param max_len Maximum number of wide characters to measure.
*
* @return Number of bytes used by the wide characters.
*
*/
size_t wstr_lsize(const wchar_t *str, size_t max_len)
{
int i, j;
return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
}
 
if (((long) dst & (sizeof(long) - 1)) ||
((long) src & (sizeof(long) - 1)))
return unaligned_memcpy(dst, src, n);
/** Get number of characters in a string.
*
* @param str NULL-terminated string.
*
* @return Number of characters in string.
*
*/
size_t str_length(const char *str)
{
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, STR_NO_LIMIT) != 0)
len++;
return len;
}
 
for (i = 0; i < n / sizeof(unsigned long); i++)
((unsigned long *) dst)[i] = ((unsigned long *) src)[i];
for (j = 0; j < n % sizeof(unsigned long); j++)
((unsigned char *) (((unsigned long *) dst) + i))[j] =
((unsigned char *) (((unsigned long *) src) + i))[j];
return (char *) dst;
/** Get number of characters in a wide string.
*
* @param str NULL-terminated wide string.
*
* @return Number of characters in @a str.
*
*/
size_t wstr_length(const wchar_t *wstr)
{
size_t len = 0;
while (*wstr++ != 0)
len++;
return len;
}
 
void *memmove(void *dst, const void *src, size_t n)
/** Get number of characters in a string with size limit.
*
* @param str NULL-terminated string.
* @param size Maximum number of bytes to consider.
*
* @return Number of characters in string.
*
*/
size_t str_nlength(const char *str, size_t size)
{
int i, j;
size_t len = 0;
size_t offset = 0;
if (src > dst)
return memcpy(dst, src, n);
while (str_decode(str, &offset, size) != 0)
len++;
return len;
}
 
for (j = (n % sizeof(unsigned long)) - 1; j >= 0; j--)
((unsigned char *) ((unsigned long *) dst))[j] =
((unsigned char *) ((unsigned long *) src))[j];
/** Get number of characters in a string with size limit.
*
* @param str NULL-terminated string.
* @param size Maximum number of bytes to consider.
*
* @return Number of characters in string.
*
*/
size_t wstr_nlength(const wchar_t *str, size_t size)
{
size_t len = 0;
size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
size_t offset = 0;
while ((offset < limit) && (*str++ != 0)) {
len++;
offset += sizeof(wchar_t);
}
return len;
}
 
for (i = n / sizeof(unsigned long) - 1; i >=0 ; i--)
((unsigned long *) dst)[i] = ((unsigned long *) src)[i];
return (char *) dst;
/** Check whether character is plain ASCII.
*
* @return True if character is plain ASCII.
*
*/
bool ascii_check(wchar_t ch)
{
if ((ch >= 0) && (ch <= 127))
return true;
return false;
}
 
/** Compare two memory areas.
/** Check whether character is valid
*
* @param s1 Pointer to the first area to compare.
* @param s2 Pointer to the second area to compare.
* @param len Size of the first area in bytes. Both areas must have
* the same length.
* @return If len is 0, return zero. If the areas match, return
* zero. Otherwise return non-zero.
* @return True if character is a valid Unicode code point.
*
*/
int bcmp(const char *s1, const char *s2, size_t len)
bool chr_check(wchar_t ch)
{
for (; len && *s1++ == *s2++; len--)
;
return len;
if ((ch >= 0) && (ch <= 1114111))
return true;
return false;
}
 
/** Count the number of characters in the string, not including terminating 0.
/** Compare two NULL terminated strings.
*
* @param str String.
* @return Number of characters in string.
* Do a char-by-char comparison of two NULL-terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths.
*
* @param s1 First string to compare.
* @param s2 Second string to compare.
*
* @return 0 if the strings are equal, -1 if first is smaller,
* 1 if second smaller.
*
*/
size_t strlen(const char *str)
int str_cmp(const char *s1, const char *s2)
{
size_t counter = 0;
wchar_t c1 = 0;
wchar_t c2 = 0;
size_t off1 = 0;
size_t off2 = 0;
 
while (str[counter] != 0)
counter++;
while (true) {
c1 = str_decode(s1, &off1, STR_NO_LIMIT);
c2 = str_decode(s2, &off2, STR_NO_LIMIT);
 
return counter;
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
 
if (c1 == 0 || c2 == 0)
break;
}
 
return 0;
}
 
int strcmp(const char *a, const char *b)
/** Compare two NULL terminated strings with length limit.
*
* Do a char-by-char comparison of two NULL-terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths and the length limit.
*
* @param s1 First string to compare.
* @param s2 Second string to compare.
* @param max_len Maximum number of characters to consider.
*
* @return 0 if the strings are equal, -1 if first is smaller,
* 1 if second smaller.
*
*/
int str_lcmp(const char *s1, const char *s2, size_t max_len)
{
int c = 0;
wchar_t c1 = 0;
wchar_t c2 = 0;
while (a[c] && b[c] && (!(a[c] - b[c])))
c++;
size_t off1 = 0;
size_t off2 = 0;
return (a[c] - b[c]);
size_t len = 0;
 
while (true) {
if (len >= max_len)
break;
 
c1 = str_decode(s1, &off1, STR_NO_LIMIT);
c2 = str_decode(s2, &off2, STR_NO_LIMIT);
 
if (c1 < c2)
return -1;
 
if (c1 > c2)
return 1;
 
if (c1 == 0 || c2 == 0)
break;
 
++len;
}
 
return 0;
 
}
 
int strncmp(const char *a, const char *b, size_t n)
/** Copy string.
*
* Copy source string @a src to destination buffer @a dest.
* No more than @a size bytes are written. If the size of the output buffer
* is at least one byte, the output string will always be well-formed, i.e.
* null-terminated and containing only complete characters.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer (must be > 0).
* @param src Source string.
*/
void str_cpy(char *dest, size_t size, const char *src)
{
size_t c = 0;
wchar_t ch;
size_t src_off;
size_t dest_off;
 
while (c < n && a[c] && b[c] && (!(a[c] - b[c])))
c++;
/* There must be space for a null terminator in the buffer. */
assert(size > 0);
return ( c < n ? a[c] - b[c] : 0);
src_off = 0;
dest_off = 0;
 
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
break;
}
 
dest[dest_off] = '\0';
}
 
/** Copy size-limited substring.
*
* Copy prefix of string @a src of max. size @a size to destination buffer
* @a dest. No more than @a size bytes are written. The output string will
* always be well-formed, i.e. null-terminated and containing only complete
* characters.
*
* No more than @a n bytes are read from the input string, so it does not
* have to be null-terminated.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer (must be > 0).
* @param src Source string.
* @param n Maximum number of bytes to read from @a src.
*/
void str_ncpy(char *dest, size_t size, const char *src, size_t n)
{
wchar_t ch;
size_t src_off;
size_t dest_off;
 
/* There must be space for a null terminator in the buffer. */
assert(size > 0);
src_off = 0;
dest_off = 0;
 
while ((ch = str_decode(src, &src_off, n)) != 0) {
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
break;
}
 
dest[dest_off] = '\0';
}
 
int stricmp(const char *a, const char *b)
/** Append one string to another.
*
* Append source string @a src to string in destination buffer @a dest.
* Size of the destination buffer is @a dest. If the size of the output buffer
* is at least one byte, the output string will always be well-formed, i.e.
* null-terminated and containing only complete characters.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer.
* @param src Source string.
*/
void str_append(char *dest, size_t size, const char *src)
{
int c = 0;
size_t dstr_size;
 
dstr_size = str_size(dest);
str_cpy(dest + dstr_size, size - dstr_size, src);
}
 
/** Copy NULL-terminated wide string to string
*
* Copy source wide string @a src to destination buffer @a dst.
* No more than @a size bytes are written. NULL-terminator is always
* written after the last succesfully copied character (i.e. if the
* destination buffer is has at least 1 byte, it will be always
* NULL-terminated).
*
* @param src Source wide string.
* @param dst Destination buffer.
* @param count Size of the destination buffer.
*
*/
void wstr_nstr(char *dst, const wchar_t *src, size_t size)
{
/* No space for the NULL-terminator in the buffer */
if (size == 0)
return;
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c]))))
c++;
wchar_t ch;
size_t src_idx = 0;
size_t dst_off = 0;
return (tolower(a[c]) - tolower(b[c]));
while ((ch = src[src_idx++]) != 0) {
if (chr_encode(ch, dst, &dst_off, size) != EOK)
break;
}
if (dst_off >= size)
dst[size - 1] = 0;
else
dst[dst_off] = 0;
}
 
/** Return pointer to the first occurence of character c in string.
/** Find first occurence of character in string.
*
* @param str Scanned string.
* @param c Searched character (taken as one byte).
* @return Pointer to the matched character or NULL if it is not
* found in given string.
* @param str String to search.
* @param ch Character to look for.
*
* @return Pointer to character in @a str or NULL if not found.
*/
char *strchr(const char *str, int c)
const char *str_chr(const char *str, wchar_t ch)
{
while (*str != '\0') {
if (*str == (char) c)
return (char *) str;
str++;
wchar_t acc;
size_t off = 0;
size_t last = 0;
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (str + last);
last = off;
}
 
return NULL;
}
 
/** Return pointer to the last occurence of character c in string.
/** Find last occurence of character in string.
*
* @param str Scanned string.
* @param c Searched character (taken as one byte).
* @return Pointer to the matched character or NULL if it is not
* found in given string.
* @param str String to search.
* @param ch Character to look for.
*
* @return Pointer to character in @a str or NULL if not found.
*/
char *strrchr(const char *str, int c)
const char *str_rchr(const char *str, wchar_t ch)
{
char *retval = NULL;
 
while (*str != '\0') {
if (*str == (char) c)
retval = (char *) str;
str++;
wchar_t acc;
size_t off = 0;
size_t last = 0;
const char *res = NULL;
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
res = (str + last);
last = off;
}
return res;
}
 
return (char *) retval;
/** Insert a wide character into a wide string.
*
* Insert a wide character into a wide string at position
* @a pos. The characters after the position are shifted.
*
* @param str String to insert to.
* @param ch Character to insert to.
* @param pos Character index where to insert.
@ @param max_pos Characters in the buffer.
*
* @return True if the insertion was sucessful, false if the position
* is out of bounds.
*
*/
bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
{
size_t len = wstr_length(str);
if ((pos > len) || (pos + 1 > max_pos))
return false;
size_t i;
for (i = len; i + 1 > pos; i--)
str[i + 1] = str[i];
str[pos] = ch;
return true;
}
 
/** Remove a wide character from a wide string.
*
* Remove a wide character from a wide string at position
* @a pos. The characters after the position are shifted.
*
* @param str String to remove from.
* @param pos Character index to remove.
*
* @return True if the removal was sucessful, false if the position
* is out of bounds.
*
*/
bool wstr_remove(wchar_t *str, size_t pos)
{
size_t len = wstr_length(str);
if (pos >= len)
return false;
size_t i;
for (i = pos + 1; i <= len; i++)
str[i - 1] = str[i];
return true;
}
 
int stricmp(const char *a, const char *b)
{
int c = 0;
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c]))))
c++;
return (tolower(a[c]) - tolower(b[c]));
}
 
/** Convert string to a number.
* Core of strtol and strtoul functions.
*
358,91 → 842,47
return (sgn ? -number : number);
}
 
char *strcpy(char *dest, const char *src)
char *str_dup(const char *src)
{
char *orig = dest;
while ((*(dest++) = *(src++)))
;
return orig;
}
size_t size = str_size(src);
void *dest = malloc(size + 1);
 
char *strncpy(char *dest, const char *src, size_t n)
{
char *orig = dest;
while ((*(dest++) = *(src++)) && --n)
;
return orig;
}
if (dest == NULL)
return (char *) NULL;
 
char *strcat(char *dest, const char *src)
{
char *orig = dest;
while (*dest++)
;
--dest;
while ((*dest++ = *src++))
;
return orig;
return (char *) memcpy(dest, src, size + 1);
}
 
char * strdup(const char *s1)
char *strtok(char *s, const char *delim)
{
size_t len = strlen(s1) + 1;
void *ret = malloc(len);
static char *next;
 
if (ret == NULL)
return (char *) NULL;
 
return (char *) memcpy(ret, s1, len);
return strtok_r(s, delim, &next);
}
 
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */
char * strtok_r(char *s, const char *delim, char **last)
char *strtok_r(char *s, const char *delim, char **next)
{
char *spanp, *tok;
int c, sc;
char *start, *end;
 
if (s == NULL && (s = *last) == NULL)
return (NULL);
if (s == NULL)
s = *next;
 
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
/* Skip over leading delimiters. */
while (*s && (str_chr(delim, *s) != NULL)) ++s;
start = s;
 
if (c == 0) { /* no non-delimiter characters */
*last = NULL;
return (NULL);
}
/* Skip over token characters. */
while (*s && (str_chr(delim, *s) == NULL)) ++s;
end = s;
*next = (*s ? s + 1 : s);
 
tok = s - 1;
 
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = '\0';
*last = s;
return (tok);
}
} while (sc != 0);
if (start == end) {
return NULL; /* No more tokens. */
}
}
 
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */
char * strtok(char *s, const char *delim)
{
static char *last;
 
return (strtok_r(s, delim, &last));
/* Overwrite delimiter with NULL terminator. */
*end = '\0';
return start;
}
 
/** @}
/branches/arm/uspace/lib/libc/generic/ddi.c
33,26 → 33,42
*/
 
#include <ddi.h>
#include <libarch/ddi.h>
#include <libc.h>
#include <task.h>
#include <as.h>
#include <align.h>
#include <libarch/config.h>
#include <kernel/ddi/ddi_arg.h>
 
/** Return unique device number.
*
* @return New unique device number.
*
*/
int device_assign_devno(void)
{
return __SYSCALL0(SYS_DEVICE_ASSIGN_DEVNO);
}
 
/** Map piece of physical memory to task.
*
* Caller of this function must have the CAP_MEM_MANAGER capability.
*
* @param pf Physical address of the starting frame.
* @param vp Virtual address of the sterting page.
* @param pages Number of pages to map.
* @param flags Flags for the new address space area.
* @param pf Physical address of the starting frame.
* @param vp Virtual address of the starting page.
* @param pages Number of pages to map.
* @param flags Flags for the new address space area.
*
* @return 0 on success, EPERM if the caller lacks the CAP_MEM_MANAGER capability,
* ENOENT if there is no task with specified ID and ENOMEM if there
* was some problem in creating address space area.
* @return 0 on success, EPERM if the caller lacks the
* CAP_MEM_MANAGER capability, ENOENT if there is no task
* with specified ID and ENOMEM if there was some problem
* in creating address space area.
*/
int physmem_map(void *pf, void *vp, unsigned long pages, int flags)
{
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, flags);
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages,
flags);
}
 
/** Enable I/O space range to task.
59,13 → 75,14
*
* Caller of this function must have the IO_MEM_MANAGER capability.
*
* @param id Task ID.
* @param ioaddr Starting address of the I/O range.
* @param size Size of the range.
* @param id Task ID.
* @param ioaddr Starting address of the I/O range.
* @param size Size of the range.
*
* @return 0 on success, EPERM if the caller lacks the CAP_IO_MANAGER capability,
* ENOENT if there is no task with specified ID and ENOMEM if there
* was some problem in allocating memory.
* @return 0 on success, EPERM if the caller lacks the
* CAP_IO_MANAGER capability, ENOENT if there is no task
* with specified ID and ENOMEM if there was some problem
* in allocating memory.
*/
int iospace_enable(task_id_t id, void *ioaddr, unsigned long size)
{
80,7 → 97,7
 
/** Interrupt control
*
* @param enable 1 - enable interrupts, 0 - disable interrupts
* @param enable 1 - enable interrupts, 0 - disable interrupts
*/
int preemption_control(int enable)
{
87,5 → 104,36
return __SYSCALL1(SYS_PREEMPT_CONTROL, (sysarg_t) enable);
}
 
/** Enable PIO for specified I/O range.
*
* @param pio_addr I/O start address.
* @param size Size of the I/O region.
* @param use_addr Address where the final address for application's PIO
* will be stored.
*
* @return Zero on success or negative error code.
*/
int pio_enable(void *pio_addr, size_t size, void **use_addr)
{
void *phys;
void *virt;
size_t offset;
unsigned int pages;
 
#ifdef IO_SPACE_BOUNDARY
if (pio_addr < IO_SPACE_BOUNDARY) {
*use_addr = pio_addr;
return iospace_enable(task_get_id(), pio_addr, size);
}
#endif
 
phys = (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
offset = pio_addr - phys;
pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH;
virt = as_get_mappable_page(pages << PAGE_WIDTH);
*use_addr = virt + offset;
return physmem_map(phys, virt, pages, AS_AREA_READ | AS_AREA_WRITE);
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/thread.c
108,8 → 108,8
uarg->uspace_thread_arg = arg;
uarg->uspace_uarg = uarg;
rc = __SYSCALL3(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name,
(sysarg_t) tid);
rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name,
(sysarg_t) str_size(name), (sysarg_t) tid);
if (rc) {
/*
130,6 → 130,8
void thread_exit(int status)
{
__SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
for (;;)
;
}
 
/** Detach thread.
152,6 → 154,7
*/
int thread_join(thread_id_t thread)
{
return 0;
}
 
/** Get current thread ID.
/branches/arm/uspace/lib/libc/generic/sysinfo.c
38,7 → 38,8
 
sysarg_t sysinfo_value(char *name)
{
return __SYSCALL2(SYS_SYSINFO_VALUE, (sysarg_t ) name, (sysarg_t) strlen(name));
return __SYSCALL2(SYS_SYSINFO_VALUE, (sysarg_t ) name,
(sysarg_t) str_size(name));
}
 
/** @}
/branches/arm/uspace/lib/libc/generic/event.c
0,0 → 1,57
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
* @}
*/
 
/** @addtogroup libc
*/
/** @file
*/
 
#include <libc.h>
#include <event.h>
#include <kernel/ipc/event_types.h>
#include <ipc/ipc.h>
 
/** Subscribe for event notifications.
*
* @param evno Event number.
* @param method Use this method for notifying me.
*
* @return Value returned by the kernel.
*/
int event_subscribe(event_type_t e, ipcarg_t method)
{
return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method);
}
 
/** @}
*/
/branches/arm/uspace/lib/libc/generic/time.c
47,6 → 47,8
#include <as.h>
#include <ddi.h>
 
#include <time.h>
 
/* Pointers to public variables with time */
struct {
volatile sysarg_t seconds1;
/branches/arm/uspace/lib/libc/generic/tls.c
116,7 → 116,7
tcb_t *tcb;
size = ALIGN_UP(size, &_tls_alignment);
*data = memalign(&_tls_alignment, sizeof(tcb_t) + size);
*data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size);
 
tcb = (tcb_t *) (*data + size);
tcb->self = tcb;
/branches/arm/uspace/lib/libc/generic/smc.c
34,6 → 34,7
 
#include <libc.h>
#include <sys/types.h>
#include <smc.h>
 
int smc_coherence(void *address, size_t size)
{
/branches/arm/uspace/lib/libc/generic/udebug.c
34,7 → 34,6
 
#include <udebug.h>
#include <sys/types.h>
#include <syscall.h>
#include <ipc/ipc.h>
#include <async.h>
 
/branches/arm/uspace/lib/libc/arch/ppc64/_link.ld.in
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/thread.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/fibril.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/syscall.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/atomic.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/regname.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/stackarg.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/faddr.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/limits.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/tls.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/types.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/include/config.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/Makefile.inc
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/src/fibril.S
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/src/thread_entry.s
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/src/syscall.c
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/src/entry.s
File deleted
/branches/arm/uspace/lib/libc/arch/ppc64/src/tls.c
File deleted
/branches/arm/uspace/lib/libc/arch/sparc64/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/sparc64/include/stack.h
45,6 → 45,11
*/
#define STACK_WINDOW_SAVE_AREA_SIZE (16 * STACK_ITEM_SIZE)
 
/*
* Six extended words for first six arguments.
*/
#define STACK_ARG_SAVE_AREA_SIZE (6 * STACK_ITEM_SIZE)
 
/**
* By convention, the actual top of the stack is %sp + STACK_BIAS.
*/
/branches/arm/uspace/lib/libc/arch/sparc64/include/fibril.h
39,7 → 39,7
#include <sys/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
#ifdef context_set
#undef context_set
/branches/arm/uspace/lib/libc/arch/sparc64/include/types.h
47,6 → 47,9
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
 
typedef int64_t ssize_t;
typedef uint64_t size_t;
 
typedef uint64_t uintptr_t;
 
#endif
/branches/arm/uspace/lib/libc/arch/sparc64/include/ddi.h
0,0 → 1,92
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @file
* @ingroup libsparc64
*/
 
#ifndef LIBC_sparc64_DDI_H_
#define LIBC_sparc64_DDI_H_
 
#include <sys/types.h>
#include <libarch/types.h>
 
static inline memory_barrier(void)
{
asm volatile ("membar #LoadLoad | #StoreStore\n" ::: "memory");
}
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
memory_barrier();
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
memory_barrier();
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
memory_barrier();
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
#endif
/branches/arm/uspace/lib/libc/arch/sparc64/include/syscall.h
38,6 → 38,14
#include <sys/types.h>
#include <kernel/syscall/syscall.h>
 
#define __syscall0 __syscall
#define __syscall1 __syscall
#define __syscall2 __syscall
#define __syscall3 __syscall
#define __syscall4 __syscall
#define __syscall5 __syscall
#define __syscall6 __syscall
 
static inline sysarg_t
__syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3,
const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id)
/branches/arm/uspace/lib/libc/arch/sparc64/Makefile.inc
29,18 → 29,16
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = sparc64-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin
 
ARCH_SOURCES += arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c
ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
CFLAGS += -mcpu=ultrasparc -m64
LFLAGS += -no-check-sections -N
 
ENDIANESS = BE
 
BFD_NAME = elf64-sparc
BFD_ARCH = sparc
/branches/arm/uspace/lib/libc/arch/sparc64/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
31,13 → 31,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
.bss : {
*(.sbss);
*(COMMON);
/branches/arm/uspace/lib/libc/arch/ia64/Makefile.inc
29,19 → 29,18
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = ia64-pc-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16
 
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c \
arch/$(UARCH)/src/ddi.c
 
CFLAGS += -fno-unwind-tables
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
AFLAGS +=
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c
ENDIANESS = LE
 
BFD_NAME = elf64-ia64-little
BFD_ARCH = ia64-elf64
/branches/arm/uspace/lib/libc/arch/ia64/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/ia64/include/types.h
47,6 → 47,9
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;
 
typedef int64_t ssize_t;
typedef uint64_t size_t;
 
typedef uint64_t uintptr_t;
 
typedef unsigned char __r8; /* Reserve byte */
/branches/arm/uspace/lib/libc/arch/ia64/include/ddi.h
0,0 → 1,115
/*
* Copyright (c) 2005 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libcia64
* @{
*/
/** @file
*/
 
#ifndef LIBC_ia64_DDI_H_
#define LIBC_ia64_DDI_H_
 
#include <sys/types.h>
#include <libarch/types.h>
 
#define IO_SPACE_BOUNDARY (64 * 1024)
 
uint64_t get_ia64_iospace_address(void);
 
extern uint64_t ia64_iospace_address;
 
#define IA64_IOSPACE_ADDRESS \
(ia64_iospace_address ? \
ia64_iospace_address : \
(ia64_iospace_address = get_ia64_iospace_address()))
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
uintptr_t prt = (uintptr_t) port;
 
*((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
uintptr_t prt = (uintptr_t) port;
 
*((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
uintptr_t prt = (uintptr_t) port;
 
*((ioport32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
#endif
 
/** @}
*/
/branches/arm/uspace/lib/libc/arch/ia64/include/syscall.h
36,6 → 36,8
#ifndef LIBC_ia64_SYSCALL_H_
#define LIBC_ia64_SYSCALL_H_
 
#define LIBARCH_SYSCALL_GENERIC
 
#include <syscall.h>
 
#endif
/branches/arm/uspace/lib/libc/arch/ia64/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
32,13 → 32,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
.bss : {
*(.sbss);
*(.scommon);
/branches/arm/uspace/lib/libc/arch/ia64/src/entry.s
38,7 → 38,7
#
__entry:
alloc loc0 = ar.pfs, 0, 1, 2, 0
mov r1 = _gp
movl r1 = _gp
 
# Pass PCB pointer as the first argument to __main
mov out0 = r2
/branches/arm/uspace/lib/libc/arch/ia64/src/thread_entry.s
36,7 → 36,7
__thread_entry:
alloc loc0 = ar.pfs, 0, 1, 1, 0
 
mov r1 = _gp
movl r1 = _gp
#
# r8 contains address of uarg structure.
/branches/arm/uspace/lib/libc/arch/ia64/src/ddi.c
0,0 → 1,13
#include <libarch/ddi.h>
#include <sysinfo.h>
 
uint64_t ia64_iospace_address=0;
 
 
uint64_t get_ia64_iospace_address(void)
{
 
return sysinfo_value("ia64_iospace.address.virtual");
 
}
 
/branches/arm/uspace/lib/libc/arch/arm32/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/arm32/include/tls.h
40,7 → 40,7
 
#define CONFIG_TLS_VARIANT_1
 
/** Offsets for accessing __thread variables are shifted 8 bytes higher. */
/** Offsets for accessing thread-local variables are shifted 8 bytes higher. */
#define ARM_TP_OFFSET (-8)
 
/** TCB (Thread Control Block) struct.
/branches/arm/uspace/lib/libc/arch/arm32/include/types.h
48,6 → 48,9
typedef unsigned long int uint32_t;
typedef unsigned long long int uint64_t;
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
 
typedef uint32_t uintptr_t;
 
#endif
/branches/arm/uspace/lib/libc/arch/arm32/include/fibril.h
38,7 → 38,7
 
#include <sys/types.h>
#include <align.h>
#include "thread.h"
#include <thread.h>
 
/** Size of a stack item */
#define STACK_ITEM_SIZE 4
/branches/arm/uspace/lib/libc/arch/arm32/include/ddi.h
0,0 → 1,69
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @file
* @ingroup libcarm32
*/
 
#ifndef LIBC_arm32_DDI_H_
#define LIBC_arm32_DDI_H_
 
#include <sys/types.h>
#include <libarch/types.h>
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
/branches/arm/uspace/lib/libc/arch/arm32/include/syscall.h
30,12 → 30,14
* @{
*/
/** @file
* @brief Empty.
* @brief
*/
 
#ifndef LIBC_arm32_SYSCALL_H_
#define LIBC_arm32_SYSCALL_H_
 
#define LIBARCH_SYSCALL_GENERIC
 
#include <syscall.h>
 
#endif
/branches/arm/uspace/lib/libc/arch/arm32/Makefile.inc
30,20 → 30,18
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin
CFLAGS += -ffixed-r9 -mtp=soft
 
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c \
arch/$(UARCH)/src/eabi.S
 
CFLAGS += -ffixed-r9 -mtp=soft
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
AFLAGS +=
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c \
arch/$(ARCH)/src/eabi.S
ENDIANESS = LE
 
BFD_NAME = elf32-littlearm
BFD_ARCH = arm
/branches/arm/uspace/lib/libc/arch/arm32/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
28,13 → 28,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
.bss : {
*(.sbss);
*(.scommon);
/branches/arm/uspace/lib/libc/arch/mips32eb/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/mips32eb/include/ddi.h
0,0 → 1,0
link ../../mips32/include/ddi.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/uspace/lib/libc/arch/mips32eb/Makefile.inc
29,19 → 29,17
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = mips-sgi-irix5
TARGET = mips-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
CFLAGS += -mips3
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
CFLAGS += -mips3
LFLAGS += -N
 
ENDIANESS = BE
 
BFD_ARCH = mips
BFD_NAME = elf32-big
BFD_NAME = elf32-tradbigmips
/branches/arm/uspace/lib/libc/arch/ppc32/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/ppc32/include/types.h
47,6 → 47,9
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
 
typedef uint32_t uintptr_t;
 
#endif
/branches/arm/uspace/lib/libc/arch/ppc32/include/ddi.h
0,0 → 1,69
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @file
* @ingroup libcppc32
*/
 
#ifndef LIBC_ppc32_DDI_H_
#define LIBC_ppc32_DDI_H_
 
#include <sys/types.h>
#include <libarch/types.h>
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
/branches/arm/uspace/lib/libc/arch/ppc32/include/syscall.h
36,6 → 36,8
#ifndef LIBC_ppc32_SYSCALL_H_
#define LIBC_ppc32_SYSCALL_H_
 
#define LIBARCH_SYSCALL_GENERIC
 
#include <syscall.h>
 
#endif
/branches/arm/uspace/lib/libc/arch/ppc32/Makefile.inc
29,20 → 29,18
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = ppc-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
CFLAGS += -mcpu=powerpc -msoft-float -m32
AFLAGS += -a32
LFLAGS += -N
 
ENDIANESS = BE
 
BFD_NAME = elf32-powerpc
BFD_ARCH = powerpc:common
/branches/arm/uspace/lib/libc/arch/ppc32/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
27,13 → 27,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
.bss : {
*(.sbss);
*(COMMON);
/branches/arm/uspace/lib/libc/arch/ppc32/src/entry.s
34,11 → 34,12
 
## User-space task entry point
#
# r3 contains the PCB pointer
# r6 contains the PCB pointer
#
__entry:
# Pass the PCB pointer to __main() as the first argument.
# Since the first argument is passed in r3, no operation is needed.
# The first argument is passed in r3.
mr %r3, %r6
bl __main
 
bl __exit
/branches/arm/uspace/lib/libc/arch/amd64/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/amd64/include/types.h
47,6 → 47,9
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
 
typedef int64_t ssize_t;
typedef uint64_t size_t;
 
typedef uint64_t uintptr_t;
 
#endif
/branches/arm/uspace/lib/libc/arch/amd64/include/syscall.h
36,6 → 36,8
#ifndef LIBC_amd64_SYSCALL_H_
#define LIBC_amd64_SYSCALL_H_
 
#define LIBARCH_SYSCALL_GENERIC
 
#include <syscall.h>
 
#endif
/branches/arm/uspace/lib/libc/arch/amd64/Makefile.inc
29,18 → 29,16
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = amd64-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
LFLAGS += -N
 
ENDIANESS = LE
 
BFD_NAME = elf64-x86-64
BFD_ARCH = i386:x86-64
/branches/arm/uspace/lib/libc/arch/amd64/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
26,13 → 26,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
.bss : {
*(COMMON);
*(.bss);
/branches/arm/uspace/lib/libc/arch/mips32/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/mips32/include/types.h
48,6 → 48,9
typedef unsigned long int uint32_t;
typedef unsigned long long int uint64_t;
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
 
typedef uint32_t uintptr_t;
 
#endif
/branches/arm/uspace/lib/libc/arch/mips32/include/ddi.h
0,0 → 1,69
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @file
* @ingroup libcmips32
*/
 
#ifndef LIBC_mips32_DDI_H_
#define LIBC_mips32_DDI_H_
 
#include <sys/types.h>
#include <libarch/types.h>
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
/branches/arm/uspace/lib/libc/arch/mips32/include/atomic.h
59,13 → 59,14
asm volatile (
"1:\n"
" ll %0, %1\n"
" addiu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" addu %0, %0, %3\n" /* same as add, but never traps on overflow */
" move %2, %0\n"
" sc %0, %1\n"
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
/* nop */ /* nop is inserted automatically by compiler */
" nop\n"
: "=&r" (tmp), "+m" (val->count), "=&r" (v)
: "i" (i), "i" (0)
: "r" (i), "i" (0)
);
 
return v;
/branches/arm/uspace/lib/libc/arch/mips32/include/syscall.h
36,6 → 36,8
#ifndef LIBC_mips32_SYSCALL_H_
#define LIBC_mips32_SYSCALL_H_
 
#define LIBARCH_SYSCALL_GENERIC
 
#include <syscall.h>
 
#endif
/branches/arm/uspace/lib/libc/arch/mips32/Makefile.inc
29,23 → 29,16
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin
CFLAGS += -mips3
 
-include ../../Makefile.config
ifeq ($(CONFIG_MIPS_FPU),y)
CFLAGS += -DCONFIG_MIPS_FPU
endif
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c
CFLAGS += -mips3
 
ENDIANESS = LE
 
BFD_ARCH = mips
BFD_NAME = elf32-tradlittlemips
/branches/arm/uspace/lib/libc/arch/mips32/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
33,13 → 33,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
 
.sbss : {
*(.scommon);
/branches/arm/uspace/lib/libc/arch/ia32/include/byteorder.h
File deleted
/branches/arm/uspace/lib/libc/arch/ia32/include/types.h
47,6 → 47,9
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
 
typedef uint32_t uintptr_t;
 
#endif
/branches/arm/uspace/lib/libc/arch/ia32/include/ddi.h
33,43 → 33,72
#ifndef LIBC_ia32_DDI_H_
#define LIBC_ia32_DDI_H_
 
static inline void outb(int16_t port, uint8_t b)
#include <sys/types.h>
#include <libarch/types.h>
 
#define IO_SPACE_BOUNDARY ((void *) (64 * 1024))
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port));
uint8_t val;
asm volatile (
"inb %w[port], %b[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
static inline void outw(int16_t port, int16_t w)
static inline uint16_t pio_read_16(ioport16_t *port)
{
asm volatile ("outw %0, %1\n" :: "a" (w), "d" (port));
uint16_t val;
asm volatile (
"inw %w[port], %w[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
static inline void outl(int16_t port, uint32_t l)
static inline uint32_t pio_read_32(ioport32_t *port)
{
asm volatile ("outl %0, %1\n" :: "a" (l), "d" (port));
uint32_t val;
asm volatile (
"inl %w[port], %[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
static inline uint8_t inb(int16_t port)
static inline void pio_write_8(ioport8_t *port, uint8_t val)
{
uint8_t val;
 
asm volatile ("inb %1, %0 \n" : "=a" (val) : "d"(port));
return val;
asm volatile (
"outb %b[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
static inline int16_t inw(int16_t port)
static inline void pio_write_16(ioport16_t *port, uint16_t val)
{
int16_t val;
 
asm volatile ("inw %1, %0 \n" : "=a" (val) : "d"(port));
return val;
asm volatile (
"outw %w[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
static inline uint32_t inl(int16_t port)
static inline void pio_write_32(ioport32_t *port, uint32_t val)
{
uint32_t val;
 
asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port));
return val;
asm volatile (
"outl %[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
#endif
/branches/arm/uspace/lib/libc/arch/ia32/include/syscall.h
36,8 → 36,25
#ifndef LIBC_ia32_SYSCALL_H_
#define LIBC_ia32_SYSCALL_H_
 
#include <syscall.h>
#include <sys/types.h>
#include <kernel/syscall/syscall.h>
 
#define __syscall0 __syscall_sysenter
#define __syscall1 __syscall_sysenter
#define __syscall2 __syscall_sysenter
#define __syscall3 __syscall_sysenter
#define __syscall4 __syscall_sysenter
#define __syscall5 __syscall_int
#define __syscall6 __syscall_int
 
extern sysarg_t
__syscall_sysenter(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
const sysarg_t, const sysarg_t, const syscall_t);
 
extern sysarg_t
__syscall_int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
const sysarg_t, const sysarg_t, const syscall_t);
 
#endif
 
/** @}
/branches/arm/uspace/lib/libc/arch/ia32/Makefile.inc
29,19 → 29,17
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
TARGET = i686-pc-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin
 
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
arch/$(ARCH)/src/fibril.S \
arch/$(ARCH)/src/tls.c \
arch/$(ARCH)/src/setjmp.S
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c \
arch/$(UARCH)/src/setjmp.S
 
LFLAGS += -N
 
ENDIANESS = LE
 
BFD_NAME = elf32-i386
BFD_ARCH = i386
/branches/arm/uspace/lib/libc/arch/ia32/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
26,13 → 26,11
_tdata_start = .;
*(.tdata);
_tdata_end = .;
} :data
.tbss : {
_tbss_start = .;
*(.tbss);
_tbss_end = .;
} :data
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
_tls_alignment = ALIGNOF(.tdata);
.bss : {
*(COMMON);
*(.bss);
/branches/arm/uspace/lib/libc/arch/ia32/src/syscall.S
28,14 → 28,14
 
.text
 
/** Syscall wrapper.
/** Syscall wrapper - INT $0x30 version.
*
* Mind the order of arguments. First two arguments and the syscall number go to
* scratch registers. An optimized version of this wrapper for fewer arguments
* could benefit from this and not save unused registers on the stack.
*/
.global __syscall
__syscall:
.global __syscall_int
__syscall_int:
pushl %ebx
pushl %esi
pushl %edi
53,3 → 53,38
popl %esi
popl %ebx
ret
 
 
/** Syscall wrapper - SYSENTER version.
*
* This is an optimized version of syscall for four or less arguments. Note
* that EBP and EDI are used to remember user stack address and the return
* address. The kernel part doesn't save DS, ES and FS so the handler restores
* these to the selector immediately following CS (it must be the flat data
* segment, otherwise the SYSENTER wouldn't work in the first place).
*/
.global __syscall_sysenter
__syscall_sysenter:
pushl %ebx
pushl %esi
pushl %edi
pushl %ebp
mov %esp, %ebp
lea ra, %edi
movl 20(%esp), %edx # First argument.
movl 24(%esp), %ecx # Second argument.
movl 28(%esp), %ebx # Third argument.
movl 32(%esp), %esi # Fourth argument.
movl 44(%esp), %eax # Syscall number.
sysenter
ra:
movw %cs, %cx
addw $8, %cx
movw %cx, %ds
movw %cx, %es
movw %cx, %fs
popl %ebp
popl %edi
popl %esi
popl %ebx
ret
/branches/arm/uspace/lib/libc/Makefile
31,26 → 31,29
 
LIBC_PREFIX = $(shell pwd)
SOFTINT_PREFIX = ../softint
CONSOLE_PREFIX = ../../srv/console
 
 
## Setup toolchain
#
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I$(CONSOLE_PREFIX)
 
## Sources
#
 
 
GENERIC_SOURCES = \
generic/libc.c \
generic/ddi.c \
generic/as.c \
generic/cap.c \
generic/devmap.c \
generic/event.c \
generic/errno.c \
generic/mem.c \
generic/string.c \
generic/fibril.c \
generic/fibril_sync.c \
generic/pcb.c \
generic/smc.c \
generic/thread.c \
60,21 → 63,20
generic/io/asprintf.c \
generic/io/io.c \
generic/io/printf.c \
generic/io/stream.c \
generic/io/sprintf.c \
generic/io/klog.c \
generic/io/snprintf.c \
generic/io/vprintf.c \
generic/io/vsprintf.c \
generic/io/vsnprintf.c \
generic/io/printf_core.c \
malloc/malloc.c \
generic/io/console.c \
generic/malloc.c \
generic/sysinfo.c \
generic/ipc.c \
generic/async.c \
generic/loader.c \
generic/getopt.c \
generic/libadt/list.o \
generic/libadt/hash_table.o \
generic/adt/list.o \
generic/adt/hash_table.o \
generic/time.c \
generic/err.c \
generic/stdlib.c \
84,34 → 86,35
generic/vfs/canonify.c
 
ARCH_SOURCES += \
arch/$(ARCH)/src/entry.s \
arch/$(ARCH)/src/thread_entry.s
arch/$(UARCH)/src/entry.s \
arch/$(UARCH)/src/thread_entry.s
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS)
 
.PHONY: all clean depend kerninc
 
all: kerninc libc.a arch/$(ARCH)/_link.ld
all: kerninc libc.a arch/$(UARCH)/_link.ld
 
kerninc:
ln -sfn ../../../../kernel/generic/include include/kernel
ln -sfn kernel/arch include/arch
ln -sfn ../arch/$(ARCH)/include include/libarch
ln -sfn ../arch/$(UARCH)/include include/libarch
 
-include Makefile.depend
 
clean:
-rm -f include/kernel include/arch include/libarch libc.a arch/$(ARCH)/_link.ld Makefile.depend
find generic/ arch/$(ARCH)/ -name '*.o' -follow -exec rm \{\} \;
-rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend
find generic/ arch/$(UARCH)/ -name '*.o' -follow -exec rm \{\} \;
 
depend: kerninc
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
$(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in
$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
 
%.o: %.S
/branches/arm/uspace/lib/libc/Makefile.toolchain
26,16 → 26,27
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
DEFS = -DARCH=$(ARCH)
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -O3 -nostdlib -nostdinc -I$(LIBC_PREFIX)/include
CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \
-Wmissing-prototypes -Werror-implicit-function-declaration -nostdlib \
-nostdinc -pipe -g -D__$(ENDIANESS)__
LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a
AFLAGS =
#-Werror
 
## Cross-toolchain prefix
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
## Setup platform configuration
#
 
include $(LIBC_PREFIX)/arch/$(ARCH)/Makefile.inc
-include $(LIBC_PREFIX)/../../../Makefile.config
-include $(LIBC_PREFIX)/../../../config.defs
-include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
 
## Simple detection of the host system
#
59,6 → 70,7
AR = $(BINUTILS_PREFIX)ar
OBJCOPY = $(BINUTILS_PREFIX)objcopy
OBJDUMP = $(BINUTILS_PREFIX)objdump
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
ifeq ($(COMPILER),icc_native)
68,6 → 80,7
AR = ar
OBJCOPY = objcopy
OBJDUMP = objdump
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
ifeq ($(COMPILER),gcc_cross)
77,5 → 90,5
AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar
OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
/branches/arm/uspace/lib/libblock/libblock.c
0,0 → 1,604
/*
* Copyright (c) 2008 Jakub Jermar
* Copyright (c) 2008 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libblock
* @{
*/
/**
* @file
* @brief
*/
 
#include "libblock.h"
#include "../../srv/vfs/vfs.h"
#include <ipc/devmap.h>
#include <ipc/bd.h>
#include <ipc/services.h>
#include <errno.h>
#include <sys/mman.h>
#include <async.h>
#include <ipc/ipc.h>
#include <as.h>
#include <assert.h>
#include <fibril_sync.h>
#include <adt/list.h>
#include <adt/hash_table.h>
#include <mem.h>
 
/** Lock protecting the device connection list */
static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
/** Device connection list head. */
static LIST_INITIALIZE(dcl_head);
 
#define CACHE_BUCKETS_LOG2 10
#define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2)
 
typedef struct {
fibril_mutex_t lock;
size_t block_size; /**< Block size. */
unsigned block_count; /**< Total number of blocks. */
unsigned blocks_cached; /**< Number of cached blocks. */
hash_table_t block_hash;
link_t free_head;
enum cache_mode mode;
} cache_t;
 
typedef struct {
link_t link;
dev_handle_t dev_handle;
int dev_phone;
fibril_mutex_t com_area_lock;
void *com_area;
size_t com_size;
void *bb_buf;
off_t bb_off;
size_t bb_size;
cache_t *cache;
} devcon_t;
 
static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
 
static devcon_t *devcon_search(dev_handle_t dev_handle)
{
link_t *cur;
 
fibril_mutex_lock(&dcl_lock);
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
devcon_t *devcon = list_get_instance(cur, devcon_t, link);
if (devcon->dev_handle == dev_handle) {
fibril_mutex_unlock(&dcl_lock);
return devcon;
}
}
fibril_mutex_unlock(&dcl_lock);
return NULL;
}
 
static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,
size_t com_size)
{
link_t *cur;
devcon_t *devcon;
 
devcon = malloc(sizeof(devcon_t));
if (!devcon)
return ENOMEM;
link_initialize(&devcon->link);
devcon->dev_handle = dev_handle;
devcon->dev_phone = dev_phone;
fibril_mutex_initialize(&devcon->com_area_lock);
devcon->com_area = com_area;
devcon->com_size = com_size;
devcon->bb_buf = NULL;
devcon->bb_off = 0;
devcon->bb_size = 0;
devcon->cache = NULL;
 
fibril_mutex_lock(&dcl_lock);
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
devcon_t *d = list_get_instance(cur, devcon_t, link);
if (d->dev_handle == dev_handle) {
fibril_mutex_unlock(&dcl_lock);
free(devcon);
return EEXIST;
}
}
list_append(&devcon->link, &dcl_head);
fibril_mutex_unlock(&dcl_lock);
return EOK;
}
 
static void devcon_remove(devcon_t *devcon)
{
fibril_mutex_lock(&dcl_lock);
list_remove(&devcon->link);
fibril_mutex_unlock(&dcl_lock);
}
 
int block_init(dev_handle_t dev_handle, size_t com_size)
{
int rc;
int dev_phone;
void *com_area;
com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!com_area) {
return ENOMEM;
}
 
dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
if (dev_phone < 0) {
munmap(com_area, com_size);
return dev_phone;
}
 
rc = ipc_share_out_start(dev_phone, com_area,
AS_AREA_READ | AS_AREA_WRITE);
if (rc != EOK) {
munmap(com_area, com_size);
ipc_hangup(dev_phone);
return rc;
}
rc = devcon_add(dev_handle, dev_phone, com_area, com_size);
if (rc != EOK) {
munmap(com_area, com_size);
ipc_hangup(dev_phone);
return rc;
}
 
return EOK;
}
 
void block_fini(dev_handle_t dev_handle)
{
devcon_t *devcon = devcon_search(dev_handle);
assert(devcon);
devcon_remove(devcon);
 
if (devcon->bb_buf)
free(devcon->bb_buf);
 
if (devcon->cache) {
hash_table_destroy(&devcon->cache->block_hash);
free(devcon->cache);
}
 
munmap(devcon->com_area, devcon->com_size);
ipc_hangup(devcon->dev_phone);
 
free(devcon);
}
 
int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)
{
void *bb_buf;
int rc;
 
devcon_t *devcon = devcon_search(dev_handle);
if (!devcon)
return ENOENT;
if (devcon->bb_buf)
return EEXIST;
bb_buf = malloc(size);
if (!bb_buf)
return ENOMEM;
fibril_mutex_lock(&devcon->com_area_lock);
rc = read_block(devcon, 0, size);
if (rc != EOK) {
fibril_mutex_unlock(&devcon->com_area_lock);
free(bb_buf);
return rc;
}
memcpy(bb_buf, devcon->com_area, size);
fibril_mutex_unlock(&devcon->com_area_lock);
 
devcon->bb_buf = bb_buf;
devcon->bb_off = off;
devcon->bb_size = size;
 
return EOK;
}
 
void *block_bb_get(dev_handle_t dev_handle)
{
devcon_t *devcon = devcon_search(dev_handle);
assert(devcon);
return devcon->bb_buf;
}
 
static hash_index_t cache_hash(unsigned long *key)
{
return *key & (CACHE_BUCKETS - 1);
}
 
static int cache_compare(unsigned long *key, hash_count_t keys, link_t *item)
{
block_t *b = hash_table_get_instance(item, block_t, hash_link);
return b->boff == *key;
}
 
static void cache_remove_callback(link_t *item)
{
}
 
static hash_table_operations_t cache_ops = {
.hash = cache_hash,
.compare = cache_compare,
.remove_callback = cache_remove_callback
};
 
int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks,
enum cache_mode mode)
{
devcon_t *devcon = devcon_search(dev_handle);
cache_t *cache;
if (!devcon)
return ENOENT;
if (devcon->cache)
return EEXIST;
cache = malloc(sizeof(cache_t));
if (!cache)
return ENOMEM;
fibril_mutex_initialize(&cache->lock);
list_initialize(&cache->free_head);
cache->block_size = size;
cache->block_count = blocks;
cache->blocks_cached = 0;
cache->mode = mode;
 
if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
&cache_ops)) {
free(cache);
return ENOMEM;
}
 
devcon->cache = cache;
return EOK;
}
 
#define CACHE_LO_WATERMARK 10
#define CACHE_HI_WATERMARK 20
static bool cache_can_grow(cache_t *cache)
{
if (cache->blocks_cached < CACHE_LO_WATERMARK)
return true;
if (!list_empty(&cache->free_head))
return false;
return true;
}
 
static void block_initialize(block_t *b)
{
fibril_mutex_initialize(&b->lock);
b->refcnt = 1;
b->dirty = false;
fibril_rwlock_initialize(&b->contents_lock);
link_initialize(&b->free_link);
link_initialize(&b->hash_link);
}
 
/** Instantiate a block in memory and get a reference to it.
*
* @param dev_handle Device handle of the block device.
* @param boff Block offset.
* @param flags If BLOCK_FLAGS_NOREAD is specified, block_get()
* will not read the contents of the block from the
* device.
*
* @return Block structure.
*/
block_t *block_get(dev_handle_t dev_handle, bn_t boff, int flags)
{
devcon_t *devcon;
cache_t *cache;
block_t *b;
link_t *l;
unsigned long key = boff;
bn_t oboff;
devcon = devcon_search(dev_handle);
 
assert(devcon);
assert(devcon->cache);
cache = devcon->cache;
fibril_mutex_lock(&cache->lock);
l = hash_table_find(&cache->block_hash, &key);
if (l) {
/*
* We found the block in the cache.
*/
b = hash_table_get_instance(l, block_t, hash_link);
fibril_mutex_lock(&b->lock);
if (b->refcnt++ == 0)
list_remove(&b->free_link);
fibril_mutex_unlock(&b->lock);
fibril_mutex_unlock(&cache->lock);
} else {
/*
* The block was not found in the cache.
*/
int rc;
bool sync = false;
 
if (cache_can_grow(cache)) {
/*
* We can grow the cache by allocating new blocks.
* Should the allocation fail, we fail over and try to
* recycle a block from the cache.
*/
b = malloc(sizeof(block_t));
if (!b)
goto recycle;
b->data = malloc(cache->block_size);
if (!b->data) {
free(b);
goto recycle;
}
cache->blocks_cached++;
} else {
/*
* Try to recycle a block from the free list.
*/
unsigned long temp_key;
recycle:
assert(!list_empty(&cache->free_head));
l = cache->free_head.next;
list_remove(l);
b = list_get_instance(l, block_t, free_link);
sync = b->dirty;
oboff = b->boff;
temp_key = b->boff;
hash_table_remove(&cache->block_hash, &temp_key, 1);
}
 
block_initialize(b);
b->dev_handle = dev_handle;
b->size = cache->block_size;
b->boff = boff;
hash_table_insert(&cache->block_hash, &key, &b->hash_link);
 
/*
* Lock the block before releasing the cache lock. Thus we don't
* kill concurent operations on the cache while doing I/O on the
* block.
*/
fibril_mutex_lock(&b->lock);
fibril_mutex_unlock(&cache->lock);
 
if (sync) {
/*
* The block is dirty and needs to be written back to
* the device before we can read in the new contents.
*/
fibril_mutex_lock(&devcon->com_area_lock);
memcpy(devcon->com_area, b->data, b->size);
rc = write_block(devcon, oboff, cache->block_size);
assert(rc == EOK);
fibril_mutex_unlock(&devcon->com_area_lock);
}
if (!(flags & BLOCK_FLAGS_NOREAD)) {
/*
* The block contains old or no data. We need to read
* the new contents from the device.
*/
fibril_mutex_lock(&devcon->com_area_lock);
rc = read_block(devcon, b->boff, cache->block_size);
assert(rc == EOK);
memcpy(b->data, devcon->com_area, cache->block_size);
fibril_mutex_unlock(&devcon->com_area_lock);
}
 
fibril_mutex_unlock(&b->lock);
}
return b;
}
 
/** Release a reference to a block.
*
* If the last reference is dropped, the block is put on the free list.
*
* @param block Block of which a reference is to be released.
*/
void block_put(block_t *block)
{
devcon_t *devcon = devcon_search(block->dev_handle);
cache_t *cache;
int rc;
 
assert(devcon);
assert(devcon->cache);
 
cache = devcon->cache;
fibril_mutex_lock(&cache->lock);
fibril_mutex_lock(&block->lock);
if (!--block->refcnt) {
/*
* Last reference to the block was dropped. Either free the
* block or put it on the free list.
*/
if (cache->blocks_cached > CACHE_HI_WATERMARK) {
/*
* Currently there are too many cached blocks.
*/
if (block->dirty) {
fibril_mutex_lock(&devcon->com_area_lock);
memcpy(devcon->com_area, block->data,
block->size);
rc = write_block(devcon, block->boff,
block->size);
assert(rc == EOK);
fibril_mutex_unlock(&devcon->com_area_lock);
}
/*
* Take the block out of the cache and free it.
*/
unsigned long key = block->boff;
hash_table_remove(&cache->block_hash, &key, 1);
free(block);
free(block->data);
cache->blocks_cached--;
fibril_mutex_unlock(&cache->lock);
return;
}
/*
* Put the block on the free list.
*/
list_append(&block->free_link, &cache->free_head);
if (cache->mode != CACHE_MODE_WB && block->dirty) {
fibril_mutex_lock(&devcon->com_area_lock);
memcpy(devcon->com_area, block->data, block->size);
rc = write_block(devcon, block->boff, block->size);
assert(rc == EOK);
fibril_mutex_unlock(&devcon->com_area_lock);
 
block->dirty = false;
}
}
fibril_mutex_unlock(&block->lock);
fibril_mutex_unlock(&cache->lock);
}
 
/** Read sequential data from a block device.
*
* @param dev_handle Device handle of the block device.
* @param bufpos Pointer to the first unread valid offset within the
* communication buffer.
* @param buflen Pointer to the number of unread bytes that are ready in
* the communication buffer.
* @param pos Device position to be read.
* @param dst Destination buffer.
* @param size Size of the destination buffer.
* @param block_size Block size to be used for the transfer.
*
* @return EOK on success or a negative return code on failure.
*/
int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
off_t *pos, void *dst, size_t size, size_t block_size)
{
off_t offset = 0;
size_t left = size;
devcon_t *devcon = devcon_search(dev_handle);
assert(devcon);
fibril_mutex_lock(&devcon->com_area_lock);
while (left > 0) {
size_t rd;
if (*bufpos + left < *buflen)
rd = left;
else
rd = *buflen - *bufpos;
if (rd > 0) {
/*
* Copy the contents of the communication buffer to the
* destination buffer.
*/
memcpy(dst + offset, devcon->com_area + *bufpos, rd);
offset += rd;
*bufpos += rd;
*pos += rd;
left -= rd;
}
if (*bufpos == (off_t) *buflen) {
/* Refill the communication buffer with a new block. */
int rc;
 
rc = read_block(devcon, *pos / block_size, block_size);
if (rc != EOK) {
fibril_mutex_unlock(&devcon->com_area_lock);
return rc;
}
*bufpos = 0;
*buflen = block_size;
}
}
fibril_mutex_unlock(&devcon->com_area_lock);
return EOK;
}
 
/** Read block from block device.
*
* @param devcon Device connection.
* @param boff Block index.
* @param block_size Block size.
* @param src Buffer for storing the data.
*
* @return EOK on success or negative error code on failure.
*/
static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
{
ipcarg_t retval;
int rc;
 
assert(devcon);
rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
&retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : (int) retval);
 
return EOK;
}
 
/** Write block to block device.
*
* @param devcon Device connection.
* @param boff Block index.
* @param block_size Block size.
* @param src Buffer containing the data to write.
*
* @return EOK on success or negative error code on failure.
*/
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
{
ipcarg_t retval;
int rc;
 
assert(devcon);
rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
&retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : (int) retval);
 
return EOK;
}
 
/** @}
*/
/branches/arm/uspace/lib/libblock/libblock.h
0,0 → 1,113
/*
* Copyright (c) 2008 Jakub Jermar
* Copyright (c) 2008 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libblock
* @{
*/
/**
* @file
*/
 
#ifndef LIBBLOCK_LIBBLOCK_H_
#define LIBBLOCK_LIBBLOCK_H_
 
#include <stdint.h>
#include "../../srv/vfs/vfs.h"
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <adt/list.h>
 
/*
* Flags that can be used with block_get().
*/
 
/**
* This macro is a symbolic value for situations where no special flags are
* needed.
*/
#define BLOCK_FLAGS_NONE 0
 
/**
* When the client of block_get() intends to overwrite the current contents of
* the block, this flag is used to avoid the unnecessary read.
*/
#define BLOCK_FLAGS_NOREAD 1
 
typedef unsigned bn_t; /**< Block number type. */
 
typedef struct block {
/** Mutex protecting the reference count. */
fibril_mutex_t lock;
/** Number of references to the block_t structure. */
unsigned refcnt;
/** If true, the block needs to be written back to the block device. */
bool dirty;
/** Readers / Writer lock protecting the contents of the block. */
fibril_rwlock_t contents_lock;
/** Handle of the device where the block resides. */
dev_handle_t dev_handle;
/** Block offset on the block device. Counted in 'size'-byte blocks. */
bn_t boff;
/** Size of the block. */
size_t size;
/** Link for placing the block into the free block list. */
link_t free_link;
/** Link for placing the block into the block hash table. */
link_t hash_link;
/** Buffer with the block data. */
void *data;
} block_t;
 
/** Caching mode */
enum cache_mode {
/** Write-Through */
CACHE_MODE_WT,
/** Write-Back */
CACHE_MODE_WB
};
 
extern int block_init(dev_handle_t, size_t);
extern void block_fini(dev_handle_t);
 
extern int block_bb_read(dev_handle_t, off_t, size_t);
extern void *block_bb_get(dev_handle_t);
 
extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
 
extern block_t *block_get(dev_handle_t, bn_t, int);
extern void block_put(block_t *);
 
extern int block_seqread(dev_handle_t, off_t *, size_t *, off_t *, void *,
size_t, size_t);
 
#endif
 
/** @}
*/
 
/branches/arm/uspace/lib/libblock/Makefile
0,0 → 1,67
#
# Copyright (c) 2005 Martin Decky
# Copyright (c) 2007 Jakub Jermar
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Common compiler flags
#
 
LIBC_PREFIX = ../libc
 
## Setup toolchain
#
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -Iinclude
 
## Sources
#
 
SOURCES = \
libblock.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend
 
all: libblock.a
 
-include Makefile.depend
 
clean:
-rm -f libblock.a Makefile.depend
find . -name '*.o' -follow -exec rm \{\} \;
 
depend:
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
libblock.a: depend $(OBJECTS)
$(AR) rc libblock.a $(OBJECTS)
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/lib/libfs/libfs.c
1,5 → 1,5
/*
* Copyright (c) 2008 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
36,7 → 36,6
 
#include "libfs.h"
#include "../../srv/vfs/vfs.h"
#include "../../srv/rd/rd.h"
#include <errno.h>
#include <async.h>
#include <ipc/ipc.h>
43,6 → 42,8
#include <as.h>
#include <assert.h>
#include <dirent.h>
#include <mem.h>
#include <sys/stat.h>
 
/** Register file system server.
*
69,7 → 70,7
* out-of-order, when it knows that the operation succeeded or failed.
*/
ipc_call_t answer;
aid_t req = async_send_0(vfs_phone, VFS_REGISTER, &answer);
aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
 
/*
* Send our VFS info structure to VFS.
104,7 → 105,7
}
/*
* Pick up the answer for the request to the VFS_REQUEST call.
* Pick up the answer for the request to the VFS_IN_REQUEST call.
*/
async_wait_for(req, NULL);
reg->fs_handle = (int) IPC_GET_ARG1(answer);
123,23 → 124,106
return IPC_GET_RETVAL(answer);
}
 
void fs_node_initialize(fs_node_t *fn)
{
memset(fn, 0, sizeof(fs_node_t));
}
 
void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request);
int res;
ipcarg_t rc;
 
ipc_call_t call;
ipc_callid_t callid;
 
/* accept the phone */
callid = async_get_call(&call);
int mountee_phone = (int)IPC_GET_ARG1(call);
if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
mountee_phone < 0) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
ipc_answer_0(callid, EOK); /* acknowledge the mountee_phone */
res = ipc_data_write_receive(&callid, NULL);
if (!res) {
ipc_hangup(mountee_phone);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index);
if (!fn) {
ipc_hangup(mountee_phone);
ipc_answer_0(callid, ENOENT);
ipc_answer_0(rid, ENOENT);
return;
}
 
if (fn->mp_data.mp_active) {
ipc_hangup(mountee_phone);
ops->node_put(fn);
ipc_answer_0(callid, EBUSY);
ipc_answer_0(rid, EBUSY);
return;
}
 
rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
if (rc != 0) {
ipc_hangup(mountee_phone);
ops->node_put(fn);
ipc_answer_0(callid, rc);
ipc_answer_0(rid, rc);
return;
}
ipc_call_t answer;
aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
&answer);
ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
if (rc == EOK) {
fn->mp_data.mp_active = true;
fn->mp_data.fs_handle = mr_fs_handle;
fn->mp_data.dev_handle = mr_dev_handle;
fn->mp_data.phone = mountee_phone;
}
/*
* Do not release the FS node so that it stays in memory.
*/
ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
IPC_GET_ARG3(answer));
}
 
/** Lookup VFS triplet by name in the file system name space.
*
* The path passed in the PLB must be in the canonical file system path format
* as returned by the canonify() function.
*
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param fs_handle File system handle of the file system where to perform
* the lookup.
* @param rid Request ID of the VFS_LOOKUP request.
* @param request VFS_LOOKUP request data itself.
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param fs_handle File system handle of the file system where to perform
* the lookup.
* @param rid Request ID of the VFS_OUT_LOOKUP request.
* @param request VFS_OUT_LOOKUP request data itself.
*
*/
void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
unsigned next = IPC_GET_ARG1(*request);
unsigned first = IPC_GET_ARG1(*request);
unsigned last = IPC_GET_ARG2(*request);
unsigned next = first;
dev_handle_t dev_handle = IPC_GET_ARG3(*request);
int lflag = IPC_GET_ARG4(*request);
fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
149,10 → 233,18
if (last < next)
last += PLB_SIZE;
 
void *par = NULL;
void *cur = ops->root_get(dev_handle);
void *tmp = NULL;
fs_node_t *par = NULL;
fs_node_t *cur = ops->root_get(dev_handle);
fs_node_t *tmp = NULL;
 
if (cur->mp_data.mp_active) {
ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
next, last, cur->mp_data.dev_handle, lflag, index,
IPC_FF_ROUTE_FROM_ME);
ops->node_put(cur);
return;
}
 
if (ops->plb_get_char(next) == '/')
next++; /* eat slash */
175,6 → 267,21
 
/* match the component */
tmp = ops->match(cur, component);
if (tmp && tmp->mp_data.mp_active) {
if (next > last)
next = last = first;
else
next--;
ipc_forward_slow(rid, tmp->mp_data.phone,
VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
lflag, index, IPC_FF_ROUTE_FROM_ME);
ops->node_put(cur);
ops->node_put(tmp);
if (par)
ops->node_put(par);
return;
}
 
/* handle miss: match amongst siblings */
if (!tmp) {
190,36 → 297,33
ipc_answer_0(rid, ENOTDIR);
goto out;
}
void *nodep;
fs_node_t *fn;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
fn = ops->create(dev_handle, lflag);
else
nodep = ops->node_get(dev_handle,
fn = ops->node_get(dev_handle,
index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
if (fn) {
int rc;
 
rc = ops->link(cur, fn, component);
if (rc != EOK) {
if (lflag & L_CREATE) {
(void)ops->destroy(
nodep);
(void)ops->destroy(fn);
}
ipc_answer_0(rid, ENOSPC);
ipc_answer_0(rid, rc);
} else {
ipc_answer_5(rid, EOK,
fs_handle, dev_handle,
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
ops->index_get(fn),
ops->size_get(fn),
ops->lnkcnt_get(fn));
ops->node_put(fn);
}
} else {
ipc_answer_0(rid, ENOSPC);
}
goto out;
} else if (lflag & L_PARENT) {
/* return parent */
ipc_answer_5(rid, EOK, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur),
ops->lnkcnt_get(cur));
}
ipc_answer_0(rid, ENOENT);
goto out;
261,23 → 365,26
assert(len);
component[len] = '\0';
void *nodep;
fs_node_t *fn;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
fn = ops->create(dev_handle, lflag);
else
nodep = ops->node_get(dev_handle, index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
fn = ops->node_get(dev_handle, index);
if (fn) {
int rc;
 
rc = ops->link(cur, fn, component);
if (rc != EOK) {
if (lflag & L_CREATE)
(void)ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
(void)ops->destroy(fn);
ipc_answer_0(rid, rc);
} else {
ipc_answer_5(rid, EOK,
fs_handle, dev_handle,
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
ops->index_get(fn),
ops->size_get(fn),
ops->lnkcnt_get(fn));
ops->node_put(fn);
}
} else {
ipc_answer_0(rid, ENOSPC);
289,18 → 396,9
}
 
/* handle hit */
if (lflag & L_PARENT) {
ops->node_put(cur);
cur = par;
par = NULL;
if (!cur) {
ipc_answer_0(rid, ENOENT);
goto out;
}
}
if (lflag & L_UNLINK) {
unsigned old_lnkcnt = ops->lnkcnt_get(cur);
int res = ops->unlink(par, cur);
int res = ops->unlink(par, cur, component);
ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
goto out;
331,61 → 429,61
ops->node_put(tmp);
}
 
/** Read data from a block device.
void libfs_stat(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
fs_node_t *fn = ops->node_get(dev_handle, index);
 
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size) ||
size != sizeof(struct stat)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
struct stat stat;
memset(&stat, 0, sizeof(struct stat));
stat.fs_handle = fs_handle;
stat.dev_handle = dev_handle;
stat.index = index;
stat.lnkcnt = ops->lnkcnt_get(fn);
stat.is_file = ops->is_file(fn);
stat.size = ops->size_get(fn);
 
ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
ipc_answer_0(rid, EOK);
}
 
/** Open VFS triplet.
*
* @param phone Phone to be used to communicate with the device.
* @param buffer Communication buffer shared with the device.
* @param bufpos Pointer to the first unread valid offset within the
* communication buffer.
* @param buflen Pointer to the number of unread bytes that are ready in
* the communication buffer.
* @param pos Device position to be read.
* @param dst Destination buffer.
* @param size Size of the destination buffer.
* @param block_size Block size to be used for the transfer.
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param rid Request ID of the VFS_OUT_OPEN_NODE request.
* @param request VFS_OUT_OPEN_NODE request data itself.
*
* @return True on success, false on failure.
*/
bool libfs_blockread(int phone, void *buffer, off_t *bufpos, size_t *buflen,
off_t *pos, void *dst, size_t size, size_t block_size)
void libfs_open_node(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
off_t offset = 0;
size_t left = size;
dev_handle_t dev_handle = IPC_GET_ARG1(*request);
fs_index_t index = IPC_GET_ARG2(*request);
while (left > 0) {
size_t rd;
if (*bufpos + left < *buflen)
rd = left;
else
rd = *buflen - *bufpos;
if (rd > 0) {
/*
* Copy the contents of the communication buffer to the
* destination buffer.
*/
memcpy(dst + offset, buffer + *bufpos, rd);
offset += rd;
*bufpos += rd;
*pos += rd;
left -= rd;
}
if (*bufpos == *buflen) {
/* Refill the communication buffer with a new block. */
ipcarg_t retval;
int rc = async_req_2_1(phone, RD_READ_BLOCK,
*pos / block_size, block_size, &retval);
if ((rc != EOK) || (retval != EOK))
return false;
*bufpos = 0;
*buflen = block_size;
}
fs_node_t *node = ops->node_get(dev_handle, index);
if (node == NULL) {
ipc_answer_0(rid, ENOENT);
return;
}
return true;
ipc_answer_5(rid, EOK, fs_handle, dev_handle, index,
ops->size_get(node), ops->lnkcnt_get(node));
ops->node_put(node);
}
 
/** @}
/branches/arm/uspace/lib/libfs/libfs.h
1,5 → 1,5
/*
* Copyright (c) 2007 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,54 → 26,69
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libfs
/** @addtogroup libfs
* @{
*/
*/
/**
* @file
*/
 
#ifndef LIBFS_LIBFS_H_
#define LIBFS_LIBFS_H_
#define LIBFS_LIBFS_H_
 
#include "../../srv/vfs/vfs.h"
#include <ipc/vfs.h>
#include <stdint.h>
#include <ipc/ipc.h>
#include <async.h>
#include <devmap.h>
 
typedef struct {
void * (* match)(void *, const char *);
void * (* node_get)(dev_handle_t, fs_index_t);
void (* node_put)(void *);
void * (* create)(int);
int (* destroy)(void *);
bool (* link)(void *, void *, const char *);
int (* unlink)(void *, void *);
fs_index_t (* index_get)(void *);
size_t (* size_get)(void *);
unsigned (* lnkcnt_get)(void *);
bool (* has_children)(void *);
void *(* root_get)(dev_handle_t);
char (* plb_get_char)(unsigned pos);
bool (* is_directory)(void *);
bool (* is_file)(void *);
bool mp_active;
int phone;
fs_handle_t fs_handle;
dev_handle_t dev_handle;
} mp_data_t;
 
typedef struct {
mp_data_t mp_data; /**< Mount point info. */
void *data; /**< Data of the file system implementation. */
} fs_node_t;
 
typedef struct {
fs_node_t * (* match)(fs_node_t *, const char *);
fs_node_t * (* node_get)(dev_handle_t, fs_index_t);
void (* node_put)(fs_node_t *);
fs_node_t * (* create)(dev_handle_t, int);
int (* destroy)(fs_node_t *);
int (* link)(fs_node_t *, fs_node_t *, const char *);
int (* unlink)(fs_node_t *, fs_node_t *, const char *);
fs_index_t (* index_get)(fs_node_t *);
size_t (* size_get)(fs_node_t *);
unsigned (* lnkcnt_get)(fs_node_t *);
bool (* has_children)(fs_node_t *);
fs_node_t *(* root_get)(dev_handle_t);
char (* plb_get_char)(unsigned pos);
bool (* is_directory)(fs_node_t *);
bool (* is_file)(fs_node_t *);
} libfs_ops_t;
 
typedef struct {
int fs_handle; /**< File system handle. */
ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */
uint8_t *plb_ro; /**< Read-only PLB view. */
int fs_handle; /**< File system handle. */
ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */
uint8_t *plb_ro; /**< Read-only PLB view. */
} fs_reg_t;
 
extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t);
 
extern void fs_node_initialize(fs_node_t *);
 
extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
ipc_call_t *);
 
extern bool libfs_blockread(int, void *, off_t *, size_t *, off_t *, void *,
size_t, size_t);
 
#endif
 
/** @}
*/
 
/branches/arm/uspace/lib/libfs/Makefile
31,6 → 31,7
#
 
LIBC_PREFIX = ../libc
 
## Setup toolchain
#
 
57,7 → 58,7
find . -name '*.o' -follow -exec rm \{\} \;
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
libfs.a: depend $(OBJECTS)
$(AR) rc libfs.a $(OBJECTS)
/branches/arm/uspace/lib/softfloat/include/sftypes.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup softfloat
/** @addtogroup softfloat
* @{
*/
/** @file
41,40 → 41,40
typedef union {
float f;
uint32_t binary;
 
struct {
#if defined(ARCH_IS_BIG_ENDIAN)
uint32_t sign:1;
uint32_t exp:8;
uint32_t fraction:23;
#elif defined(ARCH_IS_LITTLE_ENDIAN)
uint32_t fraction:23;
uint32_t exp:8;
uint32_t sign:1;
#else
#error "Unknown endians."
struct {
#if defined(__BE__)
uint32_t sign : 1;
uint32_t exp : 8;
uint32_t fraction : 23;
#elif defined(__LE__)
uint32_t fraction : 23;
uint32_t exp : 8;
uint32_t sign : 1;
#else
#error Unknown endianess
#endif
} parts __attribute__ ((packed));
} float32;
} float32;
 
typedef union {
double d;
uint64_t binary;
struct {
#if defined(ARCH_IS_BIG_ENDIAN)
uint64_t sign:1;
uint64_t exp:11;
uint64_t fraction:52;
#elif defined(ARCH_IS_LITTLE_ENDIAN)
uint64_t fraction:52;
uint64_t exp:11;
uint64_t sign:1;
#else
#error "Unknown endians."
struct {
#if defined(__BE__)
uint64_t sign : 1;
uint64_t exp : 11;
uint64_t fraction : 52;
#elif defined(__LE__)
uint64_t fraction : 52;
uint64_t exp : 11;
uint64_t sign : 1;
#else
#error Unknown endianess
#endif
} parts __attribute__ ((packed));
} float64;
} parts __attribute__ ((packed));
} float64;
 
#define FLOAT32_MAX 0x7f800000
#define FLOAT32_MIN 0xff800000
109,7 → 109,5
 
#endif
 
 
/** @}
/** @}
*/
 
/branches/arm/uspace/lib/softfloat/Makefile
30,25 → 30,26
#
 
LIBC_PREFIX = ../libc
 
## Setup toolchain
#
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS +=-Iinclude -Iarch/$(ARCH)/include/
CFLAGS += -Iinclude -Iarch/$(UARCH)/include/
 
## Sources
#
 
GENERIC_SOURCES = \
generic/add.c \
generic/common.c \
generic/comparison.c \
generic/conversion.c \
generic/div.c \
generic/mul.c \
generic/other.c \
generic/softfloat.c \
GENERIC_SOURCES = \
generic/add.c \
generic/common.c \
generic/comparison.c \
generic/conversion.c \
generic/div.c \
generic/mul.c \
generic/other.c \
generic/softfloat.c \
generic/sub.c
 
ARCH_SOURCES =
66,7 → 67,7
find generic/ -name '*.o' -follow -exec rm \{\} \;
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
$(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
/branches/arm/uspace/lib/softfloat/arch/ppc64/include/functions.h
File deleted
/branches/arm/uspace/lib/softint/Makefile
30,6 → 30,7
#
 
LIBC_PREFIX = ../libc
 
## Setup toolchain
#
 
58,7 → 59,7
find generic/ -name '*.o' -follow -exec rm \{\} \;
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEPEMD_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
libsoftint.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
$(AR) rc libsoftint.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
/branches/arm/uspace/srv/rd/rd.h
File deleted
/branches/arm/uspace/srv/rd/Makefile
File deleted
/branches/arm/uspace/srv/rd/rd.c
File deleted
/branches/arm/uspace/srv/console/nameic.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/anim_4.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/anim_3.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/anim_2.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/anim_1.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/helenos.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/cons_selected.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/cons_idle.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/cons_kernel.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/cons_has_data.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/console.c
27,7 → 27,7
*/
 
/** @addtogroup console
* @{
* @{
*/
/** @file
*/
35,327 → 35,388
#include <libc.h>
#include <fb.h>
#include <ipc/ipc.h>
#include <keys.h>
#include <kbd.h>
#include <io/keycode.h>
#include <ipc/fb.h>
#include <ipc/services.h>
#include <errno.h>
#include <key_buffer.h>
#include <console.h>
#include <keybuffer.h>
#include <ipc/console.h>
#include <unistd.h>
#include <async.h>
#include <libadt/fifo.h>
#include <screenbuffer.h>
#include <adt/fifo.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <sysinfo.h>
#include <event.h>
#include <devmap.h>
#include <fibril_sync.h>
 
#include "console.h"
#include "gcons.h"
#include "screenbuffer.h"
 
#define MAX_KEYREQUESTS_BUFFERED 32
#define NAME "console"
 
#define NAME "console"
#define MAX_DEVICE_NAME 32
 
/** Index of currently used virtual console.
*/
int active_console = 0;
/** Phone to the keyboard driver. */
static int kbd_phone;
 
/** Information about framebuffer
*/
/** Information about framebuffer */
struct {
int phone; /**< Framebuffer phone */
ipcarg_t rows; /**< Framebuffer rows */
ipcarg_t cols; /**< Framebuffer columns */
int phone; /**< Framebuffer phone */
ipcarg_t cols; /**< Framebuffer columns */
ipcarg_t rows; /**< Framebuffer rows */
int color_cap; /**< Color capabilities (FB_CCAP_xxx) */
} fb_info;
 
typedef struct {
keybuffer_t keybuffer; /**< Buffer for incoming keys. */
/** Buffer for unsatisfied request for keys. */
FIFO_CREATE_STATIC(keyrequests, ipc_callid_t,
MAX_KEYREQUESTS_BUFFERED);
int keyrequest_counter; /**< Number of requests in buffer. */
int client_phone; /**< Phone to connected client. */
int used; /**< 1 if this virtual console is
* connected to some client.*/
screenbuffer_t screenbuffer; /**< Screenbuffer for saving screen
* contents and related settings. */
} connection_t;
size_t index; /**< Console index */
size_t refcount; /**< Connection reference count */
dev_handle_t dev_handle; /**< Device handle */
keybuffer_t keybuffer; /**< Buffer for incoming keys. */
screenbuffer_t scr; /**< Screenbuffer for saving screen
contents and related settings. */
} console_t;
 
static connection_t connections[CONSOLE_COUNT]; /**< Array of data for virtual
* consoles */
static keyfield_t *interbuffer = NULL; /**< Pointer to memory shared
* with framebufer used for
* faster virtual console
* switching */
/** Array of data for virtual consoles */
static console_t consoles[CONSOLE_COUNT];
 
static int kernel_pixmap = -1; /**< Number of fb pixmap, where kernel
* console is stored */
static console_t *active_console = &consoles[0];
static console_t *prev_console = &consoles[0];
static console_t *kernel_console = &consoles[KERNEL_CONSOLE];
 
/** Pointer to memory shared with framebufer used for
faster virtual console switching */
static keyfield_t *interbuffer = NULL;
 
/** Find unused virtual console.
*
*/
static int find_free_connection(void)
/** Information on row-span yet unsent to FB driver. */
struct {
size_t col; /**< Leftmost column of the span. */
size_t row; /**< Row where the span lies. */
size_t cnt; /**< Width of the span. */
} fb_pending;
 
static FIBRIL_MUTEX_INITIALIZE(input_mutex);
static FIBRIL_CONDVAR_INITIALIZE(input_cv);
 
static void curs_visibility(bool visible)
{
int i;
for (i = 0; i < CONSOLE_COUNT; i++) {
if (!connections[i].used)
return i;
}
return -1;
async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);
}
 
static void clrscr(void)
static void curs_hide_sync(void)
{
ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);
}
 
static void curs_goto(size_t x, size_t y)
{
async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
}
 
static void screen_clear(void)
{
async_msg_0(fb_info.phone, FB_CLEAR);
}
 
static void curs_visibility(int v)
static void screen_yield(void)
{
async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, v);
ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD);
}
 
static void curs_goto(int row, int col)
static void screen_reclaim(void)
{
async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM);
}
 
static void set_style(style_t *style)
static void kbd_yield(void)
{
async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color,
style->bg_color);
ipc_call_sync_0_0(kbd_phone, KBD_YIELD);
}
 
static void set_style_col(int fgcolor, int bgcolor)
static void kbd_reclaim(void)
{
async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor);
ipc_call_sync_0_0(kbd_phone, KBD_RECLAIM);
}
 
static void prtchr(char c, int row, int col)
static void set_style(int style)
{
async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
async_msg_1(fb_info.phone, FB_SET_STYLE, style);
}
 
/** Check key and process special keys.
static void set_color(int fgcolor, int bgcolor, int flags)
{
async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);
}
 
static void set_rgb_color(int fgcolor, int bgcolor)
{
async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
}
 
static void set_attrs(attrs_t *attrs)
{
switch (attrs->t) {
case at_style:
set_style(attrs->a.s.style);
break;
case at_idx:
set_color(attrs->a.i.fg_color, attrs->a.i.bg_color,
attrs->a.i.flags);
break;
case at_rgb:
set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color);
break;
}
}
 
int ccap_fb_to_con(int ccap_fb, int *ccap_con)
{
switch (ccap_fb) {
case FB_CCAP_NONE: *ccap_con = CONSOLE_CCAP_NONE; break;
case FB_CCAP_STYLE: *ccap_con = CONSOLE_CCAP_STYLE; break;
case FB_CCAP_INDEXED: *ccap_con = CONSOLE_CCAP_INDEXED; break;
case FB_CCAP_RGB: *ccap_con = CONSOLE_CCAP_RGB; break;
default: return EINVAL;
}
 
return EOK;
}
 
/** Send an area of screenbuffer to the FB driver. */
static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
{
if (interbuffer) {
ipcarg_t x;
ipcarg_t y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
interbuffer[y * width + x] =
*get_field_at(&cons->scr, x0 + x, y0 + y);
}
}
async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
x0, y0, width, height);
}
}
 
/** Flush pending cells to FB. */
static void fb_pending_flush(void)
{
if (fb_pending.cnt > 0) {
fb_update_area(active_console, fb_pending.col,
fb_pending.row, fb_pending.cnt, 1);
fb_pending.cnt = 0;
}
}
 
/** Mark a character cell as changed.
*
* This adds the cell to the pending rowspan if possible. Otherwise
* the old span is flushed first.
*
*/
static void write_char(int console, char key)
static void cell_mark_changed(size_t col, size_t row)
{
screenbuffer_t *scr = &(connections[console].screenbuffer);
if (fb_pending.cnt != 0) {
if ((col != fb_pending.col + fb_pending.cnt)
|| (row != fb_pending.row)) {
fb_pending_flush();
}
}
switch (key) {
if (fb_pending.cnt == 0) {
fb_pending.col = col;
fb_pending.row = row;
}
fb_pending.cnt++;
}
 
/** Print a character to the active VC with buffering. */
static void fb_putchar(wchar_t c, ipcarg_t col, ipcarg_t row)
{
async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
}
 
/** Process a character from the client (TTY emulation). */
static void write_char(console_t *cons, wchar_t ch)
{
bool flush_cursor = false;
 
switch (ch) {
case '\n':
scr->position_y++;
scr->position_x = 0;
fb_pending_flush();
flush_cursor = true;
cons->scr.position_y++;
cons->scr.position_x = 0;
break;
case '\r':
break;
case '\t':
scr->position_x += 8;
scr->position_x -= scr->position_x % 8;
cons->scr.position_x += 8;
cons->scr.position_x -= cons->scr.position_x % 8;
break;
case '\b':
if (scr->position_x == 0)
if (cons->scr.position_x == 0)
break;
scr->position_x--;
if (console == active_console)
prtchr(' ', scr->position_y, scr->position_x);
screenbuffer_putchar(scr, ' ');
cons->scr.position_x--;
if (cons == active_console)
cell_mark_changed(cons->scr.position_x, cons->scr.position_y);
screenbuffer_putchar(&cons->scr, ' ');
break;
default:
if (console == active_console)
prtchr(key, scr->position_y, scr->position_x);
 
screenbuffer_putchar(scr, key);
scr->position_x++;
default:
if (cons == active_console)
cell_mark_changed(cons->scr.position_x, cons->scr.position_y);
screenbuffer_putchar(&cons->scr, ch);
cons->scr.position_x++;
}
scr->position_y += (scr->position_x >= scr->size_x);
if (cons->scr.position_x >= cons->scr.size_x) {
flush_cursor = true;
cons->scr.position_y++;
}
if (scr->position_y >= scr->size_y) {
scr->position_y = scr->size_y - 1;
screenbuffer_clear_line(scr, scr->top_line);
scr->top_line = (scr->top_line + 1) % scr->size_y;
if (console == active_console)
if (cons->scr.position_y >= cons->scr.size_y) {
fb_pending_flush();
cons->scr.position_y = cons->scr.size_y - 1;
screenbuffer_clear_line(&cons->scr, cons->scr.top_line);
cons->scr.top_line = (cons->scr.top_line + 1) % cons->scr.size_y;
if (cons == active_console)
async_msg_1(fb_info.phone, FB_SCROLL, 1);
}
scr->position_x = scr->position_x % scr->size_x;
if (console == active_console)
curs_goto(scr->position_y, scr->position_x);
}
 
/** Save current screen to pixmap, draw old pixmap
*
* @param oldpixmap Old pixmap
* @return ID of pixmap of current screen
*/
static int switch_screens(int oldpixmap)
{
int newpmap;
/* Save screen */
newpmap = async_req_0_0(fb_info.phone, FB_VP2PIXMAP);
if (newpmap < 0)
return -1;
 
if (oldpixmap != -1) {
/* Show old screen */
async_msg_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);
/* Drop old pixmap */
async_msg_1(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
}
return newpmap;
if (cons == active_console && flush_cursor)
curs_goto(cons->scr.position_x, cons->scr.position_y);
cons->scr.position_x = cons->scr.position_x % cons->scr.size_x;
}
 
/** Switch to new console */
static void change_console(int newcons)
static void change_console(console_t *cons)
{
connection_t *conn;
static int console_pixmap = -1;
int i, j, rc;
keyfield_t *field;
style_t *style;
 
if (newcons == active_console)
if (cons == active_console)
return;
 
if (newcons == KERNEL_CONSOLE) {
if (active_console == KERNEL_CONSOLE)
return;
active_console = KERNEL_CONSOLE;
curs_visibility(0);
 
fb_pending_flush();
if (cons == kernel_console) {
async_serialize_start();
if (kernel_pixmap == -1) {
/* store/restore unsupported */
set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
clrscr();
} else {
gcons_in_kernel();
console_pixmap = switch_screens(kernel_pixmap);
kernel_pixmap = -1;
}
curs_hide_sync();
gcons_in_kernel();
screen_yield();
kbd_yield();
async_serialize_end();
 
__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
return;
}
async_serialize_start();
 
if (console_pixmap != -1) {
kernel_pixmap = switch_screens(console_pixmap);
console_pixmap = -1;
if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
prev_console = active_console;
active_console = kernel_console;
} else
cons = active_console;
}
active_console = newcons;
gcons_change_console(newcons);
conn = &connections[active_console];
 
set_style(&conn->screenbuffer.style);
curs_visibility(0);
if (interbuffer) {
for (i = 0; i < conn->screenbuffer.size_x; i++)
for (j = 0; j < conn->screenbuffer.size_y; j++) {
unsigned int size_x;
 
size_x = conn->screenbuffer.size_x;
interbuffer[i + j * size_x] =
*get_field_at(&conn->screenbuffer, i, j);
}
/* This call can preempt, but we are already at the end */
rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA);
}
if ((!interbuffer) || (rc != 0)) {
set_style(&conn->screenbuffer.style);
clrscr();
style = &conn->screenbuffer.style;
 
for (j = 0; j < conn->screenbuffer.size_y; j++)
for (i = 0; i < conn->screenbuffer.size_x; i++) {
field = get_field_at(&conn->screenbuffer, i, j);
if (!style_same(*style, field->style))
set_style(&field->style);
style = &field->style;
if ((field->character == ' ') &&
(style_same(field->style,
conn->screenbuffer.style)))
continue;
 
prtchr(field->character, j, i);
if (cons != kernel_console) {
size_t x;
size_t y;
int rc = 0;
async_serialize_start();
if (active_console == kernel_console) {
screen_reclaim();
kbd_reclaim();
gcons_redraw_console();
}
active_console = cons;
gcons_change_console(cons->index);
set_attrs(&cons->scr.attrs);
curs_visibility(false);
if (interbuffer) {
for (y = 0; y < cons->scr.size_y; y++) {
for (x = 0; x < cons->scr.size_x; x++) {
interbuffer[y * cons->scr.size_x + x] =
*get_field_at(&cons->scr, x, y);
}
}
/* This call can preempt, but we are already at the end */
rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
0, 0, cons->scr.size_x,
cons->scr.size_y);
}
if ((!interbuffer) || (rc != 0)) {
set_attrs(&cons->scr.attrs);
screen_clear();
for (y = 0; y < cons->scr.size_y; y++)
for (x = 0; x < cons->scr.size_x; x++) {
keyfield_t *field = get_field_at(&cons->scr, x, y);
if (!attrs_same(cons->scr.attrs, field->attrs))
set_attrs(&field->attrs);
cons->scr.attrs = field->attrs;
if ((field->character == ' ') &&
(attrs_same(field->attrs, cons->scr.attrs)))
continue;
fb_putchar(field->character, x, y);
}
}
curs_goto(cons->scr.position_x, cons->scr.position_y);
curs_visibility(cons->scr.is_cursor_visible);
async_serialize_end();
}
curs_goto(conn->screenbuffer.position_y,
conn->screenbuffer.position_x);
curs_visibility(conn->screenbuffer.is_cursor_visible);
 
async_serialize_end();
}
 
/** Handler for keyboard */
static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
int retval;
int c;
connection_t *conn;
int newcon;
/* Ignore parameters, the connection is alread opened */
while (1) {
callid = async_get_call(&call);
/* Ignore parameters, the connection is already opened */
while (true) {
ipc_call_t call;
ipc_callid_t callid = async_get_call(&call);
int retval;
console_event_t ev;
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
/* TODO: Handle hangup */
return;
case KBD_MS_LEFT:
newcon = gcons_mouse_btn(IPC_GET_ARG1(call));
if (newcon != -1)
change_console(newcon);
case KBD_EVENT:
/* Got event from keyboard driver. */
retval = 0;
break;
case KBD_MS_MOVE:
gcons_mouse_move(IPC_GET_ARG1(call),
IPC_GET_ARG2(call));
retval = 0;
break;
case KBD_PUSHCHAR:
/* got key from keyboard driver */
ev.type = IPC_GET_ARG1(call);
ev.key = IPC_GET_ARG2(call);
ev.mods = IPC_GET_ARG3(call);
ev.c = IPC_GET_ARG4(call);
retval = 0;
c = IPC_GET_ARG1(call);
/* switch to another virtual console */
conn = &connections[active_console];
/*
* if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 +
* CONSOLE_COUNT)) {
*/
if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) {
if (c == 0x112)
change_console(KERNEL_CONSOLE);
if ((ev.key >= KC_F1) && (ev.key < KC_F1 +
CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) {
if (ev.key == KC_F1 + KERNEL_CONSOLE)
change_console(kernel_console);
else
change_console(c - 0x101);
change_console(&consoles[ev.key - KC_F1]);
break;
}
/* if client is awaiting key, send it */
if (conn->keyrequest_counter > 0) {
conn->keyrequest_counter--;
ipc_answer_1(fifo_pop(conn->keyrequests), EOK,
c);
break;
}
keybuffer_push(&conn->keybuffer, c);
retval = 0;
fibril_mutex_lock(&input_mutex);
keybuffer_push(&active_console->keybuffer, &ev);
fibril_condvar_broadcast(&input_cv);
fibril_mutex_unlock(&input_mutex);
break;
default:
retval = ENOENT;
364,204 → 425,361
}
}
 
static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *buf = (char *) malloc(size);
if (buf == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
(void) ipc_data_write_finalize(callid, buf, size);
async_serialize_start();
size_t off = 0;
while (off < size) {
wchar_t ch = str_decode(buf, &off, size);
write_char(cons, ch);
}
async_serialize_end();
gcons_notify_char(cons->index);
ipc_answer_1(rid, EOK, size);
free(buf);
}
 
static void cons_read(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *buf = (char *) malloc(size);
if (buf == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
size_t pos = 0;
console_event_t ev;
fibril_mutex_lock(&input_mutex);
recheck:
while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
if (ev.type == KEY_PRESS) {
buf[pos] = ev.c;
pos++;
}
}
if (pos == size) {
(void) ipc_data_read_finalize(callid, buf, size);
ipc_answer_1(rid, EOK, size);
free(buf);
} else {
fibril_condvar_wait(&input_cv, &input_mutex);
goto recheck;
}
fibril_mutex_unlock(&input_mutex);
}
 
static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
{
console_event_t ev;
 
fibril_mutex_lock(&input_mutex);
recheck:
if (keybuffer_pop(&cons->keybuffer, &ev)) {
ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
} else {
fibril_condvar_wait(&input_cv, &input_mutex);
goto recheck;
}
fibril_mutex_unlock(&input_mutex);
}
 
/** Default thread for new connections */
static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
console_t *cons = NULL;
size_t i;
for (i = 0; i < CONSOLE_COUNT; i++) {
if (i == KERNEL_CONSOLE)
continue;
if (consoles[i].dev_handle == (dev_handle_t) IPC_GET_ARG1(*icall)) {
cons = &consoles[i];
break;
}
}
if (cons == NULL) {
ipc_answer_0(iid, ENOENT);
return;
}
ipc_callid_t callid;
ipc_call_t call;
int consnum;
ipcarg_t arg1, arg2;
connection_t *conn;
ipcarg_t arg1;
ipcarg_t arg2;
ipcarg_t arg3;
 
if ((consnum = find_free_connection()) == -1) {
ipc_answer_0(iid, ELIMIT);
return;
}
conn = &connections[consnum];
conn->used = 1;
int cons_ccap;
int rc;
async_serialize_start();
gcons_notify_connect(consnum);
conn->client_phone = IPC_GET_ARG5(*icall);
screenbuffer_clear(&conn->screenbuffer);
if (cons->refcount == 0)
gcons_notify_connect(cons->index);
cons->refcount++;
/* Accept the connection */
ipc_answer_0(iid, EOK);
 
while (1) {
while (true) {
async_serialize_end();
callid = async_get_call(&call);
async_serialize_start();
 
arg1 = 0;
arg2 = 0;
arg3 = 0;
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
gcons_notify_disconnect(consnum);
/* Answer all pending requests */
while (conn->keyrequest_counter > 0) {
conn->keyrequest_counter--;
ipc_answer_0(fifo_pop(conn->keyrequests),
ENOENT);
break;
cons->refcount--;
if (cons->refcount == 0)
gcons_notify_disconnect(cons->index);
return;
case VFS_OUT_READ:
async_serialize_end();
cons_read(cons, callid, &call);
async_serialize_start();
continue;
case VFS_OUT_WRITE:
async_serialize_end();
cons_write(cons, callid, &call);
async_serialize_start();
continue;
case VFS_OUT_SYNC:
fb_pending_flush();
if (cons == active_console) {
async_req_0_0(fb_info.phone, FB_FLUSH);
curs_goto(cons->scr.position_x, cons->scr.position_y);
}
conn->used = 0;
return;
case CONSOLE_PUTCHAR:
write_char(consnum, IPC_GET_ARG1(call));
gcons_notify_char(consnum);
break;
case CONSOLE_CLEAR:
/* Send message to fb */
if (consnum == active_console) {
async_msg_0(fb_info.phone, FB_CLEAR);
}
if (cons == active_console)
async_msg_0(fb_info.phone, FB_CLEAR);
screenbuffer_clear(&conn->screenbuffer);
screenbuffer_clear(&cons->scr);
break;
case CONSOLE_GOTO:
screenbuffer_goto(&conn->screenbuffer,
IPC_GET_ARG2(call), IPC_GET_ARG1(call));
if (consnum == active_console)
screenbuffer_goto(&cons->scr,
IPC_GET_ARG1(call), IPC_GET_ARG2(call));
if (cons == active_console)
curs_goto(IPC_GET_ARG1(call),
IPC_GET_ARG2(call));
break;
case CONSOLE_GETSIZE:
arg1 = fb_info.rows;
arg2 = fb_info.cols;
case CONSOLE_GET_SIZE:
arg1 = fb_info.cols;
arg2 = fb_info.rows;
break;
case CONSOLE_FLUSH:
if (consnum == active_console)
async_req_0_0(fb_info.phone, FB_FLUSH);
case CONSOLE_GET_COLOR_CAP:
rc = ccap_fb_to_con(fb_info.color_cap, &cons_ccap);
if (rc != EOK) {
ipc_answer_0(callid, rc);
continue;
}
arg1 = cons_ccap;
break;
case CONSOLE_SET_STYLE:
fb_pending_flush();
arg1 = IPC_GET_ARG1(call);
screenbuffer_set_style(&cons->scr, arg1);
if (cons == active_console)
set_style(arg1);
break;
case CONSOLE_SET_COLOR:
fb_pending_flush();
arg1 = IPC_GET_ARG1(call);
arg2 = IPC_GET_ARG2(call);
screenbuffer_set_style(&conn->screenbuffer, arg1,
arg2);
if (consnum == active_console)
set_style_col(arg1, arg2);
arg3 = IPC_GET_ARG3(call);
screenbuffer_set_color(&cons->scr, arg1, arg2, arg3);
if (cons == active_console)
set_color(arg1, arg2, arg3);
break;
case CONSOLE_SET_RGB_COLOR:
fb_pending_flush();
arg1 = IPC_GET_ARG1(call);
arg2 = IPC_GET_ARG2(call);
screenbuffer_set_rgb_color(&cons->scr, arg1, arg2);
if (cons == active_console)
set_rgb_color(arg1, arg2);
break;
case CONSOLE_CURSOR_VISIBILITY:
fb_pending_flush();
arg1 = IPC_GET_ARG1(call);
conn->screenbuffer.is_cursor_visible = arg1;
if (consnum == active_console)
cons->scr.is_cursor_visible = arg1;
if (cons == active_console)
curs_visibility(arg1);
break;
case CONSOLE_GETCHAR:
if (keybuffer_empty(&conn->keybuffer)) {
/* buffer is empty -> store request */
if (conn->keyrequest_counter <
MAX_KEYREQUESTS_BUFFERED) {
fifo_push(conn->keyrequests, callid);
conn->keyrequest_counter++;
} else {
/*
* No key available and too many
* requests => fail.
*/
ipc_answer_0(callid, ELIMIT);
}
continue;
}
keybuffer_pop(&conn->keybuffer, (int *) &arg1);
case CONSOLE_GET_EVENT:
async_serialize_end();
cons_get_event(cons, callid, &call);
async_serialize_start();
continue;
case CONSOLE_KCON_ENABLE:
change_console(kernel_console);
break;
}
ipc_answer_2(callid, EOK, arg1, arg2);
ipc_answer_3(callid, EOK, arg1, arg2, arg3);
}
}
 
int main(int argc, char *argv[])
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
{
printf(NAME ": HelenOS Console service\n");
ipcarg_t phonehash;
int kbd_phone;
int i;
change_console(prev_console);
}
 
async_set_client_connection(client_connection);
static bool console_init(void)
{
ipcarg_t color_cap;
 
/* Connect to keyboard driver */
 
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
while (kbd_phone < 0) {
usleep(10000);
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
if (kbd_phone < 0) {
printf(NAME ": Failed to connect to keyboard service\n");
return false;
}
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0)
return -1;
ipcarg_t phonehash;
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
printf(NAME ": Failed to create callback from keyboard service\n");
return false;
}
async_new_connection(phonehash, 0, NULL, keyboard_events);
 
/* Connect to framebuffer driver */
fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0);
if (fb_info.phone < 0) {
printf(NAME ": Failed to connect to video service\n");
return -1;
}
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0);
while (fb_info.phone < 0) {
usleep(10000);
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0);
/* Register driver */
int rc = devmap_driver_register(NAME, client_connection);
if (rc < 0) {
printf(NAME ": Unable to register driver (%d)\n", rc);
return false;
}
/* Save old kernel screen */
kernel_pixmap = switch_screens(-1);
 
/* Initialize gcons */
gcons_init(fb_info.phone);
/* Synchronize, the gcons can have something in queue */
/* Synchronize, the gcons could put something in queue */
async_req_0_0(fb_info.phone, FB_FLUSH);
/* Enable double buffering */
async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1);
async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &color_cap);
fb_info.color_cap = color_cap;
async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows,
&fb_info.cols);
set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
clrscr();
/* Set up shared memory buffer. */
size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
interbuffer = as_get_mappable_page(ib_size);
/* Init virtual consoles */
for (i = 0; i < CONSOLE_COUNT; i++) {
connections[i].used = 0;
keybuffer_init(&connections[i].keybuffer);
connections[i].keyrequests.head = 0;
connections[i].keyrequests.tail = 0;
connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED;
connections[i].keyrequest_counter = 0;
if (screenbuffer_init(&connections[i].screenbuffer,
fb_info.cols, fb_info.rows) == NULL) {
/* FIXME: handle error */
return -1;
}
}
connections[KERNEL_CONSOLE].used = 1;
if (as_area_create(interbuffer, ib_size, AS_AREA_READ |
AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer)
interbuffer = NULL;
interbuffer = mmap(NULL,
sizeof(keyfield_t) * fb_info.cols * fb_info.rows,
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!interbuffer) {
if (interbuffer) {
if (ipc_share_out_start(fb_info.phone, interbuffer,
AS_AREA_READ) != EOK) {
munmap(interbuffer,
sizeof(keyfield_t) * fb_info.cols * fb_info.rows);
as_area_destroy(interbuffer);
interbuffer = NULL;
}
}
 
fb_pending.cnt = 0;
/* Inititalize consoles */
size_t i;
for (i = 0; i < CONSOLE_COUNT; i++) {
if (i != KERNEL_CONSOLE) {
if (screenbuffer_init(&consoles[i].scr,
fb_info.cols, fb_info.rows) == NULL) {
printf(NAME ": Unable to allocate screen buffer %u\n", i);
return false;
}
screenbuffer_clear(&consoles[i].scr);
keybuffer_init(&consoles[i].keybuffer);
consoles[i].index = i;
consoles[i].refcount = 0;
char vc[MAX_DEVICE_NAME];
snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
devmap_hangup_phone(DEVMAP_DRIVER);
printf(NAME ": Unable to register device %s\n", vc);
return false;
}
}
}
/* Disable kernel output to the console */
__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
/* Initialize the screen */
async_serialize_start();
gcons_redraw_console();
set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
screen_clear();
curs_goto(0, 0);
curs_visibility(
connections[active_console].screenbuffer.is_cursor_visible);
curs_visibility(active_console->scr.is_cursor_visible);
async_serialize_end();
/* Receive kernel notifications */
if (event_subscribe(EVENT_KCONSOLE, 0) != EOK)
printf(NAME ": Error registering kconsole notifications\n");
async_set_interrupt_received(interrupt_received);
return true;
}
 
/* Register at NS */
if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, 0, &phonehash) != 0)
int main(int argc, char *argv[])
{
printf(NAME ": HelenOS Console service\n");
if (!console_init())
return -1;
// FIXME: avoid connectiong to itself, keep using klog
// printf(NAME ": Accepting connections\n");
printf(NAME ": Accepting connections\n");
async_manager();
return 0;
}
 
return 0;
}
/** @}
*/
/branches/arm/uspace/srv/console/screenbuffer.h
27,74 → 27,133
*/
 
/** @addtogroup console
* @{
* @{
*/
/** @file
*/
 
#ifndef __SCREENBUFFER_H__
#define __SCREENBUFFER_H__
#ifndef SCREENBUFFER_H__
#define SCREENBUFFER_H__
 
#include <stdint.h>
#include <sys/types.h>
#include <bool.h>
 
#define DEFAULT_FOREGROUND 0x0 /**< default console foreground color */
#define DEFAULT_BACKGROUND 0xf0f0f0 /**< default console background color */
#define DEFAULT_FOREGROUND 0x0 /**< default console foreground color */
#define DEFAULT_BACKGROUND 0xf0f0f0 /**< default console background color */
 
typedef struct {
unsigned int bg_color; /**< background color */
unsigned int fg_color; /**< foreground color */
} style_t;
uint8_t style;
} attr_style_t;
 
typedef struct {
uint8_t fg_color;
uint8_t bg_color;
uint8_t flags;
} attr_idx_t;
 
typedef struct {
uint32_t bg_color; /**< background color */
uint32_t fg_color; /**< foreground color */
} attr_rgb_t;
 
typedef struct {
enum {
at_style,
at_idx,
at_rgb
} t;
union {
attr_style_t s;
attr_idx_t i;
attr_rgb_t r;
} a;
} attrs_t;
 
/** One field on screen. It contain one character and its attributes. */
typedef struct {
char character; /**< Character itself */
style_t style; /**< Character`s attributes */
wchar_t character; /**< Character itself */
attrs_t attrs; /**< Character attributes */
} keyfield_t;
 
/** Structure for buffering state of one virtual console.
*/
typedef struct {
keyfield_t *buffer; /**< Screen content - characters and its style. Used as cyclyc buffer. */
unsigned int size_x, size_y; /**< Number of columns and rows */
unsigned int position_x, position_y; /**< Coordinates of last printed character for determining cursor position */
style_t style; /**< Current style */
unsigned int top_line; /**< Points to buffer[][] line that will be printed at screen as the first line */
unsigned char is_cursor_visible; /**< Cursor state - default is visible */
keyfield_t *buffer; /**< Screen content - characters and
their attributes (used as a circular buffer) */
size_t size_x; /**< Number of columns */
size_t size_y; /**< Number of rows */
/** Coordinates of last printed character for determining cursor position */
size_t position_x;
size_t position_y;
attrs_t attrs; /**< Current attributes. */
size_t top_line; /**< Points to buffer[][] line that will
be printed at screen as the first line */
bool is_cursor_visible; /**< Cursor state - default is visible */
} screenbuffer_t;
 
/** Returns keyfield for position on screen. Screenbuffer->buffer is cyclic buffer so we must couted in index of the topmost line.
* @param scr screenbuffer
* @param x position on screen
* @param y position on screen
* @return keyfield structure with character and its attributes on x,y
/** Returns keyfield for position on screen
*
* Screenbuffer->buffer is cyclic buffer so we
* must couted in index of the topmost line.
*
* @param scr Screenbuffer
* @param x Position on screen
* @param y Position on screen
*
* @return Keyfield structure with character and its attributes on x, y
*
*/
static inline keyfield_t *get_field_at(screenbuffer_t *scr, unsigned int x, unsigned int y)
static inline keyfield_t *get_field_at(screenbuffer_t *scr, size_t x, size_t y)
{
return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x;
}
 
/** Compares two styles.
* @param s1 first style
* @param s2 second style
* @return nonzero on equality
/** Compares two sets of attributes.
*
* @param s1 First style
* @param s2 Second style
*
* @return Nonzero on equality
*
*/
static inline int style_same(style_t s1, style_t s2)
static inline int attrs_same(attrs_t a1, attrs_t a2)
{
return s1.fg_color == s2.fg_color && s1.bg_color == s2.bg_color;
if (a1.t != a2.t)
return 0;
switch (a1.t) {
case at_style:
return (a1.a.s.style == a2.a.s.style);
case at_idx:
return (a1.a.i.fg_color == a2.a.i.fg_color)
&& (a1.a.i.bg_color == a2.a.i.bg_color)
&& (a1.a.i.flags == a2.a.i.flags);
case at_rgb:
return (a1.a.r.fg_color == a2.a.r.fg_color)
&& (a1.a.r.bg_color == a2.a.r.bg_color);
}
return 0;
}
 
 
void screenbuffer_putchar(screenbuffer_t *scr, char c);
screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y);
void screenbuffer_putchar(screenbuffer_t *scr, wchar_t c);
screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y);
 
void screenbuffer_clear(screenbuffer_t *scr);
void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line);
void screenbuffer_clear_line(screenbuffer_t *scr, size_t line);
void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest);
void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y);
void screenbuffer_set_style(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color);
void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y);
void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style);
void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color,
uint8_t bg_color, uint8_t attr);
void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color,
uint32_t bg_color);
 
#endif
 
/** @}
*/
 
/branches/arm/uspace/srv/console/gcons.c
27,7 → 27,7
*/
 
/** @addtogroup console
* @{
* @{
*/
/** @file
*/
39,23 → 39,25
#include <sys/mman.h>
#include <string.h>
#include <align.h>
#include <bool.h>
 
#include "console.h"
#include "gcons.h"
 
#define CONSOLE_TOP 66
#define CONSOLE_MARGIN 6
#define CONSOLE_TOP 66
#define CONSOLE_MARGIN 6
 
#define STATUS_START 110
#define STATUS_TOP 8
#define STATUS_SPACE 4
#define STATUS_WIDTH 48
#define STATUS_HEIGHT 48
#define STATUS_START 110
#define STATUS_TOP 8
#define STATUS_SPACE 4
#define STATUS_WIDTH 48
#define STATUS_HEIGHT 48
 
#define MAIN_COLOR 0xffffff
#define MAIN_COLOR 0xffffff
 
static int use_gcons = 0;
static ipcarg_t xres,yres;
static bool use_gcons = false;
static ipcarg_t xres;
static ipcarg_t yres;
 
enum butstate {
CONS_DISCONNECTED = 0,
77,16 → 79,22
static int ic_pixmaps[CONS_LAST] = {-1, -1, -1, -1, -1, -1};
static int animation = -1;
 
static int active_console = 0;
static size_t active_console = 0;
 
size_t mouse_x;
size_t mouse_y;
 
bool btn_pressed;
size_t btn_x;
size_t btn_y;
 
static void vp_switch(int vp)
{
async_msg_1(fbphone,FB_VIEWPORT_SWITCH, vp);
async_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp);
}
 
/** Create view port */
static int vp_create(unsigned int x, unsigned int y, unsigned int width,
unsigned int height)
static int vp_create(size_t x, size_t y, size_t width, size_t height)
{
return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
(width << 16) | height);
97,48 → 105,52
async_msg_0(fbphone, FB_CLEAR);
}
 
static void set_style(int fgcolor, int bgcolor)
static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
{
async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
}
 
/** Transparent putchar */
static void tran_putch(char c, int row, int col)
static void tran_putch(wchar_t ch, size_t col, size_t row)
{
async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
}
 
/** Redraw the button showing state of a given console */
static void redraw_state(int consnum)
static void redraw_state(size_t index)
{
char data[5];
int i;
enum butstate state = console_state[consnum];
 
vp_switch(cstatus_vp[consnum]);
vp_switch(cstatus_vp[index]);
enum butstate state = console_state[index];
if (ic_pixmaps[state] != -1)
async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum],
async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
ic_pixmaps[state]);
 
if (state != CONS_DISCONNECTED && state != CONS_KERNEL &&
state != CONS_DISCONNECTED_SEL) {
snprintf(data, 5, "%d", consnum + 1);
for (i = 0; data[i]; i++)
tran_putch(data[i], 1, 2 + i);
}
if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL)
&& (state != CONS_DISCONNECTED_SEL)) {
char data[5];
snprintf(data, 5, "%u", index + 1);
size_t i;
for (i = 0; data[i] != 0; i++)
tran_putch(data[i], 2 + i, 1);
}
}
 
/** Notification run on changing console (except kernel console) */
void gcons_change_console(int consnum)
void gcons_change_console(size_t index)
{
int i;
 
if (!use_gcons)
return;
 
if (active_console == KERNEL_CONSOLE) {
size_t i;
for (i = 0; i < CONSOLE_COUNT; i++)
redraw_state(i);
if (animation != -1)
async_msg_1(fbphone, FB_ANIM_START, animation);
} else {
146,71 → 158,74
console_state[active_console] = CONS_DISCONNECTED;
else
console_state[active_console] = CONS_IDLE;
redraw_state(active_console);
}
active_console = consnum;
 
if (console_state[consnum] == CONS_DISCONNECTED) {
console_state[consnum] = CONS_DISCONNECTED_SEL;
redraw_state(consnum);
} else
console_state[consnum] = CONS_SELECTED;
redraw_state(consnum);
 
active_console = index;
if ((console_state[index] == CONS_DISCONNECTED)
|| (console_state[index] == CONS_DISCONNECTED_SEL))
console_state[index] = CONS_DISCONNECTED_SEL;
else
console_state[index] = CONS_SELECTED;
redraw_state(index);
vp_switch(console_vp);
}
 
/** Notification function that gets called on new output to virtual console */
void gcons_notify_char(int consnum)
void gcons_notify_char(size_t index)
{
if (!use_gcons)
return;
 
if (consnum == active_console ||
console_state[consnum] == CONS_HAS_DATA)
if ((index == active_console)
|| (console_state[index] == CONS_HAS_DATA))
return;
 
console_state[consnum] = CONS_HAS_DATA;
 
console_state[index] = CONS_HAS_DATA;
if (active_console == KERNEL_CONSOLE)
return;
 
redraw_state(consnum);
redraw_state(index);
vp_switch(console_vp);
}
 
/** Notification function called on service disconnect from console */
void gcons_notify_disconnect(int consnum)
void gcons_notify_disconnect(size_t index)
{
if (!use_gcons)
return;
if (active_console == consnum)
console_state[consnum] = CONS_DISCONNECTED_SEL;
if (index == active_console)
console_state[index] = CONS_DISCONNECTED_SEL;
else
console_state[consnum] = CONS_DISCONNECTED;
 
console_state[index] = CONS_DISCONNECTED;
if (active_console == KERNEL_CONSOLE)
return;
 
redraw_state(consnum);
redraw_state(index);
vp_switch(console_vp);
}
 
/** Notification function called on console connect */
void gcons_notify_connect(int consnum)
void gcons_notify_connect(size_t index)
{
if (!use_gcons)
return;
if (active_console == consnum)
console_state[consnum] = CONS_SELECTED;
if (index == active_console)
console_state[index] = CONS_SELECTED;
else
console_state[consnum] = CONS_IDLE;
 
console_state[index] = CONS_IDLE;
if (active_console == KERNEL_CONSOLE)
return;
 
redraw_state(consnum);
redraw_state(index);
vp_switch(console_vp);
}
 
217,50 → 232,43
/** Change to kernel console */
void gcons_in_kernel(void)
{
if (console_state[active_console] == CONS_DISCONNECTED_SEL)
console_state[active_console] = CONS_DISCONNECTED;
else
console_state[active_console] = CONS_IDLE;
redraw_state(active_console);
 
if (animation != -1)
async_msg_1(fbphone, FB_ANIM_STOP, animation);
 
active_console = KERNEL_CONSOLE; /* Set to kernel console */
active_console = KERNEL_CONSOLE;
vp_switch(0);
}
 
/** Return x, where left <= x <= right && |a-x|==min(|a-x|) is smallest */
static inline int limit(int a,int left, int right)
/** Return x, where left <= x <= right && |a-x| == min(|a-x|) is smallest */
static inline int limit(size_t a, size_t left, size_t right)
{
if (a < left)
a = left;
if (a >= right)
a = right - 1;
return a;
}
 
int mouse_x, mouse_y;
int btn_pressed, btn_x, btn_y;
 
/** Handle mouse move
*
* @param dx Delta X of mouse move
* @param dy Delta Y of mouse move
*/
void gcons_mouse_move(int dx, int dy)
void gcons_mouse_move(ssize_t dx, ssize_t dy)
{
mouse_x = limit(mouse_x+dx, 0, xres);
mouse_y = limit(mouse_y+dy, 0, yres);
 
mouse_x = limit(mouse_x + dx, 0, xres);
mouse_y = limit(mouse_y + dy, 0, yres);
async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
}
 
static int gcons_find_conbut(int x, int y)
{
int status_start = STATUS_START + (xres - 800) / 2;;
 
if (y < STATUS_TOP || y >= STATUS_TOP + STATUS_HEIGHT)
int status_start = STATUS_START + (xres - 800) / 2;
if ((y < STATUS_TOP) || (y >= STATUS_TOP + STATUS_HEIGHT))
return -1;
if (x < status_start)
268,36 → 276,39
if (x >= status_start + (STATUS_WIDTH + STATUS_SPACE) * CONSOLE_COUNT)
return -1;
if (((x - status_start) % (STATUS_WIDTH+STATUS_SPACE)) < STATUS_SPACE)
if (((x - status_start) % (STATUS_WIDTH + STATUS_SPACE)) < STATUS_SPACE)
return -1;
return (x - status_start) / (STATUS_WIDTH+STATUS_SPACE);
return (x - status_start) / (STATUS_WIDTH + STATUS_SPACE);
}
 
/** Handle mouse click
*
* @param state New state (1-pressed, 0-depressed)
* @param state New state (true - pressed, false - depressed)
*/
int gcons_mouse_btn(int state)
int gcons_mouse_btn(bool state)
{
int conbut;
 
if (state) {
conbut = gcons_find_conbut(mouse_x, mouse_y);
if (conbut != -1) {
btn_pressed = 1;
btn_pressed = true;
btn_x = mouse_x;
btn_y = mouse_y;
}
return -1;
}
if (!state && !btn_pressed)
}
if ((!state) && (!btn_pressed))
return -1;
btn_pressed = 0;
 
btn_pressed = false;
conbut = gcons_find_conbut(mouse_x, mouse_y);
if (conbut == gcons_find_conbut(btn_x, btn_y))
return conbut;
return -1;
}
 
313,53 → 324,60
{
char *shm;
int rc;
 
/* Create area */
shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
MAP_ANONYMOUS, 0, 0);
if (shm == MAP_FAILED)
return;
 
memcpy(shm, logo, size);
/* Send area */
rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
if (rc)
goto exit;
rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
if (rc)
goto drop;
/* Draw logo */
async_msg_2(fbphone, FB_DRAW_PPM, x, y);
drop:
/* Drop area */
async_msg_0(fbphone, FB_DROP_SHM);
exit:
exit:
/* Remove area */
munmap(shm, size);
}
 
extern char _binary_helenos_ppm_start[0];
extern int _binary_helenos_ppm_size;
extern char _binary_nameic_ppm_start[0];
extern int _binary_nameic_ppm_size;
/** Redraws console graphics */
static void gcons_redraw_console(void)
extern char _binary_gfx_helenos_ppm_start[0];
extern int _binary_gfx_helenos_ppm_size;
extern char _binary_gfx_nameic_ppm_start[0];
extern int _binary_gfx_nameic_ppm_size;
 
/** Redraws console graphics */
void gcons_redraw_console(void)
{
int i;
 
if (!use_gcons)
return;
vp_switch(0);
set_style(MAIN_COLOR, MAIN_COLOR);
set_rgb_color(MAIN_COLOR, MAIN_COLOR);
clear();
draw_pixmap(_binary_helenos_ppm_start,
(size_t) &_binary_helenos_ppm_size, xres - 66, 2);
draw_pixmap(_binary_nameic_ppm_start,
(size_t) &_binary_nameic_ppm_size, 5, 17);
 
draw_pixmap(_binary_gfx_helenos_ppm_start,
(size_t) &_binary_gfx_helenos_ppm_size, xres - 66, 2);
draw_pixmap(_binary_gfx_nameic_ppm_start,
(size_t) &_binary_gfx_nameic_ppm_size, 5, 17);
for (i = 0; i < CONSOLE_COUNT; i++)
redraw_state(i);
vp_switch(console_vp);
}
 
367,152 → 385,159
*
* @param data PPM data
* @param size PPM data size
*
* @return Pixmap identification
*
*/
static int make_pixmap(char *data, int size)
static int make_pixmap(char *data, size_t size)
{
char *shm;
int rc;
int pxid = -1;
 
/* Create area */
shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
MAP_ANONYMOUS, 0, 0);
if (shm == MAP_FAILED)
return -1;
 
memcpy(shm, data, size);
/* Send area */
rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
if (rc)
goto exit;
rc = ipc_share_out_start(fbphone, shm, PROTO_READ);
if (rc)
goto drop;
 
/* Obtain pixmap */
rc = async_req_0_0(fbphone, FB_SHM2PIXMAP);
if (rc < 0)
goto drop;
pxid = rc;
drop:
/* Drop area */
async_msg_0(fbphone, FB_DROP_SHM);
exit:
exit:
/* Remove area */
munmap(shm, size);
 
return pxid;
}
 
extern char _binary_anim_1_ppm_start[0];
extern int _binary_anim_1_ppm_size;
extern char _binary_anim_2_ppm_start[0];
extern int _binary_anim_2_ppm_size;
extern char _binary_anim_3_ppm_start[0];
extern int _binary_anim_3_ppm_size;
extern char _binary_anim_4_ppm_start[0];
extern int _binary_anim_4_ppm_size;
extern char _binary_gfx_anim_1_ppm_start[0];
extern int _binary_gfx_anim_1_ppm_size;
extern char _binary_gfx_anim_2_ppm_start[0];
extern int _binary_gfx_anim_2_ppm_size;
extern char _binary_gfx_anim_3_ppm_start[0];
extern int _binary_gfx_anim_3_ppm_size;
extern char _binary_gfx_anim_4_ppm_start[0];
extern int _binary_gfx_anim_4_ppm_size;
 
static void make_anim(void)
{
int an;
int pm;
 
an = async_req_1_0(fbphone, FB_ANIM_CREATE, cstatus_vp[KERNEL_CONSOLE]);
int an = async_req_1_0(fbphone, FB_ANIM_CREATE, cstatus_vp[KERNEL_CONSOLE]);
if (an < 0)
return;
 
pm = make_pixmap(_binary_anim_1_ppm_start,
(int) &_binary_anim_1_ppm_size);
int pm = make_pixmap(_binary_gfx_anim_1_ppm_start,
(int) &_binary_gfx_anim_1_ppm_size);
async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 
pm = make_pixmap(_binary_anim_2_ppm_start,
(int) &_binary_anim_2_ppm_size);
pm = make_pixmap(_binary_gfx_anim_2_ppm_start,
(int) &_binary_gfx_anim_2_ppm_size);
async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 
pm = make_pixmap(_binary_anim_3_ppm_start,
(int) &_binary_anim_3_ppm_size);
pm = make_pixmap(_binary_gfx_anim_3_ppm_start,
(int) &_binary_gfx_anim_3_ppm_size);
async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 
pm = make_pixmap(_binary_anim_4_ppm_start,
(int) &_binary_anim_4_ppm_size);
pm = make_pixmap(_binary_gfx_anim_4_ppm_start,
(int) &_binary_gfx_anim_4_ppm_size);
async_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
 
async_msg_1(fbphone, FB_ANIM_START, an);
 
animation = an;
}
 
extern char _binary_cons_selected_ppm_start[0];
extern int _binary_cons_selected_ppm_size;
extern char _binary_cons_idle_ppm_start[0];
extern int _binary_cons_idle_ppm_size;
extern char _binary_cons_has_data_ppm_start[0];
extern int _binary_cons_has_data_ppm_size;
extern char _binary_cons_kernel_ppm_start[0];
extern int _binary_cons_kernel_ppm_size;
extern char _binary_gfx_cons_selected_ppm_start[0];
extern int _binary_gfx_cons_selected_ppm_size;
extern char _binary_gfx_cons_idle_ppm_start[0];
extern int _binary_gfx_cons_idle_ppm_size;
extern char _binary_gfx_cons_has_data_ppm_start[0];
extern int _binary_gfx_cons_has_data_ppm_size;
extern char _binary_gfx_cons_kernel_ppm_start[0];
extern int _binary_gfx_cons_kernel_ppm_size;
 
/** Initialize nice graphical console environment */
void gcons_init(int phone)
{
int rc;
int i;
int status_start = STATUS_START;
 
fbphone = phone;
 
rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
if (rc)
return;
if (xres < 800 || yres < 600)
if ((xres < 800) || (yres < 600))
return;
 
/* create console viewport */
/* Create console viewport */
/* Align width & height to character size */
console_vp = vp_create(CONSOLE_MARGIN, CONSOLE_TOP,
ALIGN_DOWN(xres - 2 * CONSOLE_MARGIN, 8),
ALIGN_DOWN(yres - (CONSOLE_TOP + CONSOLE_MARGIN), 16));
if (console_vp < 0)
return;
/* Create status buttons */
status_start += (xres - 800) / 2;
size_t status_start = STATUS_START + (xres - 800) / 2;
size_t i;
for (i = 0; i < CONSOLE_COUNT; i++) {
cstatus_vp[i] = vp_create(status_start + CONSOLE_MARGIN +
i * (STATUS_WIDTH + STATUS_SPACE), STATUS_TOP,
STATUS_WIDTH, STATUS_HEIGHT);
if (cstatus_vp[i] < 0)
return;
vp_switch(cstatus_vp[i]);
set_style(0x202020, 0xffffff);
set_rgb_color(0x202020, 0xffffff);
}
/* Initialize icons */
ic_pixmaps[CONS_SELECTED] =
make_pixmap(_binary_cons_selected_ppm_start,
(int) &_binary_cons_selected_ppm_size);
ic_pixmaps[CONS_IDLE] = make_pixmap(_binary_cons_idle_ppm_start,
(int) &_binary_cons_idle_ppm_size);
make_pixmap(_binary_gfx_cons_selected_ppm_start,
(size_t) &_binary_gfx_cons_selected_ppm_size);
ic_pixmaps[CONS_IDLE] =
make_pixmap(_binary_gfx_cons_idle_ppm_start,
(size_t) &_binary_gfx_cons_idle_ppm_size);
ic_pixmaps[CONS_HAS_DATA] =
make_pixmap(_binary_cons_has_data_ppm_start,
(int) &_binary_cons_has_data_ppm_size);
make_pixmap(_binary_gfx_cons_has_data_ppm_start,
(size_t) &_binary_gfx_cons_has_data_ppm_size);
ic_pixmaps[CONS_DISCONNECTED] =
make_pixmap(_binary_cons_idle_ppm_start,
(int) &_binary_cons_idle_ppm_size);
ic_pixmaps[CONS_KERNEL] = make_pixmap(_binary_cons_kernel_ppm_start,
(int) &_binary_cons_kernel_ppm_size);
make_pixmap(_binary_gfx_cons_idle_ppm_start,
(size_t) &_binary_gfx_cons_idle_ppm_size);
ic_pixmaps[CONS_KERNEL] =
make_pixmap(_binary_gfx_cons_kernel_ppm_start,
(size_t) &_binary_gfx_cons_kernel_ppm_size);
ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
make_anim();
 
use_gcons = 1;
use_gcons = true;
console_state[0] = CONS_DISCONNECTED_SEL;
console_state[KERNEL_CONSOLE] = CONS_KERNEL;
gcons_redraw_console();
vp_switch(console_vp);
}
 
/** @}
*/
 
/branches/arm/uspace/srv/console/gcons.h
27,24 → 27,30
*/
 
/** @addtogroup console
* @{
* @{
*/
/** @file
*/
 
#ifndef _GCONS_H_
#define _GCONS_H_
#ifndef GCONS_H_
#define GCONS_H_
 
#include <sys/types.h>
 
void gcons_init(int phone);
void gcons_change_console(int consnum);
void gcons_notify_char(int consnum);
 
void gcons_redraw_console(void);
void gcons_change_console(size_t index);
void gcons_notify_char(size_t index);
void gcons_in_kernel(void);
void gcons_notify_connect(int consnum);
void gcons_notify_disconnect(int consnum);
void gcons_mouse_move(int dx, int dy);
int gcons_mouse_btn(int state);
 
void gcons_notify_connect(size_t index);
void gcons_notify_disconnect(size_t index);
 
void gcons_mouse_move(ssize_t dx, ssize_t dy);
int gcons_mouse_btn(bool state);
 
#endif
 
/** @}
*/
/branches/arm/uspace/srv/console/screenbuffer.c
27,48 → 27,55
*/
 
/** @addtogroup console
* @{
* @{
*/
/** @file
*/
 
#include <screenbuffer.h>
#include <io/style.h>
#include <malloc.h>
#include <unistd.h>
 
/** Store one character to screenbuffer. Its position is determined by
* scr->position_x and scr->position_y.
/** Store one character to screenbuffer.
*
* @param scr screenbuffer
* @param c stored character
* Its position is determined by scr->position_x
* and scr->position_y.
*
* @param scr Screenbuffer
* @param c Stored character
*
*/
void screenbuffer_putchar(screenbuffer_t *scr, char c)
void screenbuffer_putchar(screenbuffer_t *scr, wchar_t ch)
{
keyfield_t *field;
keyfield_t *field =
get_field_at(scr, scr->position_x, scr->position_y);
field = get_field_at(scr, scr->position_x, scr->position_y);
 
field->character = c;
field->style = scr->style;
field->character = ch;
field->attrs = scr->attrs;
}
 
/** Initilize screenbuffer. Allocate space for screen content in accordance to given size.
* @param scr initialized screenbuffer
* @param size_x width in characters
* @param size_y height in characters
* @return pointer to screenbuffer (same as scr parameter) or NULL
/** Initilize screenbuffer.
*
* Allocate space for screen content in accordance to given size.
*
* @param scr Initialized screenbuffer
* @param size_x Width in characters
* @param size_y Height in characters
*
* @return Pointer to screenbuffer (same as scr parameter) or NULL
*
*/
screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y)
screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y)
{
scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y);
if (!scr->buffer) {
if (!scr->buffer)
return NULL;
}
scr->size_x = size_x;
scr->size_y = size_y;
scr->style.fg_color = DEFAULT_FOREGROUND;
scr->style.bg_color = DEFAULT_BACKGROUND;
scr->attrs.t = at_style;
scr->attrs.a.s.style = STYLE_NORMAL;
scr->is_cursor_visible = 1;
screenbuffer_clear(scr);
76,56 → 83,63
return scr;
}
 
/** Clear screenbuffer.
* @param scr screenbuffer
/** Clear screenbuffer.
*
* @param scr Screenbuffer
*
*/
void screenbuffer_clear(screenbuffer_t *scr)
{
unsigned int i;
size_t i;
for (i = 0; i < (scr->size_x * scr->size_y); i++) {
scr->buffer[i].character = ' ';
scr->buffer[i].style = scr->style;
scr->buffer[i].attrs = scr->attrs;
}
 
scr->top_line = 0;
scr->position_x = 0;
scr->position_y = 0;
scr->position_x = 0;
}
 
/** Clear one buffer line.
*
* @param scr
* @param line One buffer line (not a screen line!)
*
*/
void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line)
void screenbuffer_clear_line(screenbuffer_t *scr, size_t line)
{
unsigned int i;
size_t x;
for (i = 0; i < scr->size_x; i++) {
scr->buffer[i + line * scr->size_x].character = ' ';
scr->buffer[i + line * scr->size_x].style = scr->style;
for (x = 0; x < scr->size_x; x++) {
scr->buffer[x + line * scr->size_x].character = ' ';
scr->buffer[x + line * scr->size_x].attrs = scr->attrs;
}
}
 
/** Copy content buffer from screenbuffer to given memory.
* @param scr source screenbuffer
* @param dest destination
*
* @param scr Source screenbuffer
* @param dest Destination
*
*/
void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest)
void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest)
{
unsigned int i;
size_t i;
for (i = 0; i < scr->size_x * scr->size_y; i++) {
for (i = 0; i < (scr->size_x * scr->size_y); i++)
dest[i] = scr->buffer[i];
}
}
 
/** Set new cursor position in screenbuffer.
*
* @param scr
* @param x
* @param y
*
*/
void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y)
void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y)
{
scr->position_x = x % scr->size_x;
scr->position_y = y % scr->size_y;
132,16 → 146,46
}
 
/** Set new style.
*
* @param scr
* @param fg_color
* @param bg_color
*
*/
void screenbuffer_set_style(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color)
void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style)
{
scr->style.fg_color = fg_color;
scr->style.bg_color = bg_color;
scr->attrs.t = at_style;
scr->attrs.a.s.style = style;
}
 
/** Set new color.
*
* @param scr
* @param fg_color
* @param bg_color
*
*/
void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags)
{
scr->attrs.t = at_idx;
scr->attrs.a.i.fg_color = fg_color;
scr->attrs.a.i.bg_color = bg_color;
scr->attrs.a.i.flags = flags;
}
 
/** Set new RGB color.
*
* @param scr
* @param fg_color
* @param bg_color
*
*/
void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color)
{
scr->attrs.t = at_rgb;
scr->attrs.a.r.fg_color = fg_color;
scr->attrs.a.r.bg_color = bg_color;
}
 
/** @}
*/
/branches/arm/uspace/srv/console/Makefile
31,8 → 31,9
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I. -I../kbd/include -I../fb
 
LIBS = $(LIBC_PREFIX)/libc.a
41,22 → 42,30
#
 
OUTPUT = console
 
GENERIC_SOURCES = \
console.c \
screenbuffer.c \
../kbd/generic/key_buffer.c \
../kbd/generic/keybuffer.c \
gcons.c
 
IMAGES = helenos.ppm nameic.ppm cons_selected.ppm cons_idle.ppm \
cons_has_data.ppm cons_kernel.ppm anim_1.ppm anim_2.ppm anim_3.ppm \
anim_4.ppm
IMAGES = \
gfx/helenos.ppm \
gfx/nameic.ppm \
gfx/cons_selected.ppm \
gfx/cons_idle.ppm \
gfx/cons_has_data.ppm \
gfx/cons_kernel.ppm \
gfx/anim_1.ppm \
gfx/anim_2.ppm \
gfx/anim_3.ppm \
gfx/anim_4.ppm
 
ARCH_SOURCES =
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) \
$(addsuffix .o,$(basename $(IMAGES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
$(addsuffix .o,$(basename $(IMAGES)))
 
OBJECTS := $(GENERIC_OBJECTS)
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
64,18 → 73,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(GENERIC_OBJECTS) $(ARCH_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/console/gfx/anim_1.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/anim_2.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/anim_3.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/cons_has_data.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/anim_4.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/cons_selected.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/nameic.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/helenos.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/cons_idle.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/gfx/cons_kernel.ppm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/uspace/srv/console/console.h
27,7 → 27,7
*/
 
/** @addtogroup console
* @{
* @{
*/
/** @file
*/
35,20 → 35,10
#ifndef __CONSOLE_H__
#define __CONSOLE_H__
 
#define KERNEL_CONSOLE 11
#define CONSOLE_COUNT 12
#define KERNEL_CONSOLE 11
 
#define CONSOLE_COUNT 12
#endif
 
#define CONSOLE_GETCHAR 1026
#define CONSOLE_PUTCHAR 1027
#define CONSOLE_CLEAR 1028
#define CONSOLE_GOTO 1029
#define CONSOLE_GETSIZE 1030
#define CONSOLE_FLUSH 1031
#define CONSOLE_SET_STYLE 1032
#define CONSOLE_CURSOR_VISIBILITY 1033
 
#endif
/** @}
*/
/branches/arm/uspace/srv/fb/serial_console.c
0,0 → 1,462
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/**
* @defgroup serial Serial console
* @brief Serial console services (putc, puts, clear screen, cursor goto,...)
* @{
*/
 
/** @file
*/
 
#include <stdio.h>
#include <ipc/ipc.h>
#include <async.h>
#include <ipc/fb.h>
#include <bool.h>
#include <errno.h>
#include <io/color.h>
#include <io/style.h>
#include <string.h>
 
#include "../console/screenbuffer.h"
#include "main.h"
#include "serial_console.h"
 
#define MAX_CONTROL 20
 
static void serial_sgr(const unsigned int mode);
void serial_putchar(wchar_t ch);
 
static int scr_width;
static int scr_height;
static bool color = true; /** True if producing color output. */
static bool utf8 = false; /** True if producing UTF8 output. */
static putc_function_t putc_function;
 
/* Allow only 1 connection */
static int client_connected = 0;
 
enum sgr_color_index {
CI_BLACK = 0,
CI_RED = 1,
CI_GREEN = 2,
CI_BROWN = 3,
CI_BLUE = 4,
CI_MAGENTA = 5,
CI_CYAN = 6,
CI_WHITE = 7,
};
 
enum sgr_command {
SGR_RESET = 0,
SGR_BOLD = 1,
SGR_BLINK = 5,
SGR_REVERSE = 7,
SGR_NORMAL_INT = 22,
SGR_BLINK_OFF = 25,
SGR_REVERSE_OFF = 27,
SGR_FGCOLOR = 30,
SGR_BGCOLOR = 40
};
 
static int color_map[] = {
[COLOR_BLACK] = CI_BLACK,
[COLOR_BLUE] = CI_RED,
[COLOR_GREEN] = CI_GREEN,
[COLOR_CYAN] = CI_CYAN,
[COLOR_RED] = CI_RED,
[COLOR_MAGENTA] = CI_MAGENTA,
[COLOR_YELLOW] = CI_BROWN,
[COLOR_WHITE] = CI_WHITE
};
 
void serial_puts(char *str)
{
while (*str)
putc_function(*(str++));
}
 
void serial_putchar(wchar_t ch)
{
uint8_t buf[STR_BOUNDS(1)];
size_t offs;
size_t i;
 
if (utf8 != true) {
if (ch >= 0 && ch < 128)
(*putc_function)((uint8_t) ch);
else
(*putc_function)('?');
return;
}
 
offs = 0;
if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
for (i = 0; i < offs; i++)
(*putc_function)(buf[i]);
} else {
(*putc_function)('?');
}
 
}
 
void serial_goto(const unsigned int col, const unsigned int row)
{
if ((col > scr_width) || (row > scr_height))
return;
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
serial_puts(control);
}
 
void serial_clrscr(void)
{
/* Initialize graphic rendition attributes. */
serial_sgr(SGR_RESET);
if (color) {
serial_sgr(SGR_FGCOLOR + CI_BLACK);
serial_sgr(SGR_BGCOLOR + CI_WHITE);
}
 
serial_puts("\033[2J");
}
 
void serial_scroll(int i)
{
if (i > 0) {
serial_goto(0, scr_height - 1);
while (i--)
serial_puts("\033D");
} else if (i < 0) {
serial_goto(0, 0);
while (i++)
serial_puts("\033M");
}
}
 
/** ECMA-48 Set Graphics Rendition. */
static void serial_sgr(const unsigned int mode)
{
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[%um", mode);
serial_puts(control);
}
 
/** Set scrolling region. */
void serial_set_scroll_region(unsigned last_row)
{
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
serial_puts(control);
}
 
void serial_cursor_disable(void)
{
serial_puts("\033[?25l");
}
 
void serial_cursor_enable(void)
{
serial_puts("\033[?25h");
}
 
void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
{
scr_width = w;
scr_height = h;
putc_function = putc_fn;
}
 
static void serial_set_style(int style)
{
if (style == STYLE_EMPHASIS) {
if (color) {
serial_sgr(SGR_RESET);
serial_sgr(SGR_FGCOLOR + CI_RED);
serial_sgr(SGR_BGCOLOR + CI_WHITE);
}
serial_sgr(SGR_BOLD);
} else {
if (color) {
serial_sgr(SGR_RESET);
serial_sgr(SGR_FGCOLOR + CI_BLACK);
serial_sgr(SGR_BGCOLOR + CI_WHITE);
}
serial_sgr(SGR_NORMAL_INT);
}
}
 
static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,
unsigned flags)
{
if (color) {
serial_sgr(SGR_RESET);
serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
} else {
if (fgcolor < bgcolor)
serial_sgr(SGR_RESET);
else
serial_sgr(SGR_REVERSE);
}
}
 
static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
{
if (fgcolor < bgcolor)
serial_sgr(SGR_REVERSE_OFF);
else
serial_sgr(SGR_REVERSE);
}
 
static void serial_set_attrs(const attrs_t *a)
{
switch (a->t) {
case at_style:
serial_set_style(a->a.s.style);
break;
case at_rgb:
serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
break;
case at_idx:
serial_set_idx(a->a.i.fg_color,
a->a.i.bg_color, a->a.i.flags);
break;
default:
break;
}
}
 
/** Draw text data to viewport.
*
* @param vport Viewport id
* @param data Text data.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
*/
static void draw_text_data(keyfield_t *data, unsigned int x,
unsigned int y, unsigned int w, unsigned int h)
{
unsigned int i, j;
keyfield_t *field;
attrs_t *a0, *a1;
 
serial_goto(x, y);
a0 = &data[0].attrs;
serial_set_attrs(a0);
 
for (j = 0; j < h; j++) {
if (j > 0 && w != scr_width)
serial_goto(x, j);
 
for (i = 0; i < w; i++) {
field = &data[j * w + i];
 
a1 = &field->attrs;
if (!attrs_same(*a0, *a1))
serial_set_attrs(a1);
serial_putchar(field->character);
a0 = a1;
}
}
}
 
int lastcol = 0;
int lastrow = 0;
 
/**
* Main function of the thread serving client connections.
*/
void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
int retval;
ipc_callid_t callid;
ipc_call_t call;
keyfield_t *interbuf = NULL;
size_t intersize = 0;
 
wchar_t c;
int col, row, w, h;
int i;
 
attrs_t cur_attr;
if (client_connected) {
ipc_answer_0(iid, ELIMIT);
return;
}
client_connected = 1;
ipc_answer_0(iid, EOK);
 
cur_attr.t = at_style;
cur_attr.a.s.style = STYLE_NORMAL;
/* Clear the terminal, set scrolling region
to 0 - height rows. */
serial_clrscr();
serial_goto(0, 0);
serial_set_scroll_region(scr_height);
while (true) {
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
client_connected = 0;
ipc_answer_0(callid, EOK);
return;
case IPC_M_SHARE_OUT:
/* We accept one area for data interchange */
intersize = IPC_GET_ARG2(call);
if (intersize >= scr_width * scr_height *
sizeof(*interbuf)) {
receive_comm_area(callid, &call,
(void *) &interbuf);
continue;
}
retval = EINVAL;
break;
case FB_DRAW_TEXT_DATA:
col = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
w = IPC_GET_ARG3(call);
h = IPC_GET_ARG4(call);
if (!interbuf) {
retval = EINVAL;
break;
}
if (col + w > scr_width || row + h > scr_height) {
retval = EINVAL;
break;
}
draw_text_data(interbuf, col, row, w, h);
lastcol = col + w;
lastrow = row + h - 1;
retval = 0;
break;
case FB_PUTCHAR:
c = IPC_GET_ARG1(call);
col = IPC_GET_ARG2(call);
row = IPC_GET_ARG3(call);
if ((lastcol != col) || (lastrow != row))
serial_goto(col, row);
lastcol = col + 1;
lastrow = row;
serial_putchar(c);
retval = 0;
break;
case FB_CURSOR_GOTO:
col = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
serial_goto(col, row);
lastcol = col;
lastrow = row;
retval = 0;
break;
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, scr_width, scr_height);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, color ? FB_CCAP_INDEXED :
FB_CCAP_STYLE);
continue;
case FB_CLEAR:
serial_clrscr();
retval = 0;
break;
case FB_SET_STYLE:
cur_attr.t = at_style;
cur_attr.a.s.style = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
serial_set_attrs(&cur_attr);
 
retval = 0;
break;
case FB_SET_COLOR:
cur_attr.t = at_idx;
cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
cur_attr.a.i.flags = IPC_GET_ARG3(call);
serial_set_attrs(&cur_attr);
 
retval = 0;
break;
case FB_SET_RGB_COLOR:
cur_attr.t = at_rgb;
cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
serial_set_attrs(&cur_attr);
 
retval = 0;
break;
case FB_SCROLL:
i = IPC_GET_ARG1(call);
if ((i > scr_height) || (i < -scr_height)) {
retval = EINVAL;
break;
}
serial_scroll(i);
serial_goto(lastcol, lastrow);
retval = 0;
break;
case FB_CURSOR_VISIBILITY:
if(IPC_GET_ARG1(call))
serial_cursor_enable();
else
serial_cursor_disable();
retval = 0;
break;
case FB_SCREEN_YIELD:
serial_sgr(SGR_RESET);
serial_puts("\033[2J");
serial_goto(0, 0);
serial_cursor_enable();
retval = 0;
break;
case FB_SCREEN_RECLAIM:
serial_clrscr();
serial_set_attrs(&cur_attr);
retval = 0;
break;
default:
retval = ENOENT;
}
ipc_answer_0(callid, retval);
}
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fb/fb.c
1,4 → 1,5
/*
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2006 Jakub Vana
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
29,10 → 30,10
 
/**
* @defgroup fb Graphical framebuffer
* @brief HelenOS graphical framebuffer.
* @brief HelenOS graphical framebuffer.
* @ingroup fbs
* @{
*/
*/
 
/** @file
*/
50,8 → 51,12
#include <ipc/services.h>
#include <kernel/errno.h>
#include <kernel/genarch/fb/visuals.h>
#include <io/color.h>
#include <io/style.h>
#include <async.h>
#include <fibril.h>
#include <bool.h>
#include <stdio.h>
 
#include "font-8x16.h"
#include "fb.h"
62,594 → 67,849
#include "pointer.xbm"
#include "pointer_mask.xbm"
 
#define DEFAULT_BGCOLOR 0xf0f0f0
#define DEFAULT_FGCOLOR 0x0
#define DEFAULT_BGCOLOR 0xf0f0f0
#define DEFAULT_FGCOLOR 0x000000
 
/***************************************************************/
/* Pixel specific fuctions */
#define GLYPH_UNAVAIL '?'
 
typedef void (*conv2scr_fn_t)(void *, int);
typedef int (*conv2rgb_fn_t)(void *);
#define MAX_ANIM_LEN 8
#define MAX_ANIMATIONS 4
#define MAX_PIXMAPS 256 /**< Maximum number of saved pixmaps */
#define MAX_VIEWPORTS 128 /**< Viewport is a rectangular area on the screen */
 
/** Function to render a pixel from a RGB value. */
typedef void (*rgb_conv_t)(void *, uint32_t);
 
/** Function to render a bit mask. */
typedef void (*mask_conv_t)(void *, bool);
 
/** Function to draw a glyph. */
typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
 
struct {
uint8_t *fbaddress;
 
uint8_t *fb_addr;
unsigned int xres;
unsigned int yres;
unsigned int scanline;
unsigned int glyphscanline;
unsigned int pixelbytes;
unsigned int invert_colors;
 
conv2scr_fn_t rgb2scr;
conv2rgb_fn_t scr2rgb;
unsigned int glyphbytes;
/** Pre-rendered mask for rendering glyphs. Specific for the visual. */
uint8_t *glyphs;
rgb_conv_t rgb_conv;
mask_conv_t mask_conv;
} screen;
 
/** Backbuffer character cell. */
typedef struct {
int initialized;
unsigned int x, y;
unsigned int width, height;
uint32_t glyph;
uint32_t fg_color;
uint32_t bg_color;
} bb_cell_t;
 
typedef struct {
bool initialized;
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
/* Text support in window */
unsigned int rows, cols;
/* Style for text printing */
style_t style;
unsigned int cols;
unsigned int rows;
/*
* Style and glyphs for text printing
*/
/** Current attributes. */
attr_rgb_t attr;
uint8_t *bgpixel;
/**
* Glyph drawing function for this viewport. Different viewports
* might use different drawing functions depending on whether their
* scanlines are aligned on a word boundary.
*/
dg_t dglyph;
/* Auto-cursor position */
int cursor_active, cur_col, cur_row;
int cursor_shown;
/* Double buffering */
uint8_t *dbdata;
unsigned int dboffset;
unsigned int paused;
bool cursor_active;
unsigned int cur_col;
unsigned int cur_row;
bool cursor_shown;
/* Back buffer */
bb_cell_t *backbuf;
unsigned int bbsize;
} viewport_t;
 
#define MAX_ANIM_LEN 8
#define MAX_ANIMATIONS 4
typedef struct {
int initialized;
int enabled;
bool initialized;
bool enabled;
unsigned int vp;
 
unsigned int pos;
unsigned int animlen;
unsigned int pixmaps[MAX_ANIM_LEN];
} animation_t;
 
static animation_t animations[MAX_ANIMATIONS];
static int anims_enabled;
static bool anims_enabled;
 
/** Maximum number of saved pixmaps
* Pixmap is a saved rectangle
*/
#define MAX_PIXMAPS 256
typedef struct {
unsigned int width;
unsigned int height;
uint8_t *data;
} pixmap_t;
 
static pixmap_t pixmaps[MAX_PIXMAPS];
 
/* Viewport is a rectangular area on the screen */
#define MAX_VIEWPORTS 128
static viewport_t viewports[128];
 
/* Allow only 1 connection */
static int client_connected = 0;
static bool client_connected = false; /**< Allow only 1 connection */
 
#define RED(x, bits) ((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
static uint32_t color_table[16] = {
[COLOR_BLACK] = 0x000000,
[COLOR_BLUE] = 0x0000f0,
[COLOR_GREEN] = 0x00f000,
[COLOR_CYAN] = 0x00f0f0,
[COLOR_RED] = 0xf00000,
[COLOR_MAGENTA] = 0xf000f0,
[COLOR_YELLOW] = 0xf0f000,
[COLOR_WHITE] = 0xf0f0f0,
[8 + COLOR_BLACK] = 0x000000,
[8 + COLOR_BLUE] = 0x0000ff,
[8 + COLOR_GREEN] = 0x00ff00,
[8 + COLOR_CYAN] = 0x00ffff,
[8 + COLOR_RED] = 0xff0000,
[8 + COLOR_MAGENTA] = 0xff00ff,
[8 + COLOR_YELLOW] = 0xffff00,
[8 + COLOR_WHITE] = 0xffffff,
};
 
#define COL_WIDTH 8
#define ROW_BYTES (screen.scanline * FONT_SCANLINES)
static int rgb_from_attr(attr_rgb_t *rgb, const attrs_t *a);
static int rgb_from_style(attr_rgb_t *rgb, int style);
static int rgb_from_idx(attr_rgb_t *rgb, ipcarg_t fg_color,
ipcarg_t bg_color, ipcarg_t flags);
 
#define POINTPOS(x, y) ((y) * screen.scanline + (x) * screen.pixelbytes)
static int fb_set_color(viewport_t *vport, ipcarg_t fg_color,
ipcarg_t bg_color, ipcarg_t attr);
 
static inline int COLOR(int color)
{
return screen.invert_colors ? ~color : color;
}
static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
static void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
 
/* Conversion routines between different color representations */
static void
rgb_byte0888(void *dst, int rgb)
{
*(int *)dst = rgb;
}
static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col,
unsigned int row);
 
static int
byte0888_rgb(void *src)
{
return (*(int *)src) & 0xffffff;
}
 
static void
bgr_byte0888(void *dst, int rgb)
{
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |
RED(rgb, 8);
}
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
 
static int
byte0888_bgr(void *src)
{
int color = *(uint32_t *)(src);
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) |
((color >> 16) & 0xff);
}
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
 
static void bgr_byte8880(void *dst, int rgb)
{
uint8_t *scr = (uint8_t *) dst;
scr[3] = RED(rgb, 8);
scr[2] = GREEN(rgb, 8);
scr[1] = BLUE(rgb, 8);
}
#define X2COL(x) ((x) / FONT_WIDTH)
#define Y2ROW(y) ((y) / FONT_SCANLINES)
 
static int byte8880_bgr(void *src)
{
uint8_t *scr = (uint8_t *) src;
return scr[3] << 16 | scr[2] << 8 | scr[1];
}
#define FB_POS(x, y) ((y) * screen.scanline + (x) * screen.pixelbytes)
#define BB_POS(vport, col, row) ((row) * vport->cols + (col))
#define GLYPH_POS(glyph, y, cursor) (((glyph) + (cursor) * FONT_GLYPHS) * screen.glyphbytes + (y) * screen.glyphscanline)
 
 
static void
rgb_byte888(void *dst, int rgb)
/** ARGB 8:8:8:8 conversion
*
*/
static void rgb_0888(void *dst, uint32_t rgb)
{
uint8_t *scr = dst;
#if defined(FB_INVERT_ENDIAN)
scr[0] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[2] = BLUE(rgb, 8);
#else
scr[2] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[0] = BLUE(rgb, 8);
#endif
*((uint32_t *) dst) = rgb & 0x00ffffff;
}
 
static int
byte888_rgb(void *src)
static void mask_0888(void *dst, bool mask)
{
uint8_t *scr = src;
#if defined(FB_INVERT_ENDIAN)
return scr[0] << 16 | scr[1] << 8 | scr[2];
#else
return scr[2] << 16 | scr[1] << 8 | scr[0];
#endif
*((uint32_t *) dst) = (mask ? 0x00ffffff : 0);
}
 
/** 16-bit depth (5:5:5) */
static void
rgb_byte555(void *dst, int rgb)
 
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
{
/* 5-bit, 5-bits, 5-bits */
*((uint16_t *)(dst)) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 |
BLUE(rgb, 5);
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
}
 
/** 16-bit depth (5:5:5) */
static int
byte555_rgb(void *src)
 
/** RGB 8:8:8 conversion
*
*/
static void rgb_888(void *dst, uint32_t rgb)
{
int color = *(uint16_t *)(src);
return (((color >> 10) & 0x1f) << (16 + 3)) |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3);
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
/** 16-bit depth (5:6:5) */
static void
rgb_byte565(void *dst, int rgb)
static void mask_888(void *dst, bool mask)
{
/* 5-bit, 6-bits, 5-bits */
*((uint16_t *)(dst)) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 |
BLUE(rgb, 5);
if (mask) {
((uint8_t *) dst)[0] = 0xff;
((uint8_t *) dst)[1] = 0xff;
((uint8_t *) dst)[2] = 0xff;
} else {
((uint8_t *) dst)[0] = 0;
((uint8_t *) dst)[1] = 0;
((uint8_t *) dst)[2] = 0;
}
}
 
/** 16-bit depth (5:6:5) */
static int
byte565_rgb(void *src)
 
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
{
int color = *(uint16_t *)(src);
return (((color >> 11) & 0x1f) << (16 + 3)) |
(((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
/** Put pixel - 8-bit depth (3:2:3) */
static void
rgb_byte8(void *dst, int rgb)
 
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
{
*(uint8_t *)dst = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | BLUE(rgb, 3);
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
}
 
/** Return pixel color - 8-bit depth (3:2:3) */
static int
byte8_rgb(void *src)
static void mask_555(void *dst, bool mask)
{
int color = *(uint8_t *)src;
return (((color >> 5) & 0x7) << (16 + 5)) |
(((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
*((uint16_t *) dst) = (mask ? 0x7fff : 0);
}
 
/** Put pixel into viewport
 
/** RGB 5:6:5 conversion
*
* @param vport Viewport identification
* @param x X coord relative to viewport
* @param y Y coord relative to viewport
* @param color RGB color
*/
static void
putpixel(viewport_t *vport, unsigned int x, unsigned int y, int color)
static void rgb_565(void *dst, uint32_t rgb)
{
int dx = vport->x + x;
int dy = vport->y + y;
 
if (! (vport->paused && vport->dbdata))
(*screen.rgb2scr)(&screen.fbaddress[POINTPOS(dx,dy)],
COLOR(color));
 
if (vport->dbdata) {
int dline = (y + vport->dboffset) % vport->height;
int doffset = screen.pixelbytes * (dline * vport->width + x);
(*screen.rgb2scr)(&vport->dbdata[doffset], COLOR(color));
}
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
}
 
/** Get pixel from viewport */
static int
getpixel(viewport_t *vport, unsigned int x, unsigned int y)
static void mask_565(void *dst, bool mask)
{
int dx = vport->x + x;
int dy = vport->y + y;
 
return COLOR((*screen.scr2rgb)(&screen.fbaddress[POINTPOS(dx, dy)]));
*((uint16_t *) dst) = (mask ? 0xffff : 0);
}
 
static inline void
putpixel_mem(char *mem, unsigned int x, unsigned int y, int color)
{
(*screen.rgb2scr)(&mem[POINTPOS(x, y)], COLOR(color));
}
 
static void
draw_rectangle(viewport_t *vport, unsigned int sx, unsigned int sy,
unsigned int width, unsigned int height, int color)
/** RGB 3:2:3
*
*/
static void rgb_323(void *dst, uint32_t rgb)
{
unsigned int x, y;
static void *tmpline;
 
if (!tmpline)
tmpline = malloc(screen.scanline * screen.pixelbytes);
 
/* Clear first line */
for (x = 0; x < width; x++)
putpixel_mem(tmpline, x, 0, color);
 
if (!vport->paused) {
/* Recompute to screen coords */
sx += vport->x;
sy += vport->y;
/* Copy the rest */
for (y = sy;y < sy+height; y++)
memcpy(&screen.fbaddress[POINTPOS(sx,y)], tmpline,
screen.pixelbytes * width);
}
if (vport->dbdata) {
for (y = sy; y < sy + height; y++) {
int rline = (y + vport->dboffset) % vport->height;
int rpos = (rline * vport->width + sx) *
screen.pixelbytes;
memcpy(&vport->dbdata[rpos], tmpline,
screen.pixelbytes * width);
}
}
 
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
}
 
/** Fill viewport with background color */
static void
clear_port(viewport_t *vport)
static void mask_323(void *dst, bool mask)
{
draw_rectangle(vport, 0, 0, vport->width, vport->height,
vport->style.bg_color);
*((uint8_t *) dst) = (mask ? 0xff : 0);
}
 
/** Scroll unbuffered viewport up/down
/** Draw a filled rectangle.
*
* @param vport Viewport to scroll
* @param lines Positive number - scroll up, negative - scroll down
* @note Need real implementation that does not access VRAM twice.
*
*/
static void
scroll_port_nodb(viewport_t *vport, int lines)
static void draw_filled_rect(unsigned int x0, unsigned int y0, unsigned int x1,
unsigned int y1, uint32_t color)
{
int y;
 
if (lines > 0) {
for (y = vport->y; y < vport->y+vport->height - lines; y++)
memcpy(&screen.fbaddress[POINTPOS(vport->x,y)],
&screen.fbaddress[POINTPOS(vport->x,y + lines)],
screen.pixelbytes * vport->width);
draw_rectangle(vport, 0, vport->height - lines, vport->width,
lines, vport->style.bg_color);
} else if (lines < 0) {
lines = -lines;
for (y = vport->y + vport->height-1; y >= vport->y + lines; y--)
memcpy(&screen.fbaddress[POINTPOS(vport->x,y)],
&screen.fbaddress[POINTPOS(vport->x,y - lines)],
screen.pixelbytes * vport->width);
draw_rectangle(vport, 0, 0, vport->width, lines,
vport->style.bg_color);
unsigned int x;
unsigned int y;
unsigned int copy_bytes;
uint8_t *sp;
uint8_t *dp;
uint8_t cbuf[4];
if ((y0 >= y1) || (x0 >= x1))
return;
screen.rgb_conv(cbuf, color);
sp = &screen.fb_addr[FB_POS(x0, y0)];
dp = sp;
/* Draw the first line. */
for (x = x0; x < x1; x++) {
memcpy(dp, cbuf, screen.pixelbytes);
dp += screen.pixelbytes;
}
}
 
/** Refresh given viewport from double buffer */
static void
refresh_viewport_db(viewport_t *vport)
{
unsigned int y, srcy, srcoff, dsty, dstx;
 
for (y = 0; y < vport->height; y++) {
srcy = (y + vport->dboffset) % vport->height;
srcoff = (vport->width * srcy) * screen.pixelbytes;
 
dstx = vport->x;
dsty = vport->y + y;
 
memcpy(&screen.fbaddress[POINTPOS(dstx,dsty)],
&vport->dbdata[srcoff], vport->width * screen.pixelbytes);
dp = sp + screen.scanline;
copy_bytes = (x1 - x0) * screen.pixelbytes;
/* Draw the remaining lines by copying. */
for (y = y0 + 1; y < y1; y++) {
memcpy(dp, sp, copy_bytes);
dp += screen.scanline;
}
}
 
/** Scroll viewport that has double buffering enabled */
static void
scroll_port_db(viewport_t *vport, int lines)
/** Redraw viewport.
*
* @param vport Viewport to redraw
*
*/
static void vport_redraw(viewport_t *vport)
{
++vport->paused;
if (lines > 0) {
draw_rectangle(vport, 0, 0, vport->width, lines,
vport->style.bg_color);
vport->dboffset += lines;
vport->dboffset %= vport->height;
} else if (lines < 0) {
lines = -lines;
draw_rectangle(vport, 0, vport->height-lines, vport->width,
lines, vport->style.bg_color);
 
if (vport->dboffset < lines)
vport->dboffset += vport->height;
vport->dboffset -= lines;
unsigned int col;
unsigned int row;
for (row = 0; row < vport->rows; row++) {
for (col = 0; col < vport->cols; col++) {
draw_vp_glyph(vport, false, col, row);
}
}
--vport->paused;
if (COL2X(vport->cols) < vport->width) {
draw_filled_rect(
vport->x + COL2X(vport->cols), vport->y,
vport->x + vport->width, vport->y + vport->height,
vport->attr.bg_color);
}
refresh_viewport_db(vport);
if (ROW2Y(vport->rows) < vport->height) {
draw_filled_rect(
vport->x, vport->y + ROW2Y(vport->rows),
vport->x + vport->width, vport->y + vport->height,
vport->attr.bg_color);
}
}
 
/** Scrolls viewport given number of lines */
static void
scroll_port(viewport_t *vport, int lines)
static void backbuf_clear(bb_cell_t *backbuf, size_t len, uint32_t fg_color,
uint32_t bg_color)
{
if (vport->dbdata)
scroll_port_db(vport, lines);
else
scroll_port_nodb(vport, lines);
size_t i;
for (i = 0; i < len; i++) {
backbuf[i].glyph = 0;
backbuf[i].fg_color = fg_color;
backbuf[i].bg_color = bg_color;
}
}
 
static void
invert_pixel(viewport_t *vport, unsigned int x, unsigned int y)
/** Clear viewport.
*
* @param vport Viewport to clear
*
*/
static void vport_clear(viewport_t *vport)
{
putpixel(vport, x, y, ~getpixel(vport, x, y));
backbuf_clear(vport->backbuf, vport->cols * vport->rows,
vport->attr.fg_color, vport->attr.bg_color);
vport_redraw(vport);
}
 
 
/***************************************************************/
/* Character-console functions */
 
/** Draw character at given position
/** Scroll viewport by the specified number of lines.
*
* @param vport Viewport where the character is printed
* @param sx Coordinates of top-left of the character
* @param sy Coordinates of top-left of the character
* @param style Color of the character
* @param transparent If false, print background color
* @param vport Viewport to scroll
* @param lines Number of lines to scroll
*
*/
static void
draw_glyph(viewport_t *vport,uint8_t glyph, unsigned int sx, unsigned int sy,
style_t style, int transparent)
static void vport_scroll(viewport_t *vport, int lines)
{
int i;
unsigned int col;
unsigned int row;
unsigned int x;
unsigned int y;
unsigned int glline;
 
for (y = 0; y < FONT_SCANLINES; y++) {
glline = fb_font[glyph * FONT_SCANLINES + y];
for (i = 0; i < 8; i++) {
if (glline & (1 << (7 - i)))
putpixel(vport, sx + i, sy + y, style.fg_color);
else if (!transparent)
putpixel(vport, sx + i, sy + y, style.bg_color);
uint32_t glyph;
uint32_t fg_color;
uint32_t bg_color;
bb_cell_t *bbp;
bb_cell_t *xbp;
/*
* Redraw.
*/
y = vport->y;
for (row = 0; row < vport->rows; row++) {
x = vport->x;
for (col = 0; col < vport->cols; col++) {
if (((int) row + lines >= 0) &&
((int) row + lines < (int) vport->rows)) {
xbp = &vport->backbuf[BB_POS(vport, col, row + lines)];
bbp = &vport->backbuf[BB_POS(vport, col, row)];
glyph = xbp->glyph;
fg_color = xbp->fg_color;
bg_color = xbp->bg_color;
if ((bbp->glyph == glyph)
&& (bbp->fg_color == xbp->fg_color)
&& (bbp->bg_color == xbp->bg_color)) {
x += FONT_WIDTH;
continue;
}
} else {
glyph = 0;
fg_color = vport->attr.fg_color;
bg_color = vport->attr.bg_color;
}
(*vport->dglyph)(x, y, false, screen.glyphs, glyph,
fg_color, bg_color);
x += FONT_WIDTH;
}
y += FONT_SCANLINES;
}
/*
* Scroll backbuffer.
*/
if (lines > 0) {
memmove(vport->backbuf, vport->backbuf + vport->cols * lines,
vport->cols * (vport->rows - lines) * sizeof(bb_cell_t));
backbuf_clear(&vport->backbuf[BB_POS(vport, 0, vport->rows - lines)],
vport->cols * lines, vport->attr.fg_color, vport->attr.bg_color);
} else {
memmove(vport->backbuf - vport->cols * lines, vport->backbuf,
vport->cols * (vport->rows + lines) * sizeof(bb_cell_t));
backbuf_clear(vport->backbuf, - vport->cols * lines,
vport->attr.fg_color, vport->attr.bg_color);
}
}
 
/** Invert character at given position */
static void
invert_char(viewport_t *vport,unsigned int row, unsigned int col)
/** Render glyphs
*
* Convert glyphs from device independent font
* description to current visual representation.
*
*/
static void render_glyphs(void)
{
unsigned int x;
unsigned int y;
 
for (x = 0; x < COL_WIDTH; x++)
for (y = 0; y < FONT_SCANLINES; y++)
invert_pixel(vport, col * COL_WIDTH + x, row *
FONT_SCANLINES + y);
unsigned int glyph;
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
unsigned int y;
for (y = 0; y < FONT_SCANLINES; y++) {
unsigned int x;
for (x = 0; x < FONT_WIDTH; x++) {
screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x))) ? true : false);
screen.mask_conv(&screen.glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes],
(fb_font[glyph][y] & (1 << (7 - x))) ? false : true);
}
}
}
}
 
/***************************************************************/
/* Stdout specific functions */
 
 
/** Create new viewport
*
* @return New viewport number
* @param x Origin of the viewport (x).
* @param y Origin of the viewport (y).
* @param width Width of the viewport.
* @param height Height of the viewport.
*
* @return New viewport number.
*
*/
static int
viewport_create(unsigned int x, unsigned int y,unsigned int width,
unsigned int height)
static int vport_create(unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
int i;
 
unsigned int i;
for (i = 0; i < MAX_VIEWPORTS; i++) {
if (!viewports[i].initialized)
break;
}
if (i == MAX_VIEWPORTS)
return ELIMIT;
 
unsigned int cols = width / FONT_WIDTH;
unsigned int rows = height / FONT_SCANLINES;
unsigned int bbsize = cols * rows * sizeof(bb_cell_t);
unsigned int word_size = sizeof(unsigned long);
bb_cell_t *backbuf = (bb_cell_t *) malloc(bbsize);
if (!backbuf)
return ENOMEM;
uint8_t *bgpixel = (uint8_t *) malloc(screen.pixelbytes);
if (!bgpixel) {
free(backbuf);
return ENOMEM;
}
backbuf_clear(backbuf, cols * rows, DEFAULT_FGCOLOR, DEFAULT_BGCOLOR);
memset(bgpixel, 0, screen.pixelbytes);
viewports[i].x = x;
viewports[i].y = y;
viewports[i].width = width;
viewports[i].height = height;
viewports[i].rows = height / FONT_SCANLINES;
viewports[i].cols = width / COL_WIDTH;
 
viewports[i].style.bg_color = DEFAULT_BGCOLOR;
viewports[i].style.fg_color = DEFAULT_FGCOLOR;
viewports[i].cols = cols;
viewports[i].rows = rows;
viewports[i].attr.bg_color = DEFAULT_BGCOLOR;
viewports[i].attr.fg_color = DEFAULT_FGCOLOR;
viewports[i].bgpixel = bgpixel;
/*
* Conditions necessary to select aligned version:
* - word size is divisible by pixelbytes
* - cell scanline size is divisible by word size
* - cell scanlines are word-aligned
*
*/
if (((word_size % screen.pixelbytes) == 0)
&& ((FONT_WIDTH * screen.pixelbytes) % word_size == 0)
&& ((x * screen.pixelbytes) % word_size == 0)
&& (screen.scanline % word_size == 0)) {
viewports[i].dglyph = draw_glyph_aligned;
} else {
viewports[i].dglyph = draw_glyph_fallback;
}
viewports[i].cur_col = 0;
viewports[i].cur_row = 0;
viewports[i].cursor_active = 0;
 
viewports[i].initialized = 1;
 
viewports[i].cursor_active = false;
viewports[i].cursor_shown = false;
viewports[i].bbsize = bbsize;
viewports[i].backbuf = backbuf;
viewports[i].initialized = true;
screen.rgb_conv(viewports[i].bgpixel, viewports[i].attr.bg_color);
return i;
}
 
 
/** Initialize framebuffer as a chardev output device
*
* @param addr Address of theframebuffer
* @param xres Screen width in pixels
* @param yres Screen height in pixels
* @param visual Bits per pixel (8, 16, 24, 32)
* @param scan Bytes per one scanline
* @param invert_colors Inverted colors.
* @param addr Address of the framebuffer
* @param xres Screen width in pixels
* @param yres Screen height in pixels
* @param visual Bits per pixel (8, 16, 24, 32)
* @param scan Bytes per one scanline
*
*/
static bool
screen_init(void *addr, unsigned int xres, unsigned int yres,
unsigned int scan, unsigned int visual, bool invert_colors)
static bool screen_init(void *addr, unsigned int xres, unsigned int yres,
unsigned int scan, unsigned int visual)
{
switch (visual) {
case VISUAL_INDIRECT_8:
screen.rgb2scr = rgb_byte8;
screen.scr2rgb = byte8_rgb;
screen.rgb_conv = rgb_323;
screen.mask_conv = mask_323;
screen.pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
screen.rgb2scr = rgb_byte555;
screen.scr2rgb = byte555_rgb;
screen.rgb_conv = rgb_555;
screen.mask_conv = mask_555;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
screen.rgb2scr = rgb_byte565;
screen.scr2rgb = byte565_rgb;
screen.rgb_conv = rgb_565;
screen.mask_conv = mask_565;
screen.pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
screen.rgb2scr = rgb_byte888;
screen.scr2rgb = byte888_rgb;
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 3;
break;
case VISUAL_BGR_8_8_8:
screen.rgb_conv = bgr_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
screen.rgb2scr = rgb_byte888;
screen.scr2rgb = byte888_rgb;
screen.rgb_conv = rgb_888;
screen.mask_conv = mask_888;
screen.pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
screen.rgb2scr = rgb_byte0888;
screen.scr2rgb = byte0888_rgb;
screen.rgb_conv = rgb_0888;
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
case VISUAL_BGR_0_8_8_8:
screen.rgb2scr = bgr_byte0888;
screen.scr2rgb = byte0888_bgr;
screen.rgb_conv = bgr_0888;
screen.mask_conv = mask_0888;
screen.pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
screen.rgb2scr = bgr_byte8880;
screen.scr2rgb = byte8880_bgr;
screen.pixelbytes = 4;
break;
default:
return false;
}
 
screen.fbaddress = (unsigned char *) addr;
screen.fb_addr = (unsigned char *) addr;
screen.xres = xres;
screen.yres = yres;
screen.scanline = scan;
screen.invert_colors = invert_colors;
screen.glyphscanline = FONT_WIDTH * screen.pixelbytes;
screen.glyphbytes = screen.glyphscanline * FONT_SCANLINES;
size_t glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;
uint8_t *glyphs = (uint8_t *) malloc(glyphsize);
if (!glyphs)
return false;
memset(glyphs, 0, glyphsize);
screen.glyphs = glyphs;
render_glyphs();
/* Create first viewport */
viewport_create(0, 0, xres, yres);
vport_create(0, 0, xres, yres);
return true;
}
 
/** Hide cursor if it is shown */
static void
cursor_hide(viewport_t *vport)
 
/** Draw a glyph, takes advantage of alignment.
*
* This version can only be used if the following conditions are met:
*
* - word size is divisible by pixelbytes
* - cell scanline size is divisible by word size
* - cell scanlines are word-aligned
*
* It makes use of the pre-rendered mask to process (possibly) several
* pixels at once (word size / pixelbytes pixels at a time are processed)
* making it very fast. Most notably this version is not applicable at 24 bits
* per pixel.
*
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
*
*/
static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color)
{
if (vport->cursor_active && vport->cursor_shown) {
invert_char(vport, vport->cur_row, vport->cur_col);
vport->cursor_shown = 0;
unsigned int i;
unsigned int yd;
unsigned long fg_buf;
unsigned long bg_buf;
unsigned long mask;
/*
* Prepare a pair of words, one filled with foreground-color
* pattern and the other filled with background-color pattern.
*/
for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) {
screen.rgb_conv(&((uint8_t *) &fg_buf)[i * screen.pixelbytes],
fg_color);
screen.rgb_conv(&((uint8_t *) &bg_buf)[i * screen.pixelbytes],
bg_color);
}
/* Pointer to the current position in the mask. */
unsigned long *maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)];
/* Pointer to the current position on the screen. */
unsigned long *dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)];
/* Width of the character cell in words. */
unsigned int ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long);
/* Offset to add when moving to another screen scanline. */
unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
/*
* Now process the cell scanline, combining foreground
* and background color patters using the pre-rendered mask.
*/
for (i = 0; i < ww; i++) {
mask = *maskp++;
*dp++ = (fg_buf & mask) | (bg_buf & ~mask);
}
/* Move to the beginning of the next scanline of the cell. */
dp = (unsigned long *) ((uint8_t *) dp + d_add);
}
}
 
/** Show cursor if cursor showing is enabled */
static void
cursor_print(viewport_t *vport)
/** Draw a glyph, fallback version.
*
* This version does not make use of the pre-rendered mask, it uses
* the font bitmap directly. It works always, but it is slower.
*
* @param x x coordinate of top-left corner on screen.
* @param y y coordinate of top-left corner on screen.
* @param cursor Draw glyph with cursor
* @param glyphs Pointer to font bitmap.
* @param glyph Code of the glyph to draw.
* @param fg_color Foreground color.
* @param bg_color Backgroudn color.
*
*/
void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color)
{
unsigned int i;
unsigned int j;
unsigned int yd;
uint8_t fg_buf[4];
uint8_t bg_buf[4];
uint8_t *sp;
uint8_t b;
/* Pre-render 1x the foreground and background color pixels. */
if (cursor) {
screen.rgb_conv(fg_buf, bg_color);
screen.rgb_conv(bg_buf, fg_color);
} else {
screen.rgb_conv(fg_buf, fg_color);
screen.rgb_conv(bg_buf, bg_color);
}
/* Pointer to the current position on the screen. */
uint8_t *dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)];
/* Offset to add when moving to another screen scanline. */
unsigned int d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
/* Byte containing bits of the glyph scanline. */
b = fb_font[glyph][yd];
for (i = 0; i < FONT_WIDTH; i++) {
/* Choose color based on the current bit. */
sp = (b & 0x80) ? fg_buf : bg_buf;
/* Copy the pixel. */
for (j = 0; j < screen.pixelbytes; j++) {
*dp++ = *sp++;
}
/* Move to the next bit. */
b = b << 1;
}
/* Move to the beginning of the next scanline of the cell. */
dp += d_add;
}
}
 
/** Draw glyph at specified position in viewport.
*
* @param vport Viewport identification
* @param cursor Draw glyph with cursor
* @param col Screen position relative to viewport
* @param row Screen position relative to viewport
*
*/
static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col,
unsigned int row)
{
unsigned int x = vport->x + COL2X(col);
unsigned int y = vport->y + ROW2Y(row);
uint32_t glyph = vport->backbuf[BB_POS(vport, col, row)].glyph;
uint32_t fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color;
uint32_t bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color;
(*vport->dglyph)(x, y, cursor, screen.glyphs, glyph,
fg_color, bg_color);
}
 
/** Hide cursor if it is shown
*
*/
static void cursor_hide(viewport_t *vport)
{
if ((vport->cursor_active) && (vport->cursor_shown)) {
draw_vp_glyph(vport, false, vport->cur_col, vport->cur_row);
vport->cursor_shown = false;
}
}
 
 
/** Show cursor if cursor showing is enabled
*
*/
static void cursor_show(viewport_t *vport)
{
/* Do not check for cursor_shown */
if (vport->cursor_active) {
invert_char(vport, vport->cur_row, vport->cur_col);
vport->cursor_shown = 1;
draw_vp_glyph(vport, true, vport->cur_col, vport->cur_row);
vport->cursor_shown = true;
}
}
 
/** Invert cursor, if it is enabled */
static void
cursor_blink(viewport_t *vport)
 
/** Invert cursor, if it is enabled
*
*/
static void cursor_blink(viewport_t *vport)
{
if (vport->cursor_shown)
cursor_hide(vport);
else
cursor_print(vport);
cursor_show(vport);
}
 
/** Draw character at given position relative to viewport
*
* @param vport Viewport identification
* @param c Character to print
* @param row Screen position relative to viewport
* @param col Screen position relative to viewport
* @param transparent If false, print background color with character
 
/** Draw character at given position relative to viewport
*
* @param vport Viewport identification
* @param c Character to draw
* @param col Screen position relative to viewport
* @param row Screen position relative to viewport
*
*/
static void
draw_char(viewport_t *vport, char c, unsigned int row, unsigned int col,
style_t style, int transparent)
static void draw_char(viewport_t *vport, wchar_t c, unsigned int col, unsigned int row)
{
/* Optimize - do not hide cursor if we are going to overwrite it */
if (vport->cursor_active && vport->cursor_shown &&
(vport->cur_col != col || vport->cur_row != row))
invert_char(vport, vport->cur_row, vport->cur_col);
bb_cell_t *bbp;
draw_glyph(vport, c, col * COL_WIDTH, row * FONT_SCANLINES, style,
transparent);
 
/* Do not hide cursor if we are going to overwrite it */
if ((vport->cursor_active) && (vport->cursor_shown) &&
((vport->cur_col != col) || (vport->cur_row != row)))
cursor_hide(vport);
bbp = &vport->backbuf[BB_POS(vport, col, row)];
bbp->glyph = fb_font_glyph(c);
bbp->fg_color = vport->attr.fg_color;
bbp->bg_color = vport->attr.bg_color;
draw_vp_glyph(vport, false, col, row);
vport->cur_col = col;
vport->cur_row = row;
 
vport->cur_col++;
if (vport->cur_col >= vport->cols) {
vport->cur_col = 0;
657,65 → 917,97
if (vport->cur_row >= vport->rows)
vport->cur_row--;
}
cursor_print(vport);
cursor_show(vport);
}
 
/** Draw text data to viewport
/** Draw text data to viewport.
*
* @param vport Viewport id
* @param data Text data fitting exactly into viewport
* @param data Text data.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
*
*/
static void
draw_text_data(viewport_t *vport, keyfield_t *data)
static void draw_text_data(viewport_t *vport, keyfield_t *data, unsigned int x,
unsigned int y, unsigned int w, unsigned int h)
{
int i;
int col,row;
 
clear_port(vport);
for (i = 0; i < vport->cols * vport->rows; i++) {
if (data[i].character == ' ' && style_same(data[i].style,
vport->style))
continue;
col = i % vport->cols;
row = i / vport->cols;
draw_glyph(vport, data[i].character, col * COL_WIDTH, row *
FONT_SCANLINES, data[i].style, style_same(data[i].style,
vport->style));
unsigned int i;
unsigned int j;
bb_cell_t *bbp;
attrs_t *a;
attr_rgb_t rgb;
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
unsigned int col = x + i;
unsigned int row = y + j;
bbp = &vport->backbuf[BB_POS(vport, col, row)];
a = &data[j * w + i].attrs;
rgb_from_attr(&rgb, a);
bbp->glyph = fb_font_glyph(data[j * w + i].character);
bbp->fg_color = rgb.fg_color;
bbp->bg_color = rgb.bg_color;
draw_vp_glyph(vport, false, col, row);
}
}
cursor_print(vport);
cursor_show(vport);
}
 
/** Return first free pixmap */
static int
find_free_pixmap(void)
 
static void putpixel_pixmap(void *data, unsigned int x, unsigned int y, uint32_t color)
{
int i;
int pm = *((int *) data);
pixmap_t *pmap = &pixmaps[pm];
unsigned int pos = (y * pmap->width + x) * screen.pixelbytes;
for (i = 0;i < MAX_PIXMAPS;i++)
screen.rgb_conv(&pmap->data[pos], color);
}
 
 
static void putpixel(void *data, unsigned int x, unsigned int y, uint32_t color)
{
viewport_t *vport = (viewport_t *) data;
unsigned int dx = vport->x + x;
unsigned int dy = vport->y + y;
screen.rgb_conv(&screen.fb_addr[FB_POS(dx, dy)], color);
}
 
 
/** Return first free pixmap
*
*/
static int find_free_pixmap(void)
{
unsigned int i;
for (i = 0; i < MAX_PIXMAPS; i++)
if (!pixmaps[i].data)
return i;
return -1;
}
 
static void
putpixel_pixmap(int pm, unsigned int x, unsigned int y, int color)
{
pixmap_t *pmap = &pixmaps[pm];
int pos = (y * pmap->width + x) * screen.pixelbytes;
 
(*screen.rgb2scr)(&pmap->data[pos],COLOR(color));
}
 
/** Create a new pixmap and return appropriate ID */
static int
shm2pixmap(unsigned char *shm, size_t size)
/** Create a new pixmap and return appropriate ID
*
*/
static int shm2pixmap(unsigned char *shm, size_t size)
{
int pm;
pixmap_t *pmap;
 
pm = find_free_pixmap();
if (pm == -1)
return ELIMIT;
pmap = &pixmaps[pm];
if (ppm_get_data(shm, size, &pmap->width, &pmap->height))
724,19 → 1016,19
pmap->data = malloc(pmap->width * pmap->height * screen.pixelbytes);
if (!pmap->data)
return ENOMEM;
 
ppm_draw(shm, size, 0, 0, pmap->width, pmap->height,
(putpixel_cb_t)putpixel_pixmap, (void *)pm);
 
ppm_draw(shm, size, 0, 0, pmap->width, pmap->height, putpixel_pixmap, (void *) &pm);
return pm;
}
 
 
/** Handle shared memory communication calls
*
* Protocol for drawing pixmaps:
* - FB_PREPARE_SHM(client shm identification)
* - IPC_M_AS_AREA_SEND
* - FB_DRAW_PPM(startx,starty)
* - FB_DRAW_PPM(startx, starty)
* - FB_DROP_SHM
*
* Protocol for text drawing
744,28 → 1036,32
* - FB_DRAW_TEXT_DATA
*
* @param callid Callid of the current call
* @param call Current call data
* @param vp Active viewport
* @return 0 if the call was not handled byt this function, 1 otherwise
* @param call Current call data
* @param vp Active viewport
*
* note: this function is not threads safe, you would have
* to redefine static variables with __thread
* @return false if the call was not handled byt this function, true otherwise
*
* Note: this function is not thread-safe, you would have
* to redefine static variables with fibril_local.
*
*/
static int
shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
static bool shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
{
static keyfield_t *interbuffer = NULL;
static size_t intersize = 0;
 
static unsigned char *shm = NULL;
static ipcarg_t shm_id = 0;
static size_t shm_size;
 
int handled = 1;
int retval = 0;
bool handled = true;
int retval = EOK;
viewport_t *vport = &viewports[vp];
unsigned int x, y;
 
unsigned int x;
unsigned int y;
unsigned int w;
unsigned int h;
switch (IPC_GET_METHOD(*call)) {
case IPC_M_SHARE_OUT:
/* We accept one area for data interchange */
772,19 → 1068,21
if (IPC_GET_ARG1(*call) == shm_id) {
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
shm_size = IPC_GET_ARG2(*call);
if (!ipc_answer_1(callid, EOK, (sysarg_t) dest))
shm = dest;
else
if (ipc_answer_1(callid, EOK, (sysarg_t) dest)) {
shm_id = 0;
return false;
}
shm = dest;
if (shm[0] != 'P')
while (1)
;
return 1;
return false;
return true;
} else {
intersize = IPC_GET_ARG2(*call);
receive_comm_area(callid, call, (void *) &interbuffer);
}
return 1;
return true;
case FB_PREPARE_SHM:
if (shm_id)
retval = EBUSY;
799,7 → 1097,7
}
shm_id = 0;
break;
 
case FB_SHM2PIXMAP:
if (!shm) {
retval = EINVAL;
814,29 → 1112,36
}
x = IPC_GET_ARG1(*call);
y = IPC_GET_ARG2(*call);
if (x > vport->width || y > vport->height) {
if ((x > vport->width) || (y > vport->height)) {
retval = EINVAL;
break;
}
ppm_draw(shm, shm_size, IPC_GET_ARG1(*call),
IPC_GET_ARG2(*call), vport->width - x, vport->height - y,
(putpixel_cb_t)putpixel, vport);
IPC_GET_ARG2(*call), vport->width - x, vport->height - y, putpixel, (void *) vport);
break;
case FB_DRAW_TEXT_DATA:
x = IPC_GET_ARG1(*call);
y = IPC_GET_ARG2(*call);
w = IPC_GET_ARG3(*call);
h = IPC_GET_ARG4(*call);
if (!interbuffer) {
retval = EINVAL;
break;
}
if (intersize < vport->cols * vport->rows *
sizeof(*interbuffer)) {
if (x + w > vport->cols || y + h > vport->rows) {
retval = EINVAL;
break;
}
draw_text_data(vport, interbuffer);
if (intersize < w * h * sizeof(*interbuffer)) {
retval = EINVAL;
break;
}
draw_text_data(vport, interbuffer, x, y, w, h);
break;
default:
handled = 0;
handled = false;
}
if (handled)
844,41 → 1149,39
return handled;
}
 
static void
copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
 
static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
{
int y;
int tmp, srcrowsize;
int realwidth, realheight, realrowsize;
int width = vport->width;
int height = vport->height;
 
unsigned int width = vport->width;
unsigned int height = vport->height;
if (width + vport->x > screen.xres)
width = screen.xres - vport->x;
if (height + vport->y > screen.yres)
height = screen.yres - vport->y;
realwidth = pmap->width <= width ? pmap->width : width;
realheight = pmap->height <= height ? pmap->height : height;
 
srcrowsize = vport->width * screen.pixelbytes;
realrowsize = realwidth * screen.pixelbytes;
unsigned int realwidth = pmap->width <= width ? pmap->width : width;
unsigned int realheight = pmap->height <= height ? pmap->height : height;
unsigned int srcrowsize = vport->width * screen.pixelbytes;
unsigned int realrowsize = realwidth * screen.pixelbytes;
unsigned int y;
for (y = 0; y < realheight; y++) {
tmp = (vport->y + y) * screen.scanline +
vport->x * screen.pixelbytes;
memcpy(pmap->data + srcrowsize * y, screen.fbaddress + tmp,
realrowsize);
unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;
memcpy(pmap->data + srcrowsize * y, screen.fb_addr + tmp, realrowsize);
}
}
 
/** Save viewport to pixmap */
static int
save_vp_to_pixmap(viewport_t *vport)
 
/** Save viewport to pixmap
*
*/
static int save_vp_to_pixmap(viewport_t *vport)
{
int pm;
pixmap_t *pmap;
 
pm = find_free_pixmap();
if (pm == -1)
return ELIMIT;
887,58 → 1190,60
pmap->data = malloc(screen.pixelbytes * vport->width * vport->height);
if (!pmap->data)
return ENOMEM;
 
pmap->width = vport->width;
pmap->height = vport->height;
 
copy_vp_to_pixmap(vport, pmap);
return pm;
}
 
 
/** Draw pixmap on screen
*
* @param vp Viewport to draw on
* @param pm Pixmap identifier
*
*/
static int draw_pixmap(int vp, int pm)
{
pixmap_t *pmap = &pixmaps[pm];
viewport_t *vport = &viewports[vp];
int y;
int tmp, srcrowsize;
int realwidth, realheight, realrowsize;
int width = vport->width;
int height = vport->height;
 
unsigned int width = vport->width;
unsigned int height = vport->height;
if (width + vport->x > screen.xres)
width = screen.xres - vport->x;
if (height + vport->y > screen.yres)
height = screen.yres - vport->y;
 
if (!pmap->data)
return EINVAL;
 
realwidth = pmap->width <= width ? pmap->width : width;
realheight = pmap->height <= height ? pmap->height : height;
 
srcrowsize = vport->width * screen.pixelbytes;
realrowsize = realwidth * screen.pixelbytes;
 
unsigned int realwidth = pmap->width <= width ? pmap->width : width;
unsigned int realheight = pmap->height <= height ? pmap->height : height;
unsigned int srcrowsize = vport->width * screen.pixelbytes;
unsigned int realrowsize = realwidth * screen.pixelbytes;
unsigned int y;
for (y = 0; y < realheight; y++) {
tmp = (vport->y + y) * screen.scanline +
vport->x * screen.pixelbytes;
memcpy(screen.fbaddress + tmp, pmap->data + y * srcrowsize,
realrowsize);
unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;
memcpy(screen.fb_addr + tmp, pmap->data + y * srcrowsize, realrowsize);
}
return 0;
return EOK;
}
 
/** Tick animation one step forward */
static void
anims_tick(void)
 
/** Tick animation one step forward
*
*/
static void anims_tick(void)
{
int i;
unsigned int i;
static int counts = 0;
/* Limit redrawing */
945,39 → 1250,38
counts = (counts + 1) % 8;
if (counts)
return;
 
for (i = 0; i < MAX_ANIMATIONS; i++) {
if (!animations[i].animlen || !animations[i].initialized ||
!animations[i].enabled)
if ((!animations[i].animlen) || (!animations[i].initialized) ||
(!animations[i].enabled))
continue;
draw_pixmap(animations[i].vp,
animations[i].pixmaps[animations[i].pos]);
animations[i].pos = (animations[i].pos + 1) %
animations[i].animlen;
draw_pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]);
animations[i].pos = (animations[i].pos + 1) % animations[i].animlen;
}
}
 
 
static int pointer_x, pointer_y;
static int pointer_shown, pointer_enabled;
static unsigned int pointer_x;
static unsigned int pointer_y;
static bool pointer_shown, pointer_enabled;
static int pointer_vport = -1;
static int pointer_pixmap = -1;
 
static void
mouse_show(void)
 
static void mouse_show(void)
{
int i, j;
int visibility;
int color;
int bytepos;
 
if (pointer_shown || !pointer_enabled)
if ((pointer_shown) || (!pointer_enabled))
return;
 
/* Save image under the cursor */
/* Save image under the pointer. */
if (pointer_vport == -1) {
pointer_vport = viewport_create(pointer_x, pointer_y,
pointer_width, pointer_height);
pointer_vport = vport_create(pointer_x, pointer_y, pointer_width, pointer_height);
if (pointer_vport < 0)
return;
} else {
984,14 → 1288,13
viewports[pointer_vport].x = pointer_x;
viewports[pointer_vport].y = pointer_y;
}
 
if (pointer_pixmap == -1)
pointer_pixmap = save_vp_to_pixmap(&viewports[pointer_vport]);
else
copy_vp_to_pixmap(&viewports[pointer_vport],
&pixmaps[pointer_pixmap]);
 
/* Draw cursor */
copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);
/* Draw mouse pointer. */
for (i = 0; i < pointer_height; i++)
for (j = 0; j < pointer_width; j++) {
bytepos = i * ((pointer_width - 1) / 8 + 1) + j / 8;
1009,10 → 1312,10
pointer_shown = 1;
}
 
static void
mouse_hide(void)
 
static void mouse_hide(void)
{
/* Restore image under the cursor */
/* Restore image under the pointer. */
if (pointer_shown) {
draw_pixmap(pointer_vport, pointer_pixmap);
pointer_shown = 0;
1019,8 → 1322,8
}
}
 
static void
mouse_move(unsigned int x, unsigned int y)
 
static void mouse_move(unsigned int x, unsigned int y)
{
mouse_hide();
pointer_x = x;
1028,14 → 1331,14
mouse_show();
}
 
static int
anim_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
 
static int anim_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
{
int handled = 1;
int retval = 0;
int i,nvp;
bool handled = true;
int retval = EOK;
int i, nvp;
int newval;
 
switch (IPC_GET_METHOD(*call)) {
case FB_ANIM_CREATE:
nvp = IPC_GET_ARG1(*call);
1125,14 → 1428,16
return handled;
}
 
/** Handler for messages concerning pixmap handling */
static int
pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
 
/** Handler for messages concerning pixmap handling
*
*/
static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
{
int handled = 1;
int retval = 0;
int i,nvp;
 
bool handled = true;
int retval = EOK;
int i, nvp;
switch (IPC_GET_METHOD(*call)) {
case FB_VP_DRAW_PIXMAP:
nvp = IPC_GET_ARG1(*call);
1170,7 → 1475,7
default:
handled = 0;
}
 
if (handled)
ipc_answer_0(callid, retval);
return handled;
1177,35 → 1482,99
}
 
static int rgb_from_style(attr_rgb_t *rgb, int style)
{
switch (style) {
case STYLE_NORMAL:
rgb->fg_color = color_table[COLOR_BLACK];
rgb->bg_color = color_table[COLOR_WHITE];
break;
case STYLE_EMPHASIS:
rgb->fg_color = color_table[COLOR_RED];
rgb->bg_color = color_table[COLOR_WHITE];
break;
default:
return EINVAL;
}
 
return EOK;
}
 
static int rgb_from_idx(attr_rgb_t *rgb, ipcarg_t fg_color,
ipcarg_t bg_color, ipcarg_t flags)
{
fg_color = (fg_color & 7) | ((flags & CATTR_BRIGHT) ? 8 : 0);
bg_color = (bg_color & 7) | ((flags & CATTR_BRIGHT) ? 8 : 0);
 
rgb->fg_color = color_table[fg_color];
rgb->bg_color = color_table[bg_color];
 
return EOK;
}
 
static int rgb_from_attr(attr_rgb_t *rgb, const attrs_t *a)
{
int rc;
 
switch (a->t) {
case at_style:
rc = rgb_from_style(rgb, a->a.s.style);
break;
case at_idx:
rc = rgb_from_idx(rgb, a->a.i.fg_color,
a->a.i.bg_color, a->a.i.flags);
break;
case at_rgb:
*rgb = a->a.r;
rc = EOK;
break;
}
 
return rc;
}
 
static int fb_set_style(viewport_t *vport, ipcarg_t style)
{
return rgb_from_style(&vport->attr, (int) style);
}
 
static int fb_set_color(viewport_t *vport, ipcarg_t fg_color,
ipcarg_t bg_color, ipcarg_t flags)
{
return rgb_from_idx(&vport->attr, fg_color, bg_color, flags);
}
 
/** Function for handling connections to FB
*
*/
static void
fb_client_connection(ipc_callid_t iid, ipc_call_t *icall)
static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
int retval;
int i;
unsigned int row,col;
char c;
 
int vp = 0;
viewport_t *vport = &viewports[0];
 
unsigned int vp = 0;
viewport_t *vport = &viewports[vp];
if (client_connected) {
ipc_answer_0(iid, ELIMIT);
return;
}
client_connected = 1;
ipc_answer_0(iid, EOK); /* Accept connection */
 
while (1) {
if (vport->cursor_active || anims_enabled)
/* Accept connection */
client_connected = true;
ipc_answer_0(iid, EOK);
while (true) {
ipc_callid_t callid;
ipc_call_t call;
int retval;
unsigned int i;
int scroll;
wchar_t ch;
unsigned int col, row;
if ((vport->cursor_active) || (anims_enabled))
callid = async_get_call_timeout(&call, 250000);
else
callid = async_get_call(&call);
 
mouse_hide();
if (!callid) {
cursor_blink(vport);
1213,105 → 1582,92
mouse_show();
continue;
}
if (shm_handle(callid, &call, vp))
continue;
if (pixmap_handle(callid, &call, vp))
continue;
if (anim_handle(callid, &call, vp))
continue;
 
switch (IPC_GET_METHOD(call)) {
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
client_connected = 0;
/* cleanup other viewports */
client_connected = false;
/* Cleanup other viewports */
for (i = 1; i < MAX_VIEWPORTS; i++)
vport->initialized = 0;
return; /* Exit thread */
 
vport->initialized = false;
/* Exit thread */
return;
case FB_PUTCHAR:
case FB_TRANS_PUTCHAR:
c = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
col = IPC_GET_ARG3(call);
if (row >= vport->rows || col >= vport->cols) {
ch = IPC_GET_ARG1(call);
col = IPC_GET_ARG2(call);
row = IPC_GET_ARG3(call);
if ((col >= vport->cols) || (row >= vport->rows)) {
retval = EINVAL;
break;
}
ipc_answer_0(callid, EOK);
 
draw_char(vport, c, row, col, vport->style,
IPC_GET_METHOD(call) == FB_TRANS_PUTCHAR);
continue; /* msg already answered */
draw_char(vport, ch, col, row);
/* Message already answered */
continue;
case FB_CLEAR:
clear_port(vport);
cursor_print(vport);
retval = 0;
vport_clear(vport);
cursor_show(vport);
retval = EOK;
break;
case FB_CURSOR_GOTO:
row = IPC_GET_ARG1(call);
col = IPC_GET_ARG2(call);
if (row >= vport->rows || col >= vport->cols) {
case FB_CURSOR_GOTO:
col = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
if ((col >= vport->cols) || (row >= vport->rows)) {
retval = EINVAL;
break;
}
retval = 0;
retval = EOK;
cursor_hide(vport);
vport->cur_col = col;
vport->cur_row = row;
cursor_print(vport);
break;
cursor_show(vport);
break;
case FB_CURSOR_VISIBILITY:
cursor_hide(vport);
vport->cursor_active = IPC_GET_ARG1(call);
cursor_print(vport);
retval = 0;
cursor_show(vport);
retval = EOK;
break;
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, vport->rows, vport->cols);
ipc_answer_2(callid, EOK, vport->cols, vport->rows);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, FB_CCAP_RGB);
continue;
case FB_SCROLL:
i = IPC_GET_ARG1(call);
if (i > vport->rows || i < (- (int)vport->rows)) {
scroll = IPC_GET_ARG1(call);
if ((scroll > (int) vport->rows) || (scroll < (-(int) vport->rows))) {
retval = EINVAL;
break;
}
cursor_hide(vport);
scroll_port(vport, i*FONT_SCANLINES);
cursor_print(vport);
retval = 0;
vport_scroll(vport, scroll);
cursor_show(vport);
retval = EOK;
break;
case FB_VIEWPORT_DB:
/* Enable double buffering */
i = IPC_GET_ARG1(call);
if (i == -1)
i = vp;
if (i < 0 || i >= MAX_VIEWPORTS) {
retval = EINVAL;
break;
}
if (!viewports[i].initialized ) {
retval = EADDRNOTAVAIL;
break;
}
viewports[i].dboffset = 0;
if (IPC_GET_ARG2(call) == 1 && !viewports[i].dbdata)
viewports[i].dbdata =
malloc(screen.pixelbytes *
viewports[i].width * viewports[i].height);
else if (IPC_GET_ARG2(call) == 0 &&
viewports[i].dbdata) {
free(viewports[i].dbdata);
viewports[i].dbdata = NULL;
}
retval = 0;
break;
case FB_VIEWPORT_SWITCH:
i = IPC_GET_ARG1(call);
if (i < 0 || i >= MAX_VIEWPORTS) {
if (i >= MAX_VIEWPORTS) {
retval = EINVAL;
break;
}
if (! viewports[i].initialized ) {
if (!viewports[i].initialized) {
retval = EADDRNOTAVAIL;
break;
}
1318,11 → 1674,11
cursor_hide(vport);
vp = i;
vport = &viewports[vp];
cursor_print(vport);
retval = 0;
cursor_show(vport);
retval = EOK;
break;
case FB_VIEWPORT_CREATE:
retval = viewport_create(IPC_GET_ARG1(call) >> 16,
retval = vport_create(IPC_GET_ARG1(call) >> 16,
IPC_GET_ARG1(call) & 0xffff,
IPC_GET_ARG2(call) >> 16,
IPC_GET_ARG2(call) & 0xffff);
1329,34 → 1685,45
break;
case FB_VIEWPORT_DELETE:
i = IPC_GET_ARG1(call);
if (i < 0 || i >= MAX_VIEWPORTS) {
if (i >= MAX_VIEWPORTS) {
retval = EINVAL;
break;
}
if (! viewports[i].initialized ) {
if (!viewports[i].initialized) {
retval = EADDRNOTAVAIL;
break;
}
viewports[i].initialized = 0;
if (viewports[i].dbdata) {
free(viewports[i].dbdata);
viewports[i].dbdata = NULL;
}
retval = 0;
viewports[i].initialized = false;
if (viewports[i].bgpixel)
free(viewports[i].bgpixel);
if (viewports[i].backbuf)
free(viewports[i].backbuf);
retval = EOK;
break;
case FB_SET_STYLE:
vport->style.fg_color = IPC_GET_ARG1(call);
vport->style.bg_color = IPC_GET_ARG2(call);
retval = 0;
retval = fb_set_style(vport, IPC_GET_ARG1(call));
break;
case FB_SET_COLOR:
retval = fb_set_color(vport, IPC_GET_ARG1(call),
IPC_GET_ARG2(call), IPC_GET_ARG3(call));
break;
case FB_SET_RGB_COLOR:
vport->attr.fg_color = IPC_GET_ARG1(call);
vport->attr.bg_color = IPC_GET_ARG2(call);
retval = EOK;
break;
case FB_GET_RESOLUTION:
ipc_answer_2(callid, EOK, screen.xres, screen.yres);
continue;
case FB_POINTER_MOVE:
pointer_enabled = 1;
pointer_enabled = true;
mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
retval = 0;
retval = EOK;
break;
case FB_SCREEN_YIELD:
case FB_SCREEN_RECLAIM:
retval = EOK;
break;
default:
retval = ENOENT;
}
1364,41 → 1731,33
}
}
 
/** Initialization of framebuffer */
int
fb_init(void)
/** Initialization of framebuffer
*
*/
int fb_init(void)
{
void *fb_ph_addr;
unsigned int fb_width;
unsigned int fb_height;
unsigned int fb_scanline;
unsigned int fb_visual;
bool fb_invert_colors;
void *fb_addr;
size_t asz;
 
async_set_client_connection(fb_client_connection);
 
fb_ph_addr = (void *) sysinfo_value("fb.address.physical");
fb_width = sysinfo_value("fb.width");
fb_height = sysinfo_value("fb.height");
fb_scanline = sysinfo_value("fb.scanline");
fb_visual = sysinfo_value("fb.visual");
fb_invert_colors = sysinfo_value("fb.invert-colors");
 
asz = fb_scanline * fb_height;
fb_addr = as_get_mappable_page(asz);
physmem_map(fb_ph_addr, fb_addr, ALIGN_UP(asz, PAGE_SIZE) >>
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
 
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual,
fb_invert_colors))
void *fb_ph_addr = (void *) sysinfo_value("fb.address.physical");
unsigned int fb_offset = sysinfo_value("fb.offset");
unsigned int fb_width = sysinfo_value("fb.width");
unsigned int fb_height = sysinfo_value("fb.height");
unsigned int fb_scanline = sysinfo_value("fb.scanline");
unsigned int fb_visual = sysinfo_value("fb.visual");
unsigned int fbsize = fb_scanline * fb_height;
void *fb_addr = as_get_mappable_page(fbsize);
if (physmem_map(fb_ph_addr + fb_offset, fb_addr,
ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual))
return 0;
return -1;
}
 
/**
/**
* @}
*/
/branches/arm/uspace/srv/fb/ega.c
49,6 → 49,9
#include <ipc/ns.h>
#include <ipc/services.h>
#include <libarch/ddi.h>
#include <io/style.h>
#include <io/color.h>
#include <sys/types.h>
 
#include "ega.h"
#include "../console/screenbuffer.h"
61,13 → 64,14
 
saved_screen saved_screens[MAX_SAVED_SCREENS];
 
#define EGA_IO_ADDRESS 0x3d4
#define EGA_IO_BASE ((ioport8_t *) 0x3d4)
#define EGA_IO_SIZE 2
 
#define NORMAL_COLOR 0x0f
#define INVERTED_COLOR 0xf0
int ega_normal_color = 0x0f;
int ega_inverted_color = 0xf0;
 
#define EGA_STYLE(fg,bg) ((fg) > (bg) ? NORMAL_COLOR : INVERTED_COLOR)
#define NORMAL_COLOR ega_normal_color
#define INVERTED_COLOR ega_inverted_color
 
/* Allow only 1 connection */
static int client_connected = 0;
74,13 → 78,16
 
static unsigned int scr_width;
static unsigned int scr_height;
static char *scr_addr;
static uint8_t *scr_addr;
 
static unsigned int style = NORMAL_COLOR;
static unsigned int style;
 
static unsigned attr_to_ega_style(const attrs_t *a);
static uint8_t ega_glyph(wchar_t ch);
 
static void clrscr(void)
{
int i;
unsigned i;
for (i = 0; i < scr_width * scr_height; i++) {
scr_addr[i * 2] = ' ';
88,16 → 95,16
}
}
 
static void cursor_goto(unsigned int row, unsigned int col)
static void cursor_goto(unsigned int col, unsigned int row)
{
int ega_cursor;
 
ega_cursor = col + scr_width * row;
outb(EGA_IO_ADDRESS, 0xe);
outb(EGA_IO_ADDRESS + 1, (ega_cursor >> 8) & 0xff);
outb(EGA_IO_ADDRESS, 0xf);
outb(EGA_IO_ADDRESS + 1, ega_cursor & 0xff);
pio_write_8(EGA_IO_BASE, 0xe);
pio_write_8(EGA_IO_BASE + 1, (ega_cursor >> 8) & 0xff);
pio_write_8(EGA_IO_BASE, 0xf);
pio_write_8(EGA_IO_BASE + 1, ega_cursor & 0xff);
}
 
static void cursor_disable(void)
104,10 → 111,10
{
uint8_t stat;
 
outb(EGA_IO_ADDRESS, 0xa);
stat=inb(EGA_IO_ADDRESS + 1);
outb(EGA_IO_ADDRESS, 0xa);
outb(EGA_IO_ADDRESS + 1, stat | (1 << 5));
pio_write_8(EGA_IO_BASE, 0xa);
stat = pio_read_8(EGA_IO_BASE + 1);
pio_write_8(EGA_IO_BASE, 0xa);
pio_write_8(EGA_IO_BASE + 1, stat | (1 << 5));
}
 
static void cursor_enable(void)
114,23 → 121,24
{
uint8_t stat;
 
outb(EGA_IO_ADDRESS, 0xa);
stat=inb(EGA_IO_ADDRESS + 1);
outb(EGA_IO_ADDRESS, 0xa);
outb(EGA_IO_ADDRESS + 1, stat & (~(1 << 5)));
pio_write_8(EGA_IO_BASE, 0xa);
stat = pio_read_8(EGA_IO_BASE + 1);
pio_write_8(EGA_IO_BASE, 0xa);
pio_write_8(EGA_IO_BASE + 1, stat & (~(1 << 5)));
}
 
static void scroll(int rows)
{
int i;
unsigned i;
 
if (rows > 0) {
memcpy(scr_addr, ((char *) scr_addr) + rows * scr_width * 2,
memmove(scr_addr, ((char *) scr_addr) + rows * scr_width * 2,
scr_width * scr_height * 2 - rows * scr_width * 2);
for (i = 0; i < rows * scr_width; i++)
(((short *) scr_addr) + scr_width * scr_height - rows *
scr_width)[i] = ((style << 8) + ' ');
} else if (rows < 0) {
memcpy(((char *)scr_addr) - rows * scr_width * 2, scr_addr,
memmove(((char *)scr_addr) - rows * scr_width * 2, scr_addr,
scr_width * scr_height * 2 + rows * scr_width * 2);
for (i = 0; i < -rows * scr_width; i++)
((short *)scr_addr)[i] = ((style << 8 ) + ' ');
137,22 → 145,38
}
}
 
static void printchar(char c, unsigned int row, unsigned int col)
static void printchar(wchar_t c, unsigned int col, unsigned int row)
{
scr_addr[(row * scr_width + col) * 2] = c;
scr_addr[(row * scr_width + col) * 2] = ega_glyph(c);
scr_addr[(row * scr_width + col) * 2 + 1] = style;
cursor_goto(row, col + 1);
cursor_goto(col + 1, row);
}
 
static void draw_text_data(keyfield_t *data)
/** Draw text data to viewport.
*
* @param vport Viewport id
* @param data Text data.
* @param x Leftmost column of the area.
* @param y Topmost row of the area.
* @param w Number of rows.
* @param h Number of columns.
*/
static void draw_text_data(keyfield_t *data, unsigned int x,
unsigned int y, unsigned int w, unsigned int h)
{
int i;
unsigned int i, j;
keyfield_t *field;
uint8_t *dp;
 
for (i = 0; i < scr_width * scr_height; i++) {
scr_addr[i * 2] = data[i].character;
scr_addr[i * 2 + 1] = EGA_STYLE(data[i].style.fg_color,
data[i].style.bg_color);
for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
field = &data[j * w + i];
dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))];
 
dp[0] = ega_glyph(field->character);
dp[1] = attr_to_ega_style(&field->attrs);
}
}
}
 
181,15 → 205,72
return i;
}
 
static int style_to_ega_style(int style)
{
unsigned int ega_style;
 
switch (style) {
case STYLE_NORMAL:
ega_style = INVERTED_COLOR;
break;
case STYLE_EMPHASIS:
ega_style = INVERTED_COLOR | 4;
break;
default:
return INVERTED_COLOR;
}
 
return ega_style;
}
 
static unsigned int color_to_ega_style(int fg_color, int bg_color, int attr)
{
unsigned int style;
 
style = (fg_color & 7) | ((bg_color & 7) << 4);
if (attr & CATTR_BRIGHT)
style = style | 0x08;
 
return style;
}
 
static unsigned int rgb_to_ega_style(uint32_t fg, uint32_t bg)
{
return (fg > bg) ? NORMAL_COLOR : INVERTED_COLOR;
}
 
static unsigned attr_to_ega_style(const attrs_t *a)
{
switch (a->t) {
case at_style:
return style_to_ega_style(a->a.s.style);
case at_rgb:
return rgb_to_ega_style(a->a.r.fg_color, a->a.r.bg_color);
case at_idx:
return color_to_ega_style(a->a.i.fg_color,
a->a.i.bg_color, a->a.i.flags);
default:
return INVERTED_COLOR;
}
}
 
static uint8_t ega_glyph(wchar_t ch)
{
if (ch >= 0 && ch < 128)
return ch;
 
return '?';
}
 
static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
int retval;
ipc_callid_t callid;
ipc_call_t call;
char c;
unsigned int row, col;
int bgcolor,fgcolor;
wchar_t c;
unsigned int row, col, w, h;
int bg_color, fg_color, attr;
uint32_t bg_rgb, fg_rgb;
keyfield_t *interbuf = NULL;
size_t intersize = 0;
int i;
220,16 → 301,27
retval = EINVAL;
break;
case FB_DRAW_TEXT_DATA:
col = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
w = IPC_GET_ARG3(call);
h = IPC_GET_ARG4(call);
if (!interbuf) {
retval = EINVAL;
break;
}
draw_text_data(interbuf);
if (col + w > scr_width || row + h > scr_height) {
retval = EINVAL;
break;
}
draw_text_data(interbuf, col, row, w, h);
retval = 0;
break;
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, scr_height, scr_width);
ipc_answer_2(callid, EOK, scr_width, scr_height);
continue;
case FB_GET_COLOR_CAP:
ipc_answer_1(callid, EOK, FB_CCAP_INDEXED);
continue;
case FB_CLEAR:
clrscr();
retval = 0;
236,28 → 328,28
break;
case FB_PUTCHAR:
c = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
col = IPC_GET_ARG3(call);
col = IPC_GET_ARG2(call);
row = IPC_GET_ARG3(call);
if (col >= scr_width || row >= scr_height) {
retval = EINVAL;
break;
}
printchar(c, row, col);
printchar(c, col, row);
retval = 0;
break;
case FB_CURSOR_GOTO:
row = IPC_GET_ARG1(call);
col = IPC_GET_ARG2(call);
col = IPC_GET_ARG1(call);
row = IPC_GET_ARG2(call);
if (row >= scr_height || col >= scr_width) {
retval = EINVAL;
break;
}
cursor_goto(row, col);
cursor_goto(col, row);
retval = 0;
break;
case FB_SCROLL:
i = IPC_GET_ARG1(call);
if (i > scr_height || i < -((int) scr_height)) {
if (i > (int) scr_height || i < -((int) scr_height)) {
retval = EINVAL;
break;
}
265,7 → 357,7
retval = 0;
break;
case FB_CURSOR_VISIBILITY:
if(IPC_GET_ARG1(call))
if (IPC_GET_ARG1(call))
cursor_enable();
else
cursor_disable();
272,11 → 364,22
retval = 0;
break;
case FB_SET_STYLE:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
style = EGA_STYLE(fgcolor, bgcolor);
style = style_to_ega_style(IPC_GET_ARG1(call));
retval = 0;
break;
case FB_SET_COLOR:
fg_color = IPC_GET_ARG1(call);
bg_color = IPC_GET_ARG2(call);
attr = IPC_GET_ARG3(call);
style = color_to_ega_style(fg_color, bg_color, attr);
retval = 0;
break;
case FB_SET_RGB_COLOR:
fg_rgb = IPC_GET_ARG1(call);
bg_rgb = IPC_GET_ARG2(call);
style = rgb_to_ega_style(fg_rgb, bg_rgb);
retval = 0;
break;
case FB_VP_DRAW_PIXMAP:
i = IPC_GET_ARG2(call);
retval = print_screen(i);
296,9 → 399,12
}
retval = 0;
break;
 
case FB_SCREEN_YIELD:
case FB_SCREEN_RECLAIM:
retval = EOK;
break;
default:
retval = ENOENT;
retval = EINVAL;
}
ipc_answer_0(callid, retval);
}
312,13 → 418,22
ega_ph_addr = (void *) sysinfo_value("fb.address.physical");
scr_width = sysinfo_value("fb.width");
scr_height = sysinfo_value("fb.height");
iospace_enable(task_get_id(), (void *) EGA_IO_ADDRESS, 2);
 
if (sysinfo_value("fb.blinking")) {
ega_normal_color &= 0x77;
ega_inverted_color &= 0x77;
}
 
style = NORMAL_COLOR;
 
iospace_enable(task_get_id(), (void *) EGA_IO_BASE, 2);
 
sz = scr_width * scr_height * 2;
scr_addr = as_get_mappable_page(sz);
 
physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >>
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
if (physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >>
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
 
async_set_client_connection(ega_client_connection);
 
326,6 → 441,6
}
 
 
/**
/**
* @}
*/
/branches/arm/uspace/srv/fb/ppm.c
89,26 → 89,26
{
unsigned int width, height;
unsigned int maxcolor;
int i;
unsigned int i;
unsigned int color;
unsigned int coef;
 
/* Read magic */
if (data[0] != 'P' || data[1] != '6')
if ((data[0] != 'P') || (data[1] != '6'))
return EINVAL;
 
data+=2;
data += 2;
skip_whitespace(&data);
read_num(&data, &width);
skip_whitespace(&data);
read_num(&data,&height);
read_num(&data, &height);
skip_whitespace(&data);
read_num(&data,&maxcolor);
read_num(&data, &maxcolor);
data++;
 
if (maxcolor == 0 || maxcolor > 255 || width * height > datasz) {
if ((maxcolor == 0) || (maxcolor > 255) || (width * height > datasz))
return EINVAL;
}
coef = 255 / maxcolor;
if (coef * maxcolor > 255)
coef -= 1;
125,6 → 125,6
(*putpixel)(vport, sx + (i % width), sy + (i / width), color);
data += 3;
}
 
return 0;
}
/branches/arm/uspace/srv/fb/ega.h
27,10 → 27,10
*/
 
/** @addtogroup egafb
* @brief HelenOS EGA framebuffer.
* @brief HelenOS EGA framebuffer.
* @ingroup fbs
* @{
*/
*/
/** @file
*/
 
43,4 → 43,3
 
/** @}
*/
 
/branches/arm/uspace/srv/fb/serial_console.h
0,0 → 1,56
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/**
* @defgroup serial Serial console
* @brief Serial console services (putc, puts, clear screen, cursor goto,...)
* @{
*/
 
/** @file
*/
 
#ifndef FB_SERIAL_CONSOLE_H_
#define FB_SERIAL_CONSOLE_H_
 
#include <ipc/ipc.h>
 
typedef void (*putc_function_t)(char);
 
void serial_puts(char *str);
void serial_goto(const unsigned int col, const unsigned int row);
void serial_clrscr(void);
void serial_scroll(int i);
void serial_cursor_disable(void);
void serial_cursor_enable(void);
void serial_set_scroll_region(unsigned height);
void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h);
void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall);
 
 
#endif
/branches/arm/uspace/srv/fb/Makefile
31,12 → 31,11
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../libipc/include
LIBS = $(LIBC_PREFIX)/libc.a
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
45,27 → 44,45
main.c \
ppm.c
 
ifneq ($(ARCH), ia64)
ifneq ($(UARCH),ia64)
SOURCES += fb.c \
font-8x16.c
CFLAGS += -DFB_ENABLED
endif
ifeq ($(ARCH), ia32)
 
ifeq ($(UARCH),ia32)
SOURCES += ega.c
CFLAGS += -DEGA_ENABLED
endif
ifeq ($(ARCH), amd64)
 
ifeq ($(UARCH),ia64)
SOURCES += ega.c \
ski.c \
serial_console.c
CFLAGS += -DSKI_ENABLED
CFLAGS += -DEGA_ENABLED
endif
 
ifeq ($(UARCH),amd64)
SOURCES += ega.c
CFLAGS += -DEGA_ENABLED
endif
ifeq ($(ARCH), mips32)
SOURCES += msim.c
CFLAGS += -DMSIM_ENABLED -DFB_INVERT_ENDIAN
 
ifeq ($(UARCH),mips32)
SOURCES += msim.c \
serial_console.c
CFLAGS += -DMSIM_ENABLED
endif
 
CFLAGS += -D$(ARCH)
ifeq ($(UARCH),sparc64)
SOURCES += sgcn.c \
serial_console.c
CFLAGS += -DSGCN_ENABLED
endif
 
CFLAGS += -D$(UARCH)
 
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
75,18 → 92,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/fb/font-8x16.c
1,5 → 1,6
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2000 Dmitry Bolkhovityanov
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,4616 → 27,3245
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#include <sys/types.h>
#include "font-8x16.h"
 
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = {
/** Convert character to font glyph index
*
* The font does not cover all Unicode characters.
* This function converts the character to an appropriate
* glyph in the font or returns an index to the question
* mark glyph if no specific glyph exists.
*/
uint16_t fb_font_glyph(const wchar_t ch)
{
if (ch == 0x0000)
return 0;
if ((ch >= 0x0020) && (ch <= 0x007f))
return (ch - 32);
if ((ch >= 0x00a0) && (ch <= 0x021f))
return (ch - 64);
if ((ch >= 0x0222) && (ch <= 0x0233))
return (ch - 66);
if ((ch >= 0x0250) && (ch <= 0x02ad))
return (ch - 94);
if ((ch >= 0x02b0) && (ch <= 0x02cf))
return (ch - 96);
if ((ch >= 0x02d8) && (ch <= 0x02dd))
return (ch - 104);
if (ch == 0x02ee)
return 630;
if ((ch >= 0x0300) && (ch <= 0x0301))
return (ch - 137);
if (ch == 0x0303)
return 633;
if (ch == 0x0309)
return 634;
if ((ch >= 0x0312) && (ch <= 0x0314))
return (ch - 151);
if (ch == 0x0323)
return 638;
if ((ch >= 0x0340) && (ch <= 0x0341))
return (ch - 193);
if ((ch >= 0x0374) && (ch <= 0x0375))
return (ch - 243);
if (ch == 0x037a)
return 643;
if (ch == 0x037e)
return 644;
if ((ch >= 0x0384) && (ch <= 0x038a))
return (ch - 255);
if (ch == 0x038c)
return 652;
if ((ch >= 0x038e) && (ch <= 0x03a1))
return (ch - 257);
if ((ch >= 0x03a3) && (ch <= 0x03ce))
return (ch - 258);
if ((ch >= 0x03d0) && (ch <= 0x03d7))
return (ch - 259);
if ((ch >= 0x03da) && (ch <= 0x03f3))
return (ch - 261);
if ((ch >= 0x0400) && (ch <= 0x0486))
return (ch - 273);
if ((ch >= 0x0488) && (ch <= 0x04ce))
return (ch - 274);
if ((ch >= 0x04d0) && (ch <= 0x04f5))
return (ch - 275);
if ((ch >= 0x04f8) && (ch <= 0x04f9))
return (ch - 277);
if ((ch >= 0x0500) && (ch <= 0x050f))
return (ch - 283);
if ((ch >= 0x0530) && (ch <= 0x0556))
return (ch - 315);
if ((ch >= 0x0559) && (ch <= 0x055f))
return (ch - 317);
if ((ch >= 0x0561) && (ch <= 0x0587))
return (ch - 318);
if ((ch >= 0x0589) && (ch <= 0x058a))
return (ch - 319);
if ((ch >= 0x0591) && (ch <= 0x05a1))
return (ch - 325);
if ((ch >= 0x05a3) && (ch <= 0x05b9))
return (ch - 326);
if ((ch >= 0x05bb) && (ch <= 0x05c4))
return (ch - 327);
if ((ch >= 0x05d0) && (ch <= 0x05ea))
return (ch - 338);
if ((ch >= 0x05f0) && (ch <= 0x05f4))
return (ch - 343);
if (ch == 0x060c)
return 1182;
if (ch == 0x061b)
return 1183;
if (ch == 0x061f)
return 1184;
if ((ch >= 0x0621) && (ch <= 0x063a))
return (ch - 384);
if ((ch >= 0x0640) && (ch <= 0x0655))
return (ch - 389);
if ((ch >= 0x0660) && (ch <= 0x066d))
return (ch - 399);
if ((ch >= 0x0670) && (ch <= 0x06ed))
return (ch - 401);
if ((ch >= 0x06f0) && (ch <= 0x06fe))
return (ch - 403);
if (ch == 0x10d3)
return 1388;
if (ch == 0x10d7)
return 1389;
if (ch == 0x10da)
return 1390;
if (ch == 0x10dd)
return 1391;
if (ch == 0x10e6)
return 1392;
if ((ch >= 0x1e00) && (ch <= 0x1e9b))
return (ch - 6287);
if ((ch >= 0x1ea0) && (ch <= 0x1ef9))
return (ch - 6291);
if ((ch >= 0x1f00) && (ch <= 0x1f07))
return (ch - 6297);
if ((ch >= 0x2000) && (ch <= 0x2027))
return (ch - 6545);
if ((ch >= 0x2030) && (ch <= 0x2046))
return (ch - 6553);
if ((ch >= 0x2048) && (ch <= 0x204d))
return (ch - 6554);
if (ch == 0x2070)
return 1716;
if ((ch >= 0x2074) && (ch <= 0x208f))
return (ch - 6591);
if ((ch >= 0x20a0) && (ch <= 0x20af))
return (ch - 6607);
if ((ch >= 0x2100) && (ch <= 0x213a))
return (ch - 6687);
if ((ch >= 0x2153) && (ch <= 0x2183))
return (ch - 6711);
if ((ch >= 0x2190) && (ch <= 0x21f3))
return (ch - 6723);
if ((ch >= 0x2200) && (ch <= 0x22f1))
return (ch - 6735);
if (ch == 0x2300)
return 2211;
if (ch == 0x2302)
return 2212;
if ((ch >= 0x2308) && (ch <= 0x230b))
return (ch - 6755);
if (ch == 0x2310)
return 2217;
if (ch == 0x2318)
return 2218;
if ((ch >= 0x231a) && (ch <= 0x231b))
return (ch - 6767);
if ((ch >= 0x2320) && (ch <= 0x2321))
return (ch - 6771);
if ((ch >= 0x2329) && (ch <= 0x232a))
return (ch - 6778);
if ((ch >= 0x239b) && (ch <= 0x23bd))
return (ch - 6890);
if (ch == 0x23ce)
return 2260;
if ((ch >= 0x2409) && (ch <= 0x240d))
return (ch - 6964);
if ((ch >= 0x2423) && (ch <= 0x2424))
return (ch - 6985);
if (ch == 0x2426)
return 2268;
if ((ch >= 0x2500) && (ch <= 0x2595))
return (ch - 7203);
if ((ch >= 0x25a0) && (ch <= 0x25f7))
return (ch - 7213);
if ((ch >= 0x2600) && (ch <= 0x2602))
return (ch - 7221);
if ((ch >= 0x2605) && (ch <= 0x260d))
return (ch - 7223);
if ((ch >= 0x2610) && (ch <= 0x2613))
return (ch - 7225);
if (ch == 0x2620)
return 2523;
if (ch == 0x2622)
return 2524;
if (ch == 0x2626)
return 2525;
if ((ch >= 0x2628) && (ch <= 0x262b))
return (ch - 7242);
if ((ch >= 0x262e) && (ch <= 0x2637))
return (ch - 7244);
if ((ch >= 0x2639) && (ch <= 0x2653))
return (ch - 7245);
if ((ch >= 0x2660) && (ch <= 0x2667))
return (ch - 7257);
if ((ch >= 0x2669) && (ch <= 0x266f))
return (ch - 7258);
if ((ch >= 0xfb00) && (ch <= 0xfb05))
return (ch - 61674);
if ((ch >= 0xfb50) && (ch <= 0xfbb1))
return (ch - 61748);
if ((ch >= 0xfbd3) && (ch <= 0xfbe9))
return (ch - 61781);
if ((ch >= 0xfbfc) && (ch <= 0xfbff))
return (ch - 61799);
if ((ch >= 0xfc5b) && (ch <= 0xfc63))
return (ch - 61890);
if (ch == 0xfc90)
return 2722;
if ((ch >= 0xfcf2) && (ch <= 0xfcf4))
return (ch - 62031);
if ((ch >= 0xfd3c) && (ch <= 0xfd3f))
return (ch - 62102);
if (ch == 0xfdf2)
return 2730;
if ((ch >= 0xfe50) && (ch <= 0xfe52))
return (ch - 62373);
if ((ch >= 0xfe54) && (ch <= 0xfe66))
return (ch - 62374);
if ((ch >= 0xfe68) && (ch <= 0xfe6b))
return (ch - 62375);
if ((ch >= 0xfe70) && (ch <= 0xfe72))
return (ch - 62379);
if (ch == 0xfe74)
return 2760;
if ((ch >= 0xfe76) && (ch <= 0xfefc))
return (ch - 62381);
if (ch == 0xfeff)
return 2896;
return 2898;
}
 
/* 0 0x00 '^@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0xc6, 0x00, 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, 0x00, 0x00},
{0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa1, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x44, 0xba, 0xb2, 0xaa, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x30, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x30, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x3c, 0x42, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7a, 0xc4, 0xce, 0xce, 0xd6, 0xd6, 0xe6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x66, 0xec, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0x1c, 0x3c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xc4, 0xce, 0xd6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x7c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x0c, 0x18, 0x0e, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x3e, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x10, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xff, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7e, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x3c, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x3c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x30, 0x1c, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf7, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7b, 0x7b, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0xee, 0x66, 0x66, 0x66, 0x66, 0x66, 0xf6, 0x06, 0x66, 0x3c, 0x00},
{0x08, 0x1c, 0x22, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x0e, 0x1b, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x30, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x66, 0x66, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x36, 0x36, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x78, 0xe0, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x1e, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x60, 0xc0, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6e, 0xd8, 0xd8, 0xd8, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd6, 0xd6, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x18, 0x0c, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0xfc, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x30, 0x60, 0x38, 0x00},
{0x10, 0x38, 0x44, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xb3, 0xb3, 0x33, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x64, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x62, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xe6, 0xe6, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xe0, 0xe0, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x06, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x03, 0x3e, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x7e, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xb6, 0xb3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x4c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x4c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x18, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xfe, 0xcc, 0x8c, 0x2c, 0x3c, 0x2c, 0x0c, 0x8c, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc2, 0xc0, 0x78, 0xc0, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x32, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00},
{0x00, 0x03, 0x3e, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x38, 0x6c, 0x38, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x6d, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc8, 0x38, 0x70, 0xd0, 0x38, 0x38, 0x6c, 0x64, 0xc6, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0xec, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x73, 0xdf, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x03, 0x03, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xdf, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x03, 0x03, 0x03, 0x00},
{0x00, 0x00, 0x7e, 0xb3, 0xb3, 0x33, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x6c, 0xe6, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x38, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x0c, 0x38, 0x60, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x0c, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x7e, 0xfe, 0x9a, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00},
{0x03, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0x6c, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0xb3, 0xb3, 0x33, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0xf0, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x7e, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0xfc, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x7c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x78, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x7c, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x7e, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x60, 0x60, 0x78, 0x0c, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x60, 0x78, 0x0c, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x18, 0x4c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x70, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x1b, 0x0e, 0x04, 0xf7, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf5, 0xda, 0xd8, 0xdf, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3d, 0x1a, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xcb, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf3, 0x63, 0x60, 0x67, 0x63, 0x63, 0x63, 0x67, 0x6f, 0xff, 0x03, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0xe3, 0x63, 0x60, 0x67, 0x63, 0x63, 0x63, 0x63, 0x63, 0xf3, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xf8, 0xff, 0xfb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xb7, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x33, 0x1e, 0x00},
{0x6c, 0x38, 0x10, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x28, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x78, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x30, 0x30, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xdf, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x3e, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x10, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0x0c, 0x18, 0x30, 0x7c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x1b, 0x0e, 0x04, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xf7, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0xd8, 0xd8, 0xdf, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xdb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x70, 0x60, 0x60, 0x60, 0x60, 0xe0, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x38, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x38, 0x6c, 0x38, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7a, 0xc4, 0xce, 0xce, 0xd6, 0xe6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7a, 0xc4, 0xce, 0xd6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x3c, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x1c, 0x74, 0x06, 0x06, 0x06, 0x06, 0x1c, 0xf0, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0e, 0x3c, 0x06, 0x06, 0x1c, 0xf0, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfc, 0x06, 0x0c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc0, 0xfc, 0x06, 0x0c, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x7c, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x3c, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x5c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xdc, 0xe6, 0x7c, 0x80, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0d, 0x06, 0x00},
{0x00, 0x00, 0x06, 0x0d, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6c, 0x8e, 0x16, 0x26, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xcd, 0x0d, 0x38, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xdc, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x06, 0x06, 0x1f, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x46, 0x6c, 0x2c, 0x2c, 0x38, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x64, 0x28, 0x38, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x6c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x7b, 0xde, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x78, 0x58, 0x3e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x7f, 0x63, 0x66, 0x6c, 0x7e, 0x63, 0xf3, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xd8, 0xd8, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x6c, 0x0c, 0x0d, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xfc, 0xc0, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x98, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x98, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x3b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x06, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xcb, 0xfe, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x7e, 0xc7, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x76, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x7e, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7e, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcc, 0x6c, 0x3c, 0x3c, 0x6c, 0xcc, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x1c, 0x18, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0x70, 0x30, 0xfc, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xdb, 0xdb, 0xde, 0xde, 0xdb, 0x6b, 0x03, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xdb, 0xdd, 0x6f, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x60, 0x60, 0xf6, 0x6d, 0x6c, 0x66, 0x63, 0x6b, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x26, 0x6d, 0x6c, 0xfc, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x3c, 0x0c, 0x2c, 0x18, 0x00},
{0x00, 0x00, 0x20, 0x60, 0x60, 0xf6, 0x6d, 0x6c, 0x6c, 0x6e, 0x6d, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xc0, 0xfe, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x03, 0x0e, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6d, 0x6c, 0x66, 0x63, 0x6b, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6f, 0x6b, 0x63, 0x66, 0x6c, 0x6d, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0x7c, 0x6c, 0x28, 0xc6, 0xd6, 0x7c, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xf0, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xf0, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xb0, 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0xd8, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0xd8, 0x68, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xd8, 0xd8, 0xf0, 0xd8, 0xd8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xd6, 0x7c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0x78, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xc0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x70, 0xc0, 0x70, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x70, 0x18, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x20, 0x70, 0x70, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xd8, 0xd8, 0x70, 0x70, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x34, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00},
{0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3e, 0x32, 0x30, 0x34, 0x3c, 0x34, 0x30, 0x30, 0x32, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x82, 0x44, 0x7c, 0x44, 0x00, 0x82, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x92, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x46, 0x6c, 0x2c, 0x2c, 0x38, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x30, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x46, 0x7c, 0x18, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x20, 0x30, 0x10, 0x38, 0x38, 0x6c, 0x64, 0xc6, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x66, 0x6c, 0x3c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x3c, 0x30, 0x60, 0x3c, 0x60, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x46, 0x2c, 0x2c, 0x18, 0x30, 0x68, 0x68, 0xc4, 0xc2, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x6c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x36, 0x1e, 0xc6, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc2, 0x65, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x21, 0x32, 0x12, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc2, 0x65, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa6, 0x2c, 0x38, 0x68, 0xca, 0xc4, 0x0c, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0x60, 0x3c, 0x06, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x32, 0x30, 0x30, 0x3c, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00},
{0x00, 0x60, 0x30, 0x30, 0x60, 0x63, 0xff, 0xc6, 0x06, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x60, 0x60, 0xfe, 0xfe, 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xac, 0x26, 0x26, 0x0b, 0x0b, 0x1b, 0x1b, 0x1b, 0x1b, 0x03, 0x02, 0x04, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x28, 0x4c, 0x14, 0x24, 0x06, 0x02, 0x02, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6d, 0x03, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6d, 0x03, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xd6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x76, 0x9c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0xd6, 0x66, 0x06, 0x06, 0x66, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x3c, 0x60, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x26, 0x1c, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0x68, 0x38, 0x30, 0x38, 0x38, 0x4c, 0x4c, 0x86, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xba, 0x30, 0x38, 0x28, 0x4c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xc0, 0xcc, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xdc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x7e, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1c, 0x18, 0x7e, 0x58, 0x18, 0x18, 0x18, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa6, 0x2c, 0x38, 0x68, 0xca, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0x60, 0x3c, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x30, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xb2, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x03, 0x06, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xf8, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xd8, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xb2, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x18, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x38, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xc6, 0x82, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfe, 0x06, 0x02, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xff, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xb0, 0xb0, 0x30, 0x3c, 0x36, 0x36, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x3e, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x9c, 0xb6, 0xb6, 0xb6, 0xf6, 0xb6, 0xb6, 0xb6, 0xb6, 0x9c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xcc, 0xcc, 0xcc, 0x7c, 0x6c, 0x6c, 0x6c, 0x6c, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x7c, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xc6, 0x82, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfe, 0x06, 0x02, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xff, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb0, 0x30, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb6, 0xb6, 0xf6, 0xb6, 0xb6, 0x9c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xcc, 0xcc, 0x7c, 0x6c, 0x6c, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xf8, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x38, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0xfc, 0xb4, 0x30, 0x3c, 0x36, 0x36, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x30, 0xfc, 0xb4, 0x30, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xce, 0xdb, 0xd9, 0xd8, 0xfe, 0xd8, 0xd8, 0xd9, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xdb, 0xd8, 0xfe, 0xd8, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0x6c, 0xfe, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x7c, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x88, 0x8c, 0x9c, 0x96, 0xf6, 0xb6, 0xbf, 0xab, 0xeb, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x9c, 0xf6, 0xbe, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x6c, 0x6c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x6c, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xa3, 0xb2, 0x96, 0xfc, 0x9c, 0xbe, 0xaa, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xa3, 0x96, 0xfe, 0xab, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0x06, 0x06, 0x7c, 0x06, 0x06, 0x06, 0x7c, 0xc0, 0x7c, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0x86, 0x06, 0x7c, 0x06, 0x06, 0x7c, 0xc0, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x96, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x96, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc2, 0xc6, 0xc6, 0xc4, 0xcc, 0x6c, 0x68, 0x78, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x64, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xc2, 0xc6, 0xc4, 0xc4, 0x6c, 0x68, 0x78, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xc2, 0xc6, 0x64, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6f, 0x03, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6f, 0x03, 0x06, 0x1c, 0x00},
{0x00, 0x10, 0x7c, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xc6, 0xc6, 0xc6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00},
{0x04, 0x7c, 0x40, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x40, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x54, 0x00, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x54, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x60, 0x3c, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0x78, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x3c, 0x0f, 0x18, 0x18, 0xf0, 0x3c, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x7c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0xc3, 0x00, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x50, 0x46, 0x00, 0x82, 0x41, 0x00, 0x62, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x6e, 0x64, 0x7a, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x6e, 0x64, 0x7a, 0x60, 0x60, 0xf0, 0x00},
{0x02, 0x06, 0xfe, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x06, 0xfe, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0xf8, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0xf8, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xf6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x78, 0x6c, 0x66, 0xf6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xdc, 0xf8, 0xdc, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xdc, 0xf8, 0xdc, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0xf6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0xf0, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf3, 0xb3, 0xb3, 0x36, 0x3c, 0x3c, 0x36, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xb6, 0xbc, 0x3c, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xdf, 0xdb, 0xd9, 0xd8, 0xf8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xdb, 0xd9, 0xf8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xd8, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x0b, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xdb, 0x03, 0x0b, 0x06, 0x00},
{0x00, 0x00, 0x7c, 0xc2, 0xcc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc2, 0xcc, 0xd6, 0xd6, 0xcc, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0c, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0c, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0x7e, 0x16, 0x16, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0x7e, 0x16, 0x16, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0xb3, 0xb3, 0x7f, 0x30, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xb3, 0x7f, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0xb3, 0xb3, 0x7f, 0x30, 0x30, 0x30, 0x33, 0x1e, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xb3, 0x7f, 0x30, 0x30, 0x33, 0x1e, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0e, 0x0c, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0e, 0x0c, 0x08, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x3e, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x3e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x7c, 0xcd, 0xcd, 0xcd, 0xcd, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcd, 0xcd, 0xcd, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x8c, 0x0c, 0x38, 0x0d, 0x0d, 0x0d, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x0c, 0x39, 0x0d, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0xcd, 0xcd, 0xcd, 0xcd, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xfd, 0xcd, 0xcd, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xce, 0xc6, 0xc6, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x1b, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x64, 0x94, 0xba, 0x52, 0x4c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x7b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x7e, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0c, 0xd8, 0xfe, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xcf, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xf6, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x7f, 0x24, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0xf0, 0x3c, 0x0e, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x6c, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x30, 0x60, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcf, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x7c, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x60, 0x60, 0x60, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x6c, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x16, 0x16, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x76, 0x1e, 0x0e, 0x0c, 0xd8, 0xfe, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x30, 0x18, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x63, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xfe, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd0, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0x16, 0xd6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x3c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x0c, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xcf, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xca, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x60, 0x38, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x1c, 0x0c, 0x18, 0x3c, 0x64, 0x66, 0x62, 0x63, 0x3d, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x0e, 0x18, 0x30, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0f, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x76, 0x1c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0xdc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xfe, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0x16, 0x16, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcc, 0xcc, 0xcc, 0xcc, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x6c},
{0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x38, 0x10, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x60, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0c, 0x00},
{0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x74, 0xd6, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x18, 0x30, 0x00},
{0x0c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1b, 0x36, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x44, 0xaa, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x0a, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x50, 0xe0, 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, 0x0c, 0x0c, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x6c, 0xd8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x08, 0x30},
{0x60, 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0xa0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x10, 0x10},
{0x18, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x00},
{0x48, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x33, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x60, 0x66, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18},
{0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x18, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x66, 0x76, 0xdc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x36, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x66, 0x66, 0x66, 0x2c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x4c, 0xcc, 0xcc, 0xec, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x46, 0xc6, 0xc6, 0xe6, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x6c, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x34, 0x18, 0x0c, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x66, 0x64, 0x6c, 0x6e, 0x60, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xf6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0xc6, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x3c, 0x40, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x20, 0x1c, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x28, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x30, 0x4e, 0x49, 0x39, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x24, 0x00},
{0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x12, 0xca, 0x2c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00},
{0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00},
{0x0a, 0x2a, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x7e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x10, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x0c, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x70, 0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0xfc, 0xf8, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4a, 0xfe, 0xf4, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x20, 0x40, 0x30, 0x10, 0x20, 0x42, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x2c, 0x44, 0x42, 0x82, 0x82, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xf8, 0x78, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xc6, 0xc6, 0x6c, 0x28, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x28, 0x6c, 0xc6, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xf8, 0x88, 0xf8, 0x78, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x91, 0x92, 0x64, 0x08, 0x10, 0x26, 0x49, 0x89, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0xfe, 0x7c, 0x38, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x28, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x06, 0x28, 0x5e, 0x00, 0x00, 0x00},
{0x00, 0x07, 0x08, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x14, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x04, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x54, 0x33, 0x24, 0x40, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x04, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00},
{0x06, 0x08, 0x06, 0x08, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x08, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x94, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x88, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x94, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x08, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x1c, 0x6a, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x14, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x12, 0x04, 0x18, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x15, 0x88, 0x88, 0x8a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x88, 0x90, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x00, 0x0a, 0x00, 0x01, 0x15, 0x88, 0x88, 0x90, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x90, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x2a, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x00, 0x50, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x20, 0x40, 0x3e, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x05, 0x0b, 0x48, 0x84, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x29, 0x01, 0x19, 0x21, 0x19, 0xa1, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x05, 0x0b, 0x48, 0x84, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x44, 0x09, 0xa2, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x08, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x02, 0x2a, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x14, 0x00, 0x08, 0x00},
{0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x08, 0x14, 0x08, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x38, 0x40, 0x38, 0x40, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x40, 0x38, 0x40, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x12, 0x2c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0x47, 0x88, 0x08, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x50, 0x20, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x08, 0x00, 0x08},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x14, 0x00, 0x08},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x80, 0x60, 0x80, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x40, 0x43, 0x55, 0x7e, 0x80, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x2a, 0x20, 0x26, 0x2a, 0x7c, 0x80, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0e, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x14, 0x08, 0x14, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x2c, 0x10, 0x28, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x15, 0x8a, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x5a, 0xa5, 0x66, 0x5b, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x5a, 0x66, 0xa5, 0x5a, 0x00},
{0x00, 0x00, 0x18, 0x66, 0x42, 0x42, 0x81, 0x99, 0x99, 0x81, 0x42, 0x42, 0x66, 0x18, 0x00, 0x00},
{0x08, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x26, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x8a, 0x90, 0x60},
{0x32, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x0c, 0x04, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x30, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x54, 0xaa, 0x92, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x82, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x14, 0x08},
{0x08, 0x14, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x10, 0x10, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x70, 0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0xfc, 0xf8, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4a, 0xfe, 0xf4, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4e, 0xf0, 0xfe, 0x7c, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x38, 0x2c, 0x44, 0x42, 0x82, 0x92, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x60, 0x7e, 0x3c, 0x30, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xc6, 0xc6, 0x6c, 0x28, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x28, 0x6c, 0xc6, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xf8, 0x88, 0xf8, 0x78, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x88, 0x88, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x54, 0x54, 0x54, 0x54, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x4c, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xaa, 0xaa, 0xaa, 0x82, 0x82, 0x40, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x82, 0x82, 0x44, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x82, 0x82, 0x40, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0x38},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x38, 0x6c, 0x38},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0c, 0xec, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x7c, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x30, 0x30, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x60, 0x0c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x10, 0x38, 0x6c, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x76, 0xdc, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x38, 0x6c, 0x64, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x60, 0x30, 0xe0, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x76, 0xdc, 0x00},
{0x0c, 0x18, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0c, 0xec, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x60, 0x6c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x60, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x44, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x44, 0x38, 0x10, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x18, 0x18, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x16, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x08, 0x1c, 0x36, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x6c, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x6c, 0x6c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x72, 0x9c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x76, 0xdc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x18, 0x18, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x18, 0x0c, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x38, 0x6c, 0x64, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x16, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x16, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x68, 0x1c, 0x36, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x68, 0x1c, 0x36, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x28, 0x54, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x0c, 0x18, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x54, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x54, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x72, 0x9c, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x72, 0x9c, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x76, 0x88, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x26, 0x70, 0xd8, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc4, 0x6e, 0x11, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x64, 0x0e, 0x1b, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x76, 0x88, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x26, 0x70, 0xd8, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc4, 0x6e, 0x11, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x64, 0x0e, 0x1b, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x28, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x18, 0x33, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x33, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x1b, 0x33, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x1b, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x68, 0xb3, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x68, 0xb3, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x18, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x33, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x33, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x1b, 0x33, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x1b, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x68, 0xb3, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x68, 0xb3, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x0c, 0x18, 0xf6, 0x06, 0x00},
{0x38, 0x0c, 0x18, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x3a, 0x5c, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x6c, 0xc6, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xcc, 0x66, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x66, 0xcc, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc6, 0x6c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x34, 0x58, 0x0c, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x34, 0x58, 0x30, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xfe, 0x00, 0xa4, 0xaa, 0xea, 0xea, 0xa6, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xa4, 0xea, 0xaa, 0xaa, 0xa6, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x8a, 0xce, 0x8e, 0xea, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x8e, 0xca, 0x8a, 0xea, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xca, 0x2e, 0x4a, 0x2a, 0xca, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xaa, 0xae, 0xea, 0x2a, 0x2a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x6a, 0x8e, 0xca, 0xaa, 0x4a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x38, 0x20, 0x30, 0x20, 0x20, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x30, 0x28, 0x30, 0x20, 0x20, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x4a, 0x4e, 0x4a, 0x4a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x28, 0x28, 0x38, 0x28, 0x28, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0xa2, 0xa2, 0xe2, 0xea, 0xa4, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0x08, 0x08, 0x08, 0x28, 0x10, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x80, 0x80, 0x80, 0xf0, 0x28, 0x30, 0x28, 0x0a, 0x0e, 0x0e, 0x0a, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xc0, 0xa0, 0xc0, 0xa0, 0x20, 0x20, 0x38, 0x0a, 0x0e, 0x0e, 0x0a, 0x00, 0xfe, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x9c, 0xd2, 0xbc, 0x92, 0x9c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x00, 0xcc, 0xcc, 0xcc, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x6b, 0x6b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x92, 0x44, 0x28, 0x92, 0x28, 0x44, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xc3, 0xdb, 0x1b, 0x1e, 0x1c, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x7c, 0x00, 0x00},
{0x7c, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x28, 0x00, 0x00, 0x44, 0xee, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7b, 0xcf, 0xcf, 0x1b, 0x33, 0x33, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xde, 0xf3, 0xf3, 0xc6, 0xcc, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x06, 0x06, 0x0c, 0x0c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xdb, 0xdb, 0xdb, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3e, 0x72, 0xf2, 0xf2, 0xf2, 0x72, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x9c, 0x9e, 0x9e, 0x9e, 0x9c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x38, 0x78, 0xd8, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xf8, 0xc0, 0xf0, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x78, 0xc0, 0xf0, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xf8, 0xd8, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 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, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xb0, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0xd8, 0xfc, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc0, 0xf0, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xf0, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd8, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0xf0, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 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, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcf, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x04, 0x7c, 0xce, 0xc8, 0xc8, 0xd0, 0xd0, 0xd0, 0xe0, 0xe6, 0x7c, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xd6, 0xd8, 0xd8, 0xd8, 0xde, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xc0, 0xc0, 0xc0, 0xf0, 0xcd, 0xce, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0xf8, 0x60, 0xf8, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0xd6, 0xde, 0xd6, 0xd6, 0xf6, 0xd6, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x76, 0xff, 0x76, 0x6e, 0xff, 0x6e, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xf8, 0xe0, 0xf3, 0xd6, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x81, 0x81, 0x81, 0x5a, 0xff, 0x5a, 0xff, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf2, 0x8a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa2, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x3e, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x60, 0xfc, 0x60, 0xf8, 0x60, 0x60, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0xfe, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x1e, 0x78, 0x1e, 0x78, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x7c, 0xb6, 0x36, 0x33, 0x33, 0x33, 0x63, 0x66, 0xf6, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd0, 0xd2, 0xd6, 0x7c, 0x18, 0x30, 0x6e, 0xd8, 0x98, 0x18, 0x0e, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd0, 0xd2, 0xd6, 0x7c, 0x18, 0x30, 0x6e, 0xd8, 0x8c, 0x06, 0x1c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x62, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x62, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4e, 0xb9, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x7c, 0xda, 0xd8, 0xd8, 0xda, 0x7c, 0x19, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x18, 0x30, 0x6e, 0xdb, 0x9b, 0x1b, 0x0e, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x18, 0x30, 0x7b, 0xdb, 0x9b, 0x1b, 0x0d, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc2, 0xc0, 0x78, 0xc0, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x26, 0x3e, 0x26, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0xb9, 0x58, 0x1a, 0x1e, 0x1a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x66, 0x46, 0x87, 0x8c, 0x8c, 0x7c, 0x98, 0x98, 0x70, 0x00},
{0x00, 0x00, 0x52, 0xb5, 0x15, 0x16, 0x2c, 0x34, 0x68, 0xa9, 0xaa, 0x4c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x48, 0xb0, 0x80, 0x48, 0x7c, 0x66, 0x26, 0x26, 0xa6, 0x46, 0x06, 0x34, 0x48, 0x00},
{0x00, 0x00, 0xe2, 0xa2, 0xa2, 0xa2, 0xbe, 0xa2, 0xa2, 0xa2, 0xa2, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x36, 0x3b, 0x3b, 0x33, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x1e, 0x18, 0x76, 0x3b, 0x3b, 0x33, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x33, 0x4e, 0x06, 0x06, 0x0c, 0x0c, 0x1f, 0x6c, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x71, 0x8e, 0x04, 0x0c, 0x06, 0x03, 0x63, 0xc3, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x46, 0x49, 0x39, 0x1e, 0x18, 0x30, 0x70, 0xb1, 0xba, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x19, 0x31, 0x32, 0x64, 0x68, 0x70, 0xe1, 0x66, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xff, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe2, 0xa2, 0xb2, 0xb2, 0xaa, 0xaa, 0xa6, 0xa6, 0xa2, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcf, 0xed, 0xff, 0xfc, 0xdf, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0xb9, 0xa5, 0xa5, 0xb9, 0xa1, 0xa1, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x40, 0x8e, 0x93, 0xa3, 0x63, 0x4b, 0x6a, 0xa4, 0xb0, 0xb0, 0x60, 0x00},
{0x00, 0x00, 0xfc, 0xa2, 0xa2, 0xa2, 0xa2, 0xbc, 0xa0, 0xa0, 0xa0, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xaa, 0xa6, 0x7e, 0x01, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x4d, 0x4d, 0x19, 0x1e, 0x1c, 0x34, 0x34, 0xb5, 0x62, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x58, 0xa6, 0xa3, 0x6c, 0xb8, 0x26, 0x26, 0x26, 0xa7, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0xa2, 0xa2, 0xa2, 0xa2, 0xbc, 0xb0, 0xa8, 0xa4, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x6d, 0x67, 0x66, 0xee, 0x08, 0x00, 0x00, 0x00},
{0x30, 0x0c, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xd8, 0xdc, 0xdc, 0xe6, 0xe6, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x71, 0xdb, 0x35, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x52, 0x5a, 0x52, 0x5f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf1, 0x5b, 0x55, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x18, 0xce, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xe6, 0x6c, 0x38, 0x50, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x0a, 0x14, 0x14, 0x28, 0x28, 0x50, 0x50, 0xa0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x9c, 0x30, 0xfe, 0x0c, 0x18, 0x38, 0x0c, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0x6c, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x26, 0x03, 0x13, 0x0c, 0x13, 0x03, 0x03, 0x66, 0x98, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x2d, 0x2d, 0x1a, 0x1e, 0x1b, 0x31, 0x31, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x6b, 0xc8, 0xcc, 0xc6, 0xc6, 0xcc, 0xc0, 0x63, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xe7, 0xff, 0xe0, 0x67, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x26, 0x44, 0xf8, 0xc0, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4c, 0x52, 0x3c, 0x10, 0x3c, 0x60, 0xc0, 0xc3, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x73, 0xce, 0x18, 0x3a, 0x5c, 0x18, 0x30, 0x30, 0xb0, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x2c, 0x3c, 0x2c, 0x8c, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x12, 0x12, 0x12, 0x16, 0x36, 0x3e, 0x3a, 0x5a, 0x52, 0x91, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x26, 0x46, 0xc6, 0xc4, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0xc6, 0xe7, 0x7a, 0x38, 0x5c, 0xce, 0xe7, 0x63, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xfc, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x7e, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x78, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x7e, 0xf2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xfe, 0x7e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x38, 0x00, 0x78, 0x38, 0x38, 0x38, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xff, 0x83, 0x86, 0x82, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0xc6, 0xfc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0xc6, 0xfc, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x30, 0x70, 0xb2, 0xf6, 0x3c, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0xb0, 0x3c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0xc0, 0xe2, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb0, 0x3c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0x80, 0xe2, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0x30, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0xce, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x73, 0x23, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x65, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xce, 0xce, 0xce, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0x73, 0x73, 0x73, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x95, 0x95, 0x95, 0x65, 0x65, 0x65, 0x95, 0x95, 0x95, 0x95, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x23, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x05, 0x05, 0x00, 0x95, 0x95, 0x95, 0x95, 0x95, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x15, 0x15, 0x00, 0xb5, 0xb5, 0xb5, 0xb5, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0xdb, 0xdb, 0xce, 0xce, 0xce, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xdb, 0xdb, 0x73, 0x73, 0x73, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x05, 0x05, 0x00, 0x95, 0x95, 0x65, 0x65, 0x95, 0x95, 0x95, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xe6, 0xd6, 0xd6, 0xd6, 0xd6, 0xe6, 0xcc, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0x99, 0xbd, 0xdb, 0xdb, 0xbd, 0x99, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x06, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb0, 0x18, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x07, 0x0d, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0d, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0c, 0x18, 0xb0, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x62, 0xff, 0x64, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x26, 0xff, 0x46, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xce, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x73, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xff, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x36, 0xff, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xfc, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x3f, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x63, 0xff, 0x63, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xff, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x33, 0x63, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0xc6, 0x7f, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x3b, 0x6b, 0xfe, 0x68, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xdc, 0xd6, 0x7f, 0x16, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x5a, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x6e, 0xff, 0x76, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x60, 0x63, 0xff, 0xc6, 0x16, 0x1c, 0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x66, 0x36, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0xcc, 0xd8, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, 0xcc, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x3f, 0x1e, 0x0c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x0c, 0x3f, 0x1e, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x00, 0xf0, 0xe0, 0xb0, 0x18, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x98, 0xb0, 0xff, 0xb0, 0x98, 0x19, 0x0d, 0xff, 0x0d, 0x19, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x1e, 0x1c, 0x16, 0x03, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x38, 0x68, 0xc0, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1c, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x30, 0x60, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x2e, 0x3f, 0x24, 0x24, 0x24, 0x24, 0xfc, 0x74, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x60, 0xff, 0x60, 0x30, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x7e, 0xff, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0xff, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x00, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x00, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x7f, 0xc4, 0x7f, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x7e, 0xcb, 0x7e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xfe, 0x23, 0xfe, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xc0, 0x7f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x7c, 0xee, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0x03, 0xfe, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x7e, 0xc3, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x7c, 0xee, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb0, 0xd8, 0xec, 0xb6, 0x1b, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x07, 0x0d, 0x1b, 0x37, 0x6d, 0xd8, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x20, 0x30, 0xd8, 0x6d, 0x37, 0x1b, 0x0d, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x0c, 0x1b, 0xb6, 0xec, 0xd8, 0xb0, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x60, 0xff, 0x60, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x06, 0xff, 0x06, 0xfc, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x6a, 0xff, 0x65, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xa6, 0xff, 0x56, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xd5, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x66, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xab, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xb0, 0xff, 0xb0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0d, 0xff, 0x0d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x41, 0x81, 0x41, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x82, 0x81, 0x82, 0xfc, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44, 0xc6, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x7c, 0x00, 0x7c, 0x44, 0x7c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x7c, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x54, 0xd6, 0x54, 0x54, 0x54, 0xd6, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x54, 0xee, 0x44, 0xc6, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x54, 0xee, 0x44, 0xc6, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe8, 0xbc, 0x82, 0x81, 0x82, 0xbc, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x80, 0xbc, 0xb8, 0xac, 0x86, 0x83, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x01, 0x81, 0xc1, 0x61, 0x35, 0x1d, 0x3d, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xfe, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x06, 0x06, 0x3e, 0x66, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x7e, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xfe, 0x16, 0x16, 0x16, 0x7e, 0x16, 0x26, 0x26, 0x26, 0xfe, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x3e, 0x66, 0xcf, 0xdb, 0xdb, 0xf3, 0x66, 0x7c, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xc0, 0xfe, 0xc0, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x3e, 0x64, 0xc8, 0xc8, 0xfe, 0xc8, 0xd0, 0x70, 0x3e, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfe, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0x06, 0xfe, 0x06, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xf8, 0x1c, 0x16, 0x26, 0xfe, 0x26, 0x26, 0x4c, 0xf8, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0xfe, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe7, 0x00, 0x00},
{0x00, 0x00, 0xe7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xc1, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xff, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x06, 0x06, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe3, 0x33, 0x66, 0x36, 0xe6, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x33, 0x73, 0xb6, 0xf6, 0x36, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdb, 0xdb, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x16, 0x0c, 0x1c, 0x34, 0x62, 0xff, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x1a, 0x1c, 0x38, 0x58, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6e, 0x7c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x2a, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0xa8, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0x99, 0x99, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x33, 0x66, 0x66, 0x66, 0x7e, 0xe7, 0xe7, 0xe7, 0xe7, 0x7e, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x2a, 0x54, 0x54, 0x54, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x54, 0x54, 0x54, 0xa8, 0x00, 0x00},
{0x18, 0x34, 0x30, 0x30, 0x38, 0x35, 0x33, 0x37, 0x30, 0x30, 0x30, 0x30, 0xb0, 0x60, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0xfa, 0x5a, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0x5f, 0x5a, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0xfc, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x7e, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x76, 0xdc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xdb, 0xdb, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xdb, 0xdb, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x76, 0xdc, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0xfe, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0xfe, 0x20, 0xfe, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0x76, 0xdc, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0xdf, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0xfb, 0x00, 0x00, 0xfb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x28, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x10, 0x7c, 0x28, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x44, 0x7c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x26, 0x7c, 0xb4, 0x6c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x68, 0x54, 0x54, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x08, 0x10, 0x00, 0x10, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x08, 0x7e, 0x08, 0x10, 0x7e, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0xfe, 0x08, 0x10, 0xfe, 0x10, 0x20, 0xfe, 0x20, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1b, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xce, 0x7c, 0x10, 0x7c, 0xe6, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x76, 0xdc, 0x20, 0x20, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0x76, 0xdc, 0x80, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x38, 0xe8, 0x38, 0x1e, 0xf0, 0x38, 0x2e, 0x38, 0xe0, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xe8, 0x38, 0x0e, 0x38, 0xf0, 0x1e, 0x38, 0xe0, 0x38, 0x2e, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0xf2, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x9e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x06, 0x0c, 0x38, 0xe8, 0x38, 0x1c, 0x16, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0xd0, 0x70, 0x38, 0x2e, 0x38, 0x60, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x7e, 0xc8, 0xc8, 0xd0, 0xd0, 0x7e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0xfc, 0x16, 0x16, 0x26, 0x26, 0xfc, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x7e, 0xc8, 0xc8, 0xd0, 0xd0, 0x7e, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xfc, 0x16, 0x16, 0x26, 0x26, 0xfc, 0x40, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x08, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x92, 0xa2, 0xfa, 0xa2, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xba, 0xba, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xba, 0x92, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x54, 0x92, 0xfe, 0x92, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0xfe, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0xaa, 0x92, 0xaa, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x8a, 0x92, 0xa2, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xba, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xaa, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x54, 0xd6, 0xba, 0xd6, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0xba, 0x82, 0xba, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0xba, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0xfe, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x92, 0xba, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0xdf, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xa8, 0xa8, 0xa8, 0xa8, 0xaf, 0xa8, 0xa8, 0xa8, 0xa8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xdf, 0xd8, 0xdf, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc4, 0xc4, 0xff, 0xc8, 0xc8, 0xd0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc4, 0xc4, 0xff, 0xc8, 0xff, 0xd0, 0xd0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd9, 0xda, 0xda, 0xdf, 0xda, 0xda, 0xdc, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd9, 0xda, 0xdf, 0xda, 0xdf, 0xda, 0xdc, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0c, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x1e, 0x76, 0xc6, 0x76, 0x1e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xf0, 0xdc, 0xc6, 0xdc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x1e, 0x76, 0xc6, 0x76, 0x1e, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xf0, 0xdc, 0xc6, 0xdc, 0xf0, 0xc0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0xc6, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf0, 0xc8, 0xc4, 0xc4, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0b, 0x13, 0x23, 0x43, 0x83, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x38, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x92, 0x44, 0x28, 0x92, 0x28, 0x44, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0xc4, 0xa8, 0x90, 0xa8, 0xc4, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x46, 0x2a, 0x12, 0x2a, 0x46, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x60, 0xce, 0xd8, 0xd8, 0xce, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf8, 0x0c, 0xe6, 0x36, 0x36, 0xe6, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x54, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x64, 0xce, 0x64, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x4c, 0xe6, 0x4c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x54, 0xa8, 0x54, 0x2a, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xa8, 0x54, 0x2a, 0x15, 0x2a, 0x54, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00},
{0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf2, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x9e, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x0e, 0x1c, 0xf0, 0x1c, 0x16, 0xf2, 0x1c, 0x26, 0x22, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x88, 0xc8, 0x70, 0x1e, 0x70, 0xd0, 0x9e, 0x70, 0xe0, 0xa0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0xfe, 0xc8, 0xc8, 0xd0, 0xd0, 0xfe, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xfe, 0x16, 0x16, 0x26, 0x26, 0xfe, 0x40, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x08, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x0e, 0x1e, 0x76, 0xd6, 0x76, 0x1e, 0x26, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xc8, 0xf0, 0xdc, 0xd6, 0xdc, 0xf0, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x1e, 0x76, 0xd6, 0x76, 0x1e, 0x26, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xc8, 0xf0, 0xdc, 0xd6, 0xdc, 0xf0, 0xe0, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3d, 0x66, 0xc7, 0xcb, 0xd3, 0xe3, 0x66, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x42, 0xa5, 0x7e, 0x24, 0x24, 0x7e, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x54, 0x8a, 0xf6, 0x82, 0x54, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xfe, 0xfe, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00},
{0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x03, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x00, 0x00},
{0x00, 0xc0, 0x60, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0xc0, 0x00, 0x00},
{0x00, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3f, 0x00, 0x00},
{0x00, 0xfc, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xfc, 0x00, 0x00},
{0x00, 0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0},
{0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07},
{0x00, 0x00, 0xff, 0xc1, 0xc0, 0x60, 0x60, 0x60, 0x60, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x60, 0x60, 0x60, 0x60, 0xc0, 0xc1, 0xff, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x78, 0x78, 0x38, 0x38, 0x18, 0x18, 0x00, 0x00},
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03},
{0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x07, 0x05, 0x05, 0x05, 0x05, 0x25, 0x79, 0xc2, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xf8, 0xd8, 0xd8, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xf0, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xf8, 0x70, 0x20, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0xc0, 0xe0, 0xc0, 0xc0, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xc0, 0xc0, 0xc0, 0x70, 0x1e, 0x1b, 0x1e, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x98, 0xd8, 0xf8, 0xd8, 0xd8, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xfe, 0xc6, 0xc6, 0x60, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0e, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80},
{0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01},
{0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{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, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
{0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc},
{0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8},
{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0},
{0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0},
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
{0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f},
{0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44},
{0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa},
{0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77},
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
{0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0xba, 0xba, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x8a, 0xc6, 0xa2, 0x92, 0x8a, 0xc6, 0xa2, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xa2, 0xc6, 0x8a, 0x92, 0xa2, 0xc6, 0x8a, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x42, 0x84, 0x84, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x44, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x80, 0xc0, 0xa0, 0x90, 0x88, 0x84, 0x88, 0x90, 0xa0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x78, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x48, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x98, 0x86, 0x98, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x06, 0x0a, 0x12, 0x22, 0x42, 0x22, 0x12, 0x0a, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x78, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x48, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x32, 0xc2, 0x32, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x54, 0xba, 0xba, 0x54, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xbd, 0xbd, 0xbd, 0xbd, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x82, 0x82, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x28, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa5, 0xa5, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x72, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0x72, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x4e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x70, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0xbd, 0xc3, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xbd, 0xc3, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x30, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0xff, 0xff},
{0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff},
{0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0x80, 0x80},
{0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xff, 0xfd, 0xf9, 0xf1, 0xf1, 0xe1, 0xc1, 0x81, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x81, 0x83, 0x87, 0x8f, 0x8f, 0x9f, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x28, 0x28, 0x44, 0x44, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x74, 0x74, 0xf2, 0xf2, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x5c, 0x5c, 0x9e, 0x9e, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0x92, 0xf2, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0xf2, 0x92, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x9e, 0x92, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0x92, 0x9e, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4a, 0x89, 0x89, 0x89, 0xf9, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xf9, 0x89, 0x89, 0x89, 0x4a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x9f, 0x91, 0x91, 0x91, 0x52, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x52, 0x91, 0x91, 0x91, 0x9f, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x7c, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x7c, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0xfe, 0x7c, 0x38, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x28, 0xee, 0x44, 0x54, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x34, 0x1c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcd, 0xc7, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x92, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0xa5, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xa5, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x36, 0x1c, 0x18, 0x30, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x86, 0x8a, 0xba, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0xee, 0xba, 0xba, 0xee, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x82, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x82, 0xaa, 0x82, 0x44, 0x7c, 0x44, 0x38, 0x00, 0x44, 0xc6, 0x38, 0xc6, 0x44, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0xee, 0xfe, 0x92, 0xba, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xff, 0x18, 0x1e, 0x78, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x10, 0x10, 0x92, 0xfe, 0x92, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x72, 0xe0, 0xc4, 0xdf, 0xce, 0xca, 0xe0, 0x72, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x54, 0x28, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0x99, 0x99, 0x99, 0xbd, 0xff, 0xdb, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x85, 0xb1, 0xf9, 0xff, 0xdf, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0x81, 0x99, 0xa5, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xa5, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x28, 0xc6, 0x28, 0x54, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0x14, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x14, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x28, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x28, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x06, 0x0e, 0x1a, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x03, 0x03, 0x7b, 0xcf, 0xcf, 0xcf, 0x0f, 0x1b, 0x33, 0xff, 0x03, 0x03, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf0, 0x60, 0x6e, 0x73, 0x63, 0x63, 0x66, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0x54, 0x54, 0x7c, 0x54, 0x54, 0xd6, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0xdb, 0xdb, 0xdb, 0xdb, 0x7e, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0xa5, 0xa5, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc3, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7e, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xdb, 0xd8, 0x70, 0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1b, 0x7b, 0xdb, 0xdb, 0x73, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x94, 0x7c, 0x55, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x06, 0x0b, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x24, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x94, 0x7c, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x04, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x1f, 0x07, 0x8f, 0xdb, 0x73, 0x70, 0xd8, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x90, 0x50, 0x70, 0x68, 0x48, 0x48, 0x4e, 0x49, 0x09, 0x0e, 0x10, 0x20, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x2a, 0x7e, 0xaa, 0x00, 0x00, 0x2a, 0x7e, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x82, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x81, 0x81, 0x66, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x24, 0x3c, 0xe7, 0xa5, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x3c, 0x3e, 0x32, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x7f, 0x6f, 0x63, 0x63, 0x63, 0x63, 0xe3, 0xe7, 0xc7, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x63, 0xe7, 0xe7, 0xc6, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xcc, 0xde, 0xe6, 0xc4, 0xd8, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x40, 0x44, 0x5c, 0x74, 0x44, 0x44, 0x5c, 0x74, 0x44, 0x04, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x46, 0x5c, 0x74, 0xc4, 0x46, 0x5c, 0x74, 0xc4, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6e, 0x66, 0x60, 0xfe, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6e, 0x66, 0x66, 0xfe, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6e, 0xdb, 0xdb, 0xd8, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6f, 0xdb, 0xdb, 0xdb, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x6c, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x88, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x88, 0x80, 0x88, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x94, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x94, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x94, 0x80, 0x88, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x94, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x94, 0x80, 0x94, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x28, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x28, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x28, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x28, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa2, 0x0c, 0x13, 0x0c, 0x10, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa2, 0x0c, 0x13, 0x0c, 0x10, 0x10, 0x08, 0x04, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x00, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x40, 0x38, 0x40, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x80, 0x70, 0x80, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x10, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf7, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x80, 0x70, 0x80, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x00, 0x07, 0x18, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x29, 0x01, 0x19, 0x21, 0x19, 0xa1, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x2a, 0x02, 0x32, 0x42, 0x32, 0xc6, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0xa3, 0x0c, 0x10, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0xa3, 0x0c, 0x10, 0x10, 0x08, 0x04, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x23, 0x54, 0x33, 0x24, 0x40, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x10, 0x00, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x10, 0x00, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x20, 0x20, 0x20, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x98, 0x60, 0xc2, 0x12, 0x92, 0x9c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x92, 0x9c, 0x60, 0x0e, 0x70, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x60, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x10, 0x60, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x54, 0x58, 0x20, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x0e, 0xf0, 0x02, 0x92, 0x9c, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x60, 0x02, 0x92, 0x9c, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x12, 0x9c, 0x60, 0x0e, 0x70, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x50, 0x28, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x28, 0x14, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0x10, 0x54, 0x38, 0x54, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x10, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x2a, 0x14, 0x00, 0x21, 0x69, 0xa9, 0x69, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x20, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x38, 0x38, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x54, 0x30, 0x18, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x08, 0x10, 0x10, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x54, 0x58, 0x40, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x12, 0xca, 0x2c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00},
{0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x14, 0x18, 0x60, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x06, 0x18, 0x60, 0x00, 0x00},
{0x0a, 0x2a, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x12, 0x92, 0x9c, 0x60, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x3c, 0x40, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x3e, 0x40, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x20, 0x1c, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x10, 0x0e, 0x10, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x0c, 0x10, 0x0e, 0x10, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x0c, 0x10, 0x0e, 0x10, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x28, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x50, 0x00, 0x10, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x88, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x80, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x80, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x15, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x2a, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0x22, 0x41, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0x22, 0x41, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x0e, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x00, 0x06, 0x09, 0x49, 0x87, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x32, 0x42, 0x32, 0x42, 0x02, 0x86, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x4b, 0x4a, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x32, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x30, 0x4e, 0x49, 0x39, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x24, 0x28, 0xf3, 0x24, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x24, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x24, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x68, 0x90, 0x02, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x68, 0x90, 0x02, 0x32, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x80, 0x72, 0xa2, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x40, 0x3a, 0x52, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00},
{0x00, 0x00, 0x22, 0x12, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00},
{0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x22, 0x12, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xf1, 0x35, 0x55, 0x8a, 0xe0, 0x06, 0x95, 0xd6, 0xb5, 0x97, 0x00, 0xee, 0x8a, 0xee, 0x28, 0xe8},
{0x00, 0x38, 0x7c, 0x7c, 0xc6, 0x92, 0xf2, 0xe6, 0xfe, 0xe6, 0x7c, 0x7c, 0x38, 0x00, 0x00, 0x00},
/* Special glyph for unknown character */
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}
};
 
/* 1 0x01 '^A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x81, /* 10000001 */
0xa5, /* 10100101 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 2 0x02 '^B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xdb, /* 11011011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 3 0x03 '^C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 4 0x04 '^D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 5 0x05 '^E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 6 0x06 '^F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 7 0x07 '^G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 8 0x08 '^H' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xe7, /* 11100111 */
0xc3, /* 11000011 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 9 0x09 '^I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x42, /* 01000010 */
0x42, /* 01000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 10 0x0a '^J' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0x99, /* 10011001 */
0xbd, /* 10111101 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0xc3, /* 11000011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 11 0x0b '^K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x1a, /* 00011010 */
0x32, /* 00110010 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 12 0x0c '^L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 13 0x0d '^M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x33, /* 00110011 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x70, /* 01110000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 14 0x0e '^N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x67, /* 01100111 */
0xe7, /* 11100111 */
0xe6, /* 11100110 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 15 0x0f '^O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xdb, /* 11011011 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0x3c, /* 00111100 */
0xdb, /* 11011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 16 0x10 '^P' */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0xf0, /* 11110000 */
0xf8, /* 11111000 */
0xfe, /* 11111110 */
0xf8, /* 11111000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 17 0x11 '^Q' */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0e, /* 00001110 */
0x1e, /* 00011110 */
0x3e, /* 00111110 */
0xfe, /* 11111110 */
0x3e, /* 00111110 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 18 0x12 '^R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 19 0x13 '^S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 20 0x14 '^T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7b, /* 01111011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 21 0x15 '^U' */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 22 0x16 '^V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 23 0x17 '^W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 24 0x18 '^X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 25 0x19 '^Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 26 0x1a '^Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 27 0x1b '^[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xfe, /* 11111110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 28 0x1c '^\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 29 0x1d '^]' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x28, /* 00101000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x28, /* 00101000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 30 0x1e '^^' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 31 0x1f '^_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 32 0x20 ' ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 33 0x21 '!' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 34 0x22 '"' */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x24, /* 00100100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 35 0x23 '#' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 36 0x24 '$' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x86, /* 10000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 37 0x25 '%' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 38 0x26 '&' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 39 0x27 ''' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 40 0x28 '(' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 41 0x29 ')' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 42 0x2a '*' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0xff, /* 11111111 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 43 0x2b '+' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 44 0x2c ',' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 45 0x2d '-' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 46 0x2e '.' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 47 0x2f '/' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 48 0x30 '0' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 49 0x31 '1' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x38, /* 00111000 */
0x78, /* 01111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 50 0x32 '2' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 51 0x33 '3' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x3c, /* 00111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 52 0x34 '4' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x1c, /* 00011100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 53 0x35 '5' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 54 0x36 '6' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 55 0x37 '7' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 56 0x38 '8' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 57 0x39 '9' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 58 0x3a ':' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 59 0x3b ';' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 60 0x3c '<' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 61 0x3d '=' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 62 0x3e '>' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 63 0x3f '?' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 64 0x40 '@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xdc, /* 11011100 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 65 0x41 'A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 66 0x42 'B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 67 0x43 'C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 68 0x44 'D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 69 0x45 'E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 70 0x46 'F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 71 0x47 'G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xde, /* 11011110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x66, /* 01100110 */
0x3a, /* 00111010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 72 0x48 'H' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 73 0x49 'I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 74 0x4a 'J' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 75 0x4b 'K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe6, /* 11100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 76 0x4c 'L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 77 0x4d 'M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xee, /* 11101110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 78 0x4e 'N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 79 0x4f 'O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 80 0x50 'P' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 81 0x51 'Q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xde, /* 11011110 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 82 0x52 'R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 83 0x53 'S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 84 0x54 'T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x5a, /* 01011010 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 85 0x55 'U' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 86 0x56 'V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 87 0x57 'W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0xee, /* 11101110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 88 0x58 'X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 89 0x59 'Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 90 0x5a 'Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 91 0x5b '[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 92 0x5c '\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0x70, /* 01110000 */
0x38, /* 00111000 */
0x1c, /* 00011100 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 93 0x5d ']' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 94 0x5e '^' */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 95 0x5f '_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 96 0x60 '`' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 97 0x61 'a' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 98 0x62 'b' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 99 0x63 'c' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 100 0x64 'd' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 101 0x65 'e' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 102 0x66 'f' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x36, /* 00110110 */
0x32, /* 00110010 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 103 0x67 'g' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 104 0x68 'h' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x6c, /* 01101100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 105 0x69 'i' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 106 0x6a 'j' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
 
/* 107 0x6b 'k' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 108 0x6c 'l' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 109 0x6d 'm' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 110 0x6e 'n' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 111 0x6f 'o' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 112 0x70 'p' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
 
/* 113 0x71 'q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
 
/* 114 0x72 'r' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 115 0x73 's' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 116 0x74 't' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0xfc, /* 11111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x36, /* 00110110 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 117 0x75 'u' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 118 0x76 'v' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 119 0x77 'w' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 120 0x78 'x' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 121 0x79 'y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
 
/* 122 0x7a 'z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 123 0x7b '{' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 124 0x7c '|' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 125 0x7d '}' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 126 0x7e '~' */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 127 0x7f '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 128 0x80 '€' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 129 0x81 '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 130 0x82 '‚' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 131 0x83 'ƒ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 132 0x84 '„' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 133 0x85 '…' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 134 0x86 '†' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 135 0x87 '‡' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 136 0x88 'ˆ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 137 0x89 '‰' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 138 0x8a 'Š' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 139 0x8b '‹' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 140 0x8c 'Œ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 141 0x8d '' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 142 0x8e 'Ž' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 143 0x8f '' */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 144 0x90 '' */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 145 0x91 '‘' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x6e, /* 01101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 146 0x92 '’' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3e, /* 00111110 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xce, /* 11001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 147 0x93 '“' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 148 0x94 '”' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 149 0x95 '•' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 150 0x96 '–' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 151 0x97 '—' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 152 0x98 '˜' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 153 0x99 '™' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 154 0x9a 'š' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 155 0x9b '›' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 156 0x9c 'œ' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x64, /* 01100100 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xe6, /* 11100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 157 0x9d '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 158 0x9e 'ž' */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xf8, /* 11111000 */
0xc4, /* 11000100 */
0xcc, /* 11001100 */
0xde, /* 11011110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 159 0x9f 'Ÿ' */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 160 0xa0 ' ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 161 0xa1 '¡' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 162 0xa2 '¢' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 163 0xa3 '£' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 164 0xa4 '¤' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 165 0xa5 '¥' */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 166 0xa6 '¦' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 167 0xa7 '§' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 168 0xa8 '¨' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 169 0xa9 '©' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 170 0xaa 'ª' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 171 0xab '«' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xdc, /* 11011100 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 172 0xac '¬' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x66, /* 01100110 */
0xce, /* 11001110 */
0x9a, /* 10011010 */
0x3f, /* 00111111 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 173 0xad '­' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 174 0xae '®' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 175 0xaf '¯' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 176 0xb0 '°' */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
 
/* 177 0xb1 '±' */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
 
/* 178 0xb2 '²' */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
 
/* 179 0xb3 '³' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 180 0xb4 '´' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 181 0xb5 'µ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 182 0xb6 '¶' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 183 0xb7 '·' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 184 0xb8 '¸' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 185 0xb9 '¹' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 186 0xba 'º' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 187 0xbb '»' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 188 0xbc '¼' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 189 0xbd '½' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 190 0xbe '¾' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 191 0xbf '¿' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 192 0xc0 'À' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 193 0xc1 'Á' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 194 0xc2 'Â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 195 0xc3 'Ã' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 196 0xc4 'Ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 197 0xc5 'Å' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 198 0xc6 'Æ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 199 0xc7 'Ç' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 200 0xc8 'È' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 201 0xc9 'É' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 202 0xca 'Ê' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 203 0xcb 'Ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 204 0xcc 'Ì' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 205 0xcd 'Í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 206 0xce 'Î' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 207 0xcf 'Ï' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 208 0xd0 'Ð' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 209 0xd1 'Ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 210 0xd2 'Ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 211 0xd3 'Ó' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 212 0xd4 'Ô' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 213 0xd5 'Õ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 214 0xd6 'Ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 215 0xd7 '×' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 216 0xd8 'Ø' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 217 0xd9 'Ù' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 218 0xda 'Ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 219 0xdb 'Û' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 220 0xdc 'Ü' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 221 0xdd 'Ý' */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
 
/* 222 0xde 'Þ' */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
 
/* 223 0xdf 'ß' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 224 0xe0 'à' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 225 0xe1 'á' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xd8, /* 11011000 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 226 0xe2 'â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 227 0xe3 'ã' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 228 0xe4 'ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 229 0xe5 'å' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 230 0xe6 'æ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
 
/* 231 0xe7 'ç' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 232 0xe8 'è' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 233 0xe9 'é' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 234 0xea 'ê' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xee, /* 11101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 235 0xeb 'ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x3e, /* 00111110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 236 0xec 'ì' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 237 0xed 'í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x03, /* 00000011 */
0x06, /* 00000110 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xf3, /* 11110011 */
0x7e, /* 01111110 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 238 0xee 'î' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 239 0xef 'ï' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 240 0xf0 'ð' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 241 0xf1 'ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 242 0xf2 'ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 243 0xf3 'ó' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 244 0xf4 'ô' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 245 0xf5 'õ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 246 0xf6 'ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 247 0xf7 '÷' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 248 0xf8 'ø' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 249 0xf9 'ù' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 250 0xfa 'ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 251 0xfb 'û' */
0x00, /* 00000000 */
0x0f, /* 00001111 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xec, /* 11101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3c, /* 00111100 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 252 0xfc 'ü' */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 253 0xfd 'ý' */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x32, /* 00110010 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 254 0xfe 'þ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 255 0xff 'ÿ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
};
/** @}
*/
/branches/arm/uspace/srv/fb/font-8x16.h
26,12 → 26,25
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef FB_FONT_8X16_H_
#define FB_FONT_8X16_H_
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#define FONT_GLIPHS 256
#define FONT_SCANLINES 16
#ifndef FONT_8X16_H_
#define FONT_8X16_H_
 
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES];
#define FONT_GLYPHS 2899
#define FONT_WIDTH 8
#define FONT_SCANLINES 16
 
#include <sys/types.h>
 
extern uint16_t fb_font_glyph(const wchar_t ch);
extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
#endif
 
/** @}
*/
/branches/arm/uspace/srv/fb/msim.c
36,29 → 36,17
*/
 
#include <async.h>
#include <ipc/fb.h>
#include <ipc/ipc.h>
#include <libc.h>
#include <errno.h>
#include <string.h>
#include <libc.h>
#include <stdio.h>
#include <ipc/fb.h>
#include <sysinfo.h>
#include <as.h>
#include <align.h>
#include <ddi.h>
 
#include "serial_console.h"
#include "msim.h"
 
#define WIDTH 80
#define HEIGHT 25
#define HEIGHT 24
 
#define MAX_CONTROL 20
 
/* Allow only 1 connection */
static int client_connected = 0;
 
static char *virt_addr;
 
static void msim_putc(const char c)
66,159 → 54,17
*virt_addr = c;
}
 
static void msim_puts(char *str)
{
while (*str)
*virt_addr = *(str++);
}
 
static void msim_clrscr(void)
{
msim_puts("\033[2J");
}
 
static void msim_goto(const unsigned int row, const unsigned int col)
{
if ((row > HEIGHT) || (col > WIDTH))
return;
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
msim_puts(control);
}
 
static void msim_set_style(const unsigned int mode)
{
char control[MAX_CONTROL];
snprintf(control, MAX_CONTROL, "\033[%um", mode);
msim_puts(control);
}
 
static void msim_cursor_disable(void)
{
msim_puts("\033[?25l");
}
 
static void msim_cursor_enable(void)
{
msim_puts("\033[?25h");
}
 
static void msim_scroll(int i)
{
if (i > 0) {
msim_goto(HEIGHT - 1, 0);
while (i--)
msim_puts("\033D");
} else if (i < 0) {
msim_goto(0, 0);
while (i++)
msim_puts("\033M");
}
}
 
static void msim_client_connection(ipc_callid_t iid, ipc_call_t *icall)
{
int retval;
ipc_callid_t callid;
ipc_call_t call;
char c;
int lastcol = 0;
int lastrow = 0;
int newcol;
int newrow;
int fgcolor;
int bgcolor;
int i;
 
if (client_connected) {
ipc_answer_0(iid, ELIMIT);
return;
}
client_connected = 1;
ipc_answer_0(iid, EOK);
/* Clear the terminal, set scrolling region
to 0 - 25 lines */
msim_clrscr();
msim_goto(0, 0);
msim_puts("\033[0;25r");
while (true) {
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
client_connected = 0;
ipc_answer_0(callid, EOK);
return;
case FB_PUTCHAR:
c = IPC_GET_ARG1(call);
newrow = IPC_GET_ARG2(call);
newcol = IPC_GET_ARG3(call);
if ((lastcol != newcol) || (lastrow != newrow))
msim_goto(newrow, newcol);
lastcol = newcol + 1;
lastrow = newrow;
msim_putc(c);
retval = 0;
break;
case FB_CURSOR_GOTO:
newrow = IPC_GET_ARG1(call);
newcol = IPC_GET_ARG2(call);
msim_goto(newrow, newcol);
lastrow = newrow;
lastcol = newcol;
retval = 0;
break;
case FB_GET_CSIZE:
ipc_answer_2(callid, EOK, HEIGHT, WIDTH);
continue;
case FB_CLEAR:
msim_clrscr();
retval = 0;
break;
case FB_SET_STYLE:
fgcolor = IPC_GET_ARG1(call);
bgcolor = IPC_GET_ARG2(call);
if (fgcolor < bgcolor)
msim_set_style(0);
else
msim_set_style(7);
retval = 0;
break;
case FB_SCROLL:
i = IPC_GET_ARG1(call);
if ((i > HEIGHT) || (i < -HEIGHT)) {
retval = EINVAL;
break;
}
msim_scroll(i);
msim_goto(lastrow, lastcol);
retval = 0;
break;
case FB_CURSOR_VISIBILITY:
if(IPC_GET_ARG1(call))
msim_cursor_enable();
else
msim_cursor_disable();
retval = 0;
break;
default:
retval = ENOENT;
}
ipc_answer_0(callid, retval);
}
}
 
int msim_init(void)
{
void *phys_addr = (void *) sysinfo_value("fb.address.physical");
virt_addr = (char *) as_get_mappable_page(1);
physmem_map(phys_addr, virt_addr, 1, AS_AREA_READ | AS_AREA_WRITE);
if (physmem_map(phys_addr, virt_addr, 1, AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
async_set_client_connection(msim_client_connection);
serial_console_init(msim_putc, WIDTH, HEIGHT);
async_set_client_connection(serial_client_connection);
return 0;
}
 
/branches/arm/uspace/srv/fb/ski.c
0,0 → 1,84
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @defgroup msimfb MSIM text console
* @brief HelenOS MSIM text console.
* @ingroup fbs
* @{
*/
/** @file
*/
 
#include <async.h>
#include <libc.h>
#include <sysinfo.h>
#include <as.h>
#include <ddi.h>
 
#include "serial_console.h"
#include "ski.h"
 
#define SKI_PUTCHAR 31
 
#define WIDTH 80
#define HEIGHT 24
 
/** Display character on ski debug console
*
* Use SSC (Simulator System Call) to
* display character on debug console.
*
* @param ch Character to be printed.
*/
static void ski_putc(const char ch)
{
asm volatile (
"mov r15 = %0\n"
"mov r32 = %1\n" /* r32 is in0 */
"break 0x80000\n" /* modifies r8 */
:
: "i" (SKI_PUTCHAR), "r" (ch)
: "r15", "in0", "r8"
);
if (ch == '\n')
ski_putc('\r');
}
 
int ski_init(void)
{
serial_console_init(ski_putc, WIDTH, HEIGHT);
async_set_client_connection(serial_client_connection);
return 0;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fb/sgcn.c
0,0 → 1,142
/*
* Copyright (c) 2006 Ondrej Palkovsky
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @defgroup sgcnfb SGCN
* @brief userland driver of the Serengeti console output
* @{
*/
/** @file
*/
 
#include <async.h>
#include <sysinfo.h>
#include <as.h>
#include <errno.h>
#include <stdio.h>
#include <ddi.h>
 
#include "serial_console.h"
#include "sgcn.h"
 
#define WIDTH 80
#define HEIGHT 24
 
/**
* Virtual address mapped to SRAM.
*/
static uintptr_t sram_virt_addr;
 
/**
* SGCN buffer offset within SGCN.
*/
static uintptr_t sram_buffer_offset;
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[4];
/** we don't need this */
char unused[24];
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
/** offset within the SGCN buffer of the output buffer end */
uint32_t out_end;
/** offset within the SGCN buffer of the output buffer read pointer */
uint32_t out_rdptr;
/** offset within the SGCN buffer of the output buffer write pointer */
uint32_t out_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
/**
* Pushes the character to the SGCN serial.
* @param c character to be pushed
*/
static void sgcn_putc(char c)
{
uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
uint32_t end = SGCN_BUFFER_HEADER->out_end;
uint32_t size = end - begin;
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
 
uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
while (*out_rdptr_ptr == new_wrptr)
;
*buf_ptr = c;
*out_wrptr_ptr = new_wrptr;
}
 
/**
* Initializes the SGCN serial driver.
*/
int sgcn_init(void)
{
sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
if (physmem_map((void *) sysinfo_value("sram.address.physical"),
(void *) sram_virt_addr, sysinfo_value("sram.area.size") / PAGE_SIZE,
AS_AREA_READ | AS_AREA_WRITE) != 0)
return -1;
serial_console_init(sgcn_putc, WIDTH, HEIGHT);
sram_buffer_offset = sysinfo_value("sram.buffer.offset");
async_set_client_connection(serial_client_connection);
return 0;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fb/ski.h
0,0 → 1,46
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup skifb
* @brief HelenOS ski text console.
* @ingroup fbs
* @{
*/
/** @file
*/
 
#ifndef FB_SKI_H_
#define FB_SKI_H_
 
extern int ski_init(void);
 
#endif
 
/** @}
*/
 
/branches/arm/uspace/srv/fb/main.c
38,6 → 38,8
#include "fb.h"
#include "ega.h"
#include "msim.h"
#include "ski.h"
#include "sgcn.h"
#include "main.h"
 
#define NAME "fb"
45,7 → 47,7
void receive_comm_area(ipc_callid_t callid, ipc_call_t *call, void **area)
{
void *dest;
 
dest = as_get_mappable_page(IPC_GET_ARG2(*call));
if (ipc_answer_1(callid, EOK, (sysarg_t) dest) == 0) {
if (*area)
60,12 → 62,12
ipcarg_t phonead;
bool initialized = false;
 
#ifdef FB_ENABLED
if (sysinfo_value("fb.kind") == 1) {
if (fb_init() == 0)
initialized = true;
}
}
#endif
#ifdef EGA_ENABLED
if ((!initialized) && (sysinfo_value("fb.kind") == 2)) {
79,15 → 81,28
initialized = true;
}
#endif
#ifdef SGCN_ENABLED
if ((!initialized) && (sysinfo_value("fb.kind") == 4)) {
if (sgcn_init() == 0)
initialized = true;
}
#endif
#ifdef SKI_ENABLED
if ((!initialized) && (sysinfo_value("fb") != true)) {
if (ski_init() == 0)
initialized = true;
}
#endif
 
if (!initialized)
return -1;
 
if (ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, 0, &phonead) != 0)
return -1;
printf(NAME ": Accepting connections\n");
async_manager();
/* Never reached */
return 0;
}
/branches/arm/uspace/srv/fb/fb.h
29,7 → 29,7
/** @addtogroup fb
* @ingroup fbs
* @{
*/
*/
/** @file
*/
 
36,8 → 36,10
#ifndef FB_FB_H_
#define FB_FB_H_
 
typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, int);
#include <stdint.h>
 
typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, uint32_t);
 
extern int fb_init(void);
 
#endif
/branches/arm/uspace/srv/fb/sgcn.h
0,0 → 1,46
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @defgroup sgcnfb SGCN
* @brief userland driver of the Serengeti console output
* @{
*/
/** @file
*/
 
#ifndef FB_SGCN_H_
#define FB_SGCN_H_
 
int sgcn_init(void);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/bd/ata_bd/ata_bd.c
0,0 → 1,441
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup bd
* @{
*/
 
/**
* @file
* @brief ATA disk driver
*
* This driver currently works only with CHS addressing and uses PIO.
* Currently based on the (now obsolete) ANSI X3.221-1994 (ATA-1) standard.
* At this point only reading is possible, not writing.
*
* The driver services a single controller which can have up to two disks
* attached.
*/
 
#include <stdio.h>
#include <libarch/ddi.h>
#include <ddi.h>
#include <ipc/ipc.h>
#include <ipc/bd.h>
#include <async.h>
#include <as.h>
#include <fibril_sync.h>
#include <devmap.h>
#include <sys/types.h>
#include <errno.h>
#include <bool.h>
#include <task.h>
 
#include "ata_bd.h"
 
#define NAME "ata_bd"
 
static const size_t block_size = 512;
static size_t comm_size;
 
static uintptr_t cmd_physical = 0x1f0;
static uintptr_t ctl_physical = 0x170;
static ata_cmd_t *cmd;
static ata_ctl_t *ctl;
 
/** Per-disk state. */
static disk_t disk[MAX_DISKS];
 
static int ata_bd_init(void);
static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
void *buf);
static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
void *buf);
static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
const void *buf);
static int drive_identify(int drive_id, disk_t *d);
 
int main(int argc, char **argv)
{
uint8_t status;
char name[16];
int i, rc;
int n_disks;
 
printf(NAME ": ATA disk driver\n");
 
printf("I/O address 0x%x\n", cmd_physical);
 
if (ata_bd_init() != EOK)
return -1;
 
/* Put drives to reset, disable interrupts. */
printf("Reset drives... ");
fflush(stdout);
 
pio_write_8(&ctl->device_control, DCR_SRST);
/* FIXME: Find out how to do this properly. */
async_usleep(100);
pio_write_8(&ctl->device_control, 0);
 
do {
status = pio_read_8(&cmd->status);
} while ((status & SR_BSY) != 0);
printf("Done\n");
 
(void) drive_identify(0, &disk[0]);
(void) drive_identify(1, &disk[1]);
 
n_disks = 0;
 
for (i = 0; i < MAX_DISKS; i++) {
/* Skip unattached drives. */
if (disk[i].present == false)
continue;
 
snprintf(name, 16, "disk%d", i);
rc = devmap_device_register(name, &disk[i].dev_handle);
if (rc != EOK) {
devmap_hangup_phone(DEVMAP_DRIVER);
printf(NAME ": Unable to register device %s.\n",
name);
return rc;
}
++n_disks;
}
 
if (n_disks == 0) {
printf("No disks detected.\n");
return -1;
}
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
return 0;
}
 
static int drive_identify(int disk_id, disk_t *d)
{
uint16_t data;
uint8_t status;
size_t i;
 
printf("Identify drive %d... ", disk_id);
fflush(stdout);
 
pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0));
async_usleep(100);
pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
 
status = pio_read_8(&cmd->status);
 
d->present = false;
 
/*
* Detect if drive is present. This is Qemu only! Need to
* do the right thing to work with real drives.
*/
if ((status & SR_DRDY) == 0) {
printf("None attached.\n");
return ENOENT;
}
 
for (i = 0; i < block_size / 2; i++) {
do {
status = pio_read_8(&cmd->status);
} while ((status & SR_DRDY) == 0);
 
data = pio_read_16(&cmd->data_port);
 
switch (i) {
case 1: d->cylinders = data; break;
case 3: d->heads = data; break;
case 6: d->sectors = data; break;
}
}
 
d->blocks = d->cylinders * d->heads * d->sectors;
 
printf("Geometry: %u cylinders, %u heads, %u sectors\n",
d->cylinders, d->heads, d->sectors);
 
d->present = true;
fibril_mutex_initialize(&d->lock);
 
return EOK;
}
 
static int ata_bd_init(void)
{
void *vaddr;
int rc;
 
rc = devmap_driver_register(NAME, ata_bd_connection);
if (rc < 0) {
printf(NAME ": Unable to register driver.\n");
return rc;
}
 
rc = pio_enable((void *) cmd_physical, sizeof(ata_cmd_t), &vaddr);
if (rc != EOK) {
printf(NAME ": Could not initialize device I/O space.\n");
return rc;
}
 
cmd = vaddr;
 
rc = pio_enable((void *) ctl_physical, sizeof(ata_ctl_t), &vaddr);
if (rc != EOK) {
printf(NAME ": Could not initialize device I/O space.\n");
return rc;
}
 
ctl = vaddr;
 
 
return EOK;
}
 
static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
{
void *fs_va = NULL;
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t method;
dev_handle_t dh;
int flags;
int retval;
off_t idx;
size_t size;
int disk_id, i;
 
/* Get the device handle. */
dh = IPC_GET_ARG1(*icall);
 
/* Determine which disk device is the client connecting to. */
disk_id = -1;
for (i = 0; i < MAX_DISKS; i++)
if (disk[i].dev_handle == dh)
disk_id = i;
 
if (disk_id < 0 || disk[disk_id].present == false) {
ipc_answer_0(iid, EINVAL);
return;
}
 
/* Answer the IPC_M_CONNECT_ME_TO call. */
ipc_answer_0(iid, EOK);
 
if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
ipc_answer_0(callid, EHANGUP);
return;
}
 
fs_va = as_get_mappable_page(comm_size);
if (fs_va == NULL) {
ipc_answer_0(callid, EHANGUP);
return;
}
 
(void) ipc_share_out_finalize(callid, fs_va);
 
while (1) {
callid = async_get_call(&call);
method = IPC_GET_METHOD(call);
switch (method) {
case IPC_M_PHONE_HUNGUP:
/* The other side has hung up. */
ipc_answer_0(callid, EOK);
return;
case BD_READ_BLOCK:
case BD_WRITE_BLOCK:
idx = IPC_GET_ARG1(call);
size = IPC_GET_ARG2(call);
if (size > comm_size) {
retval = EINVAL;
break;
}
retval = ata_bd_rdwr(disk_id, method, idx,
size, fs_va);
break;
default:
retval = EINVAL;
break;
}
ipc_answer_0(callid, retval);
}
}
 
static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size,
void *buf)
{
int rc;
size_t now;
 
while (size > 0) {
now = size < block_size ? size : block_size;
if (now != block_size)
return EINVAL;
 
if (method == BD_READ_BLOCK)
rc = ata_bd_read_block(disk_id, blk_idx, 1, buf);
else
rc = ata_bd_write_block(disk_id, blk_idx, 1, buf);
 
if (rc != EOK)
return rc;
 
buf += block_size;
blk_idx++;
 
if (size > block_size)
size -= block_size;
else
size = 0;
}
 
return EOK;
}
 
 
static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
void *buf)
{
size_t i;
uint16_t data;
uint8_t status;
uint64_t c, h, s;
uint64_t idx;
uint8_t drv_head;
disk_t *d;
 
d = &disk[disk_id];
 
/* Check device bounds. */
if (blk_idx >= d->blocks)
return EINVAL;
 
/* Compute CHS. */
c = blk_idx / (d->heads * d->sectors);
idx = blk_idx % (d->heads * d->sectors);
 
h = idx / d->sectors;
s = 1 + (idx % d->sectors);
 
/* New value for Drive/Head register */
drv_head =
((disk_id != 0) ? DHR_DRV : 0) |
(h & 0x0f);
 
fibril_mutex_lock(&d->lock);
 
/* Program a Read Sectors operation. */
 
pio_write_8(&cmd->drive_head, drv_head);
pio_write_8(&cmd->sector_count, 1);
pio_write_8(&cmd->sector_number, s);
pio_write_8(&cmd->cylinder_low, c & 0xff);
pio_write_8(&cmd->cylinder_high, c >> 16);
pio_write_8(&cmd->command, CMD_READ_SECTORS);
 
/* Read data from the disk buffer. */
 
for (i = 0; i < block_size / 2; i++) {
do {
status = pio_read_8(&cmd->status);
} while ((status & SR_DRDY) == 0);
 
data = pio_read_16(&cmd->data_port);
((uint16_t *) buf)[i] = data;
}
 
fibril_mutex_unlock(&d->lock);
return EOK;
}
 
static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
const void *buf)
{
size_t i;
uint8_t status;
uint64_t c, h, s;
uint64_t idx;
uint8_t drv_head;
disk_t *d;
 
d = &disk[disk_id];
 
/* Check device bounds. */
if (blk_idx >= d->blocks)
return EINVAL;
 
/* Compute CHS. */
c = blk_idx / (d->heads * d->sectors);
idx = blk_idx % (d->heads * d->sectors);
 
h = idx / d->sectors;
s = 1 + (idx % d->sectors);
 
/* New value for Drive/Head register */
drv_head =
((disk_id != 0) ? DHR_DRV : 0) |
(h & 0x0f);
 
fibril_mutex_lock(&d->lock);
 
/* Program a Read Sectors operation. */
 
pio_write_8(&cmd->drive_head, drv_head);
pio_write_8(&cmd->sector_count, 1);
pio_write_8(&cmd->sector_number, s);
pio_write_8(&cmd->cylinder_low, c & 0xff);
pio_write_8(&cmd->cylinder_high, c >> 16);
pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
 
/* Write data to the disk buffer. */
 
for (i = 0; i < block_size / 2; i++) {
do {
status = pio_read_8(&cmd->status);
} while ((status & SR_DRDY) == 0);
 
pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
}
 
fibril_mutex_unlock(&d->lock);
return EOK;
}
 
 
/**
* @}
*/
/branches/arm/uspace/srv/bd/ata_bd/ata_bd.h
0,0 → 1,151
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup bd
* @{
*/
/** @file
*/
 
#ifndef __ATA_BD_H__
#define __ATA_BD_H__
 
#include <sys/types.h>
#include <fibril_sync.h>
 
enum {
CTL_READ_START = 0,
CTL_WRITE_START = 1,
};
 
enum {
STATUS_FAILURE = 0
};
 
enum {
MAX_DISKS = 2
};
 
/** ATA Command Register Block. */
typedef union {
/* Read/Write */
struct {
uint16_t data_port;
uint8_t sector_count;
uint8_t sector_number;
uint8_t cylinder_low;
uint8_t cylinder_high;
uint8_t drive_head;
uint8_t pad_rw0;
};
 
/* Read Only */
struct {
uint8_t pad_ro0;
uint8_t error;
uint8_t pad_ro1[5];
uint8_t status;
};
 
/* Write Only */
struct {
uint8_t pad_wo0;
uint8_t features;
uint8_t pad_wo1[5];
uint8_t command;
};
} ata_cmd_t;
 
typedef union {
/* Read */
struct {
uint8_t pad0[6];
uint8_t alt_status;
uint8_t drive_address;
};
 
/* Write */
struct {
uint8_t pad1[6];
uint8_t device_control;
uint8_t pad2;
};
} ata_ctl_t;
 
enum devctl_bits {
DCR_SRST = 0x04, /**< Software Reset */
DCR_nIEN = 0x02 /**< Interrupt Enable (negated) */
};
 
enum status_bits {
SR_BSY = 0x80, /**< Busy */
SR_DRDY = 0x40, /**< Drive Ready */
SR_DWF = 0x20, /**< Drive Write Fault */
SR_DSC = 0x10, /**< Drive Seek Complete */
SR_DRQ = 0x08, /**< Data Request */
SR_CORR = 0x04, /**< Corrected Data */
SR_IDX = 0x02, /**< Index */
SR_ERR = 0x01 /**< Error */
};
 
enum drive_head_bits {
DHR_DRV = 0x10
};
 
enum error_bits {
ER_BBK = 0x80, /**< Bad Block Detected */
ER_UNC = 0x40, /**< Uncorrectable Data Error */
ER_MC = 0x20, /**< Media Changed */
ER_IDNF = 0x10, /**< ID Not Found */
ER_MCR = 0x08, /**< Media Change Request */
ER_ABRT = 0x04, /**< Aborted Command */
ER_TK0NF = 0x02, /**< Track 0 Not Found */
ER_AMNF = 0x01 /**< Address Mark Not Found */
};
 
enum ata_command {
CMD_IDENTIFY_DRIVE = 0xEC,
CMD_READ_SECTORS = 0x20,
CMD_WRITE_SECTORS = 0x30
};
 
typedef struct {
bool present;
unsigned heads;
unsigned cylinders;
unsigned sectors;
uint64_t blocks;
 
fibril_mutex_t lock;
dev_handle_t dev_handle;
} disk_t;
 
#endif
 
/** @}
*/
/branches/arm/uspace/srv/bd/ata_bd/Makefile
0,0 → 1,76
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
 
LIBC_PREFIX = ../../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = ata_bd
SOURCES = \
ata_bd.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/bd/file_bd/file_bd.c
0,0 → 1,215
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup bd
* @{
*/
 
/**
* @file
* @brief File-backed block device driver
*
* Allows accessing a file as a block device. Useful for, e.g., mounting
* a disk image.
*/
 
#include <stdio.h>
#include <unistd.h>
#include <ipc/ipc.h>
#include <ipc/bd.h>
#include <async.h>
#include <as.h>
#include <fibril_sync.h>
#include <devmap.h>
#include <sys/types.h>
#include <errno.h>
#include <bool.h>
#include <task.h>
 
#define NAME "file_bd"
 
static size_t comm_size;
static FILE *img;
 
static dev_handle_t dev_handle;
static fibril_mutex_t dev_lock;
 
static int file_bd_init(const char *fname);
static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
static int file_bd_read(off_t blk_idx, size_t size, void *buf);
static int file_bd_write(off_t blk_idx, size_t size, void *buf);
 
int main(int argc, char **argv)
{
int rc;
 
printf(NAME ": File-backed block device driver\n");
 
if (argc != 3) {
printf("Expected two arguments (image name, device name).\n");
return -1;
}
 
if (file_bd_init(argv[1]) != EOK)
return -1;
 
rc = devmap_device_register(argv[2], &dev_handle);
if (rc != EOK) {
devmap_hangup_phone(DEVMAP_DRIVER);
printf(NAME ": Unable to register device %s.\n",
argv[2]);
return rc;
}
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
return 0;
}
 
static int file_bd_init(const char *fname)
{
int rc;
 
rc = devmap_driver_register(NAME, file_bd_connection);
if (rc < 0) {
printf(NAME ": Unable to register driver.\n");
return rc;
}
 
img = fopen(fname, "rb+");
if (img == NULL)
return EINVAL;
 
fibril_mutex_initialize(&dev_lock);
 
return EOK;
}
 
static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
{
void *fs_va = NULL;
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t method;
int flags;
int retval;
off_t idx;
size_t size;
 
/* Answer the IPC_M_CONNECT_ME_TO call. */
ipc_answer_0(iid, EOK);
 
if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
ipc_answer_0(callid, EHANGUP);
return;
}
 
fs_va = as_get_mappable_page(comm_size);
if (fs_va == NULL) {
ipc_answer_0(callid, EHANGUP);
return;
}
 
(void) ipc_share_out_finalize(callid, fs_va);
 
while (1) {
callid = async_get_call(&call);
method = IPC_GET_METHOD(call);
switch (method) {
case IPC_M_PHONE_HUNGUP:
/* The other side has hung up. */
ipc_answer_0(callid, EOK);
return;
case BD_READ_BLOCK:
case BD_WRITE_BLOCK:
idx = IPC_GET_ARG1(call);
size = IPC_GET_ARG2(call);
if (size > comm_size) {
retval = EINVAL;
break;
}
if (method == BD_READ_BLOCK)
retval = file_bd_read(idx, size, fs_va);
else
retval = file_bd_write(idx, size, fs_va);
break;
default:
retval = EINVAL;
break;
}
ipc_answer_0(callid, retval);
}
}
 
static int file_bd_read(off_t blk_idx, size_t size, void *buf)
{
size_t n_rd;
 
fibril_mutex_lock(&dev_lock);
 
fseek(img, blk_idx * size, SEEK_SET);
n_rd = fread(buf, 1, size, img);
 
if (ferror(img)) {
fibril_mutex_unlock(&dev_lock);
return EIO; /* Read error */
}
 
fibril_mutex_unlock(&dev_lock);
 
if (n_rd < size)
return EINVAL; /* Read beyond end of disk */
 
return EOK;
}
 
static int file_bd_write(off_t blk_idx, size_t size, void *buf)
{
size_t n_wr;
 
fibril_mutex_lock(&dev_lock);
 
fseek(img, blk_idx * size, SEEK_SET);
n_wr = fread(buf, 1, size, img);
 
if (ferror(img) || n_wr < size) {
fibril_mutex_unlock(&dev_lock);
return EIO; /* Write error */
}
 
fibril_mutex_unlock(&dev_lock);
 
return EOK;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/bd/file_bd/Makefile
0,0 → 1,76
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
 
LIBC_PREFIX = ../../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = file_bd
SOURCES = \
file_bd.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/bd/gxe_bd/gxe_bd.c
0,0 → 1,310
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup bd
* @{
*/
 
/**
* @file
* @brief GXemul disk driver
*/
 
#include <stdio.h>
#include <libarch/ddi.h>
#include <ddi.h>
#include <ipc/ipc.h>
#include <ipc/bd.h>
#include <async.h>
#include <as.h>
#include <fibril_sync.h>
#include <devmap.h>
#include <sys/types.h>
#include <errno.h>
#include <task.h>
 
#define NAME "gxe_bd"
 
enum {
CTL_READ_START = 0,
CTL_WRITE_START = 1,
};
 
enum {
STATUS_FAILURE = 0
};
 
enum {
MAX_DISKS = 2
};
 
typedef struct {
uint32_t offset_lo;
uint32_t pad0;
uint32_t offset_hi;
uint32_t pad1;
 
uint32_t disk_id;
uint32_t pad2[3];
 
uint32_t control;
uint32_t pad3[3];
 
uint32_t status;
 
uint32_t pad4[3];
uint8_t pad5[0x3fc0];
 
uint8_t buffer[512];
} gxe_bd_t;
 
 
static const size_t block_size = 512;
static size_t comm_size;
 
static uintptr_t dev_physical = 0x13000000;
static gxe_bd_t *dev;
 
static dev_handle_t dev_handle[MAX_DISKS];
 
static fibril_mutex_t dev_lock[MAX_DISKS];
 
static int gxe_bd_init(void);
static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
void *buf);
static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
void *buf);
static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
const void *buf);
 
int main(int argc, char **argv)
{
printf(NAME ": GXemul disk driver\n");
 
if (gxe_bd_init() != EOK)
return -1;
 
printf(NAME ": Accepting connections\n");
task_retval(0);
async_manager();
 
/* Not reached */
return 0;
}
 
static int gxe_bd_init(void)
{
void *vaddr;
int rc, i;
char name[16];
 
rc = devmap_driver_register(NAME, gxe_bd_connection);
if (rc < 0) {
printf(NAME ": Unable to register driver.\n");
return rc;
}
 
rc = pio_enable((void *) dev_physical, sizeof(gxe_bd_t), &vaddr);
if (rc != EOK) {
printf(NAME ": Could not initialize device I/O space.\n");
return rc;
}
 
dev = vaddr;
 
for (i = 0; i < MAX_DISKS; i++) {
snprintf(name, 16, "disk%d", i);
rc = devmap_device_register(name, &dev_handle[i]);
if (rc != EOK) {
devmap_hangup_phone(DEVMAP_DRIVER);
printf(NAME ": Unable to register device %s.\n",
name);
return rc;
}
fibril_mutex_initialize(&dev_lock[i]);
}
 
return EOK;
}
 
static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
{
void *fs_va = NULL;
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t method;
dev_handle_t dh;
int flags;
int retval;
off_t idx;
size_t size;
int disk_id, i;
 
/* Get the device handle. */
dh = IPC_GET_ARG1(*icall);
 
/* Determine which disk device is the client connecting to. */
disk_id = -1;
for (i = 0; i < MAX_DISKS; i++)
if (dev_handle[i] == dh)
disk_id = i;
 
if (disk_id < 0) {
ipc_answer_0(iid, EINVAL);
return;
}
 
/* Answer the IPC_M_CONNECT_ME_TO call. */
ipc_answer_0(iid, EOK);
 
if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
ipc_answer_0(callid, EHANGUP);
return;
}
 
fs_va = as_get_mappable_page(comm_size);
if (fs_va == NULL) {
ipc_answer_0(callid, EHANGUP);
return;
}
 
(void) ipc_share_out_finalize(callid, fs_va);
 
while (1) {
callid = async_get_call(&call);
method = IPC_GET_METHOD(call);
switch (method) {
case IPC_M_PHONE_HUNGUP:
/* The other side has hung up. */
ipc_answer_0(callid, EOK);
return;
case BD_READ_BLOCK:
case BD_WRITE_BLOCK:
idx = IPC_GET_ARG1(call);
size = IPC_GET_ARG2(call);
if (size > comm_size) {
retval = EINVAL;
break;
}
retval = gx_bd_rdwr(disk_id, method, idx * size,
size, fs_va);
break;
default:
retval = EINVAL;
break;
}
ipc_answer_0(callid, retval);
}
}
 
static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,
void *buf)
{
int rc;
size_t now;
 
while (size > 0) {
now = size < block_size ? size : block_size;
 
if (method == BD_READ_BLOCK)
rc = gxe_bd_read_block(disk_id, offset, now, buf);
else
rc = gxe_bd_write_block(disk_id, offset, now, buf);
 
if (rc != EOK)
return rc;
 
buf += block_size;
offset += block_size;
 
if (size > block_size)
size -= block_size;
else
size = 0;
}
 
return EOK;
}
 
static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size,
void *buf)
{
uint32_t status;
size_t i;
uint32_t w;
 
fibril_mutex_lock(&dev_lock[disk_id]);
pio_write_32(&dev->offset_lo, (uint32_t) offset);
pio_write_32(&dev->offset_hi, offset >> 32);
pio_write_32(&dev->disk_id, disk_id);
pio_write_32(&dev->control, CTL_READ_START);
 
status = pio_read_32(&dev->status);
if (status == STATUS_FAILURE) {
fibril_mutex_unlock(&dev_lock[disk_id]);
return EIO;
}
 
for (i = 0; i < size; i++) {
((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]);
}
 
fibril_mutex_unlock(&dev_lock[disk_id]);
return EOK;
}
 
static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size,
const void *buf)
{
uint32_t status;
size_t i;
 
for (i = 0; i < size; i++) {
pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]);
}
 
fibril_mutex_lock(&dev_lock[disk_id]);
pio_write_32(&dev->offset_lo, (uint32_t) offset);
pio_write_32(&dev->offset_hi, offset >> 32);
pio_write_32(&dev->disk_id, disk_id);
pio_write_32(&dev->control, CTL_WRITE_START);
 
status = pio_read_32(&dev->status);
if (status == STATUS_FAILURE) {
fibril_mutex_unlock(&dev_lock[disk_id]);
return EIO;
}
 
fibril_mutex_unlock(&dev_lock[disk_id]);
return EOK;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/bd/gxe_bd/Makefile
0,0 → 1,76
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
 
LIBC_PREFIX = ../../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = gxe_bd
SOURCES = \
gxe_bd.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/bd/rd/rd.c
0,0 → 1,241
/*
* Copyright (c) 2007 Michal Konopa
* Copyright (c) 2007 Martin Jelen
* Copyright (c) 2007 Peter Majer
* Copyright (c) 2007 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup rd
* @{
*/
 
/**
* @file rd.c
* @brief Initial RAM disk for HelenOS.
*/
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/ns.h>
#include <sysinfo.h>
#include <as.h>
#include <ddi.h>
#include <align.h>
#include <bool.h>
#include <errno.h>
#include <async.h>
#include <align.h>
#include <async.h>
#include <fibril_sync.h>
#include <stdio.h>
#include <devmap.h>
#include <ipc/bd.h>
 
#define NAME "rd"
 
/** Pointer to the ramdisk's image. */
static void *rd_addr;
/** Size of the ramdisk. */
static size_t rd_size;
 
/**
* This rwlock protects the ramdisk's data.
* If we were to serve multiple requests (read + write or several writes)
* concurrently (i.e. from two or more threads), each read and write needs to be
* protected by this rwlock.
*/
fibril_rwlock_t rd_lock;
 
/** Handle one connection to ramdisk.
*
* @param iid Hash of the request that opened the connection.
* @param icall Call data of the request that opened the connection.
*/
static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
int retval;
void *fs_va = NULL;
off_t offset;
size_t block_size;
size_t maxblock_size;
 
/*
* Answer the first IPC_M_CONNECT_ME_TO call.
*/
ipc_answer_0(iid, EOK);
 
/*
* Now we wait for the client to send us its communication as_area.
*/
int flags;
if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
fs_va = as_get_mappable_page(maxblock_size);
if (fs_va) {
(void) ipc_share_out_finalize(callid, fs_va);
} else {
ipc_answer_0(callid, EHANGUP);
return;
}
} else {
/*
* The client doesn't speak the same protocol.
* At this point we can't handle protocol variations.
* Close the connection.
*/
ipc_answer_0(callid, EHANGUP);
return;
}
while (true) {
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
/*
* The other side has hung up.
* Answer the message and exit the fibril.
*/
ipc_answer_0(callid, EOK);
return;
case BD_READ_BLOCK:
offset = IPC_GET_ARG1(call);
block_size = IPC_GET_ARG2(call);
if (block_size > maxblock_size) {
/*
* Maximum block size exceeded.
*/
retval = ELIMIT;
break;
}
if (offset * block_size > rd_size - block_size) {
/*
* Reading past the end of the device.
*/
retval = ELIMIT;
break;
}
fibril_rwlock_read_lock(&rd_lock);
memcpy(fs_va, rd_addr + offset * block_size, block_size);
fibril_rwlock_read_unlock(&rd_lock);
retval = EOK;
break;
case BD_WRITE_BLOCK:
offset = IPC_GET_ARG1(call);
block_size = IPC_GET_ARG2(call);
if (block_size > maxblock_size) {
/*
* Maximum block size exceeded.
*/
retval = ELIMIT;
break;
}
if (offset * block_size > rd_size - block_size) {
/*
* Writing past the end of the device.
*/
retval = ELIMIT;
break;
}
fibril_rwlock_write_lock(&rd_lock);
memcpy(rd_addr + offset * block_size, fs_va, block_size);
fibril_rwlock_write_unlock(&rd_lock);
retval = EOK;
break;
default:
/*
* The client doesn't speak the same protocol.
* Instead of closing the connection, we just ignore
* the call. This can be useful if the client uses a
* newer version of the protocol.
*/
retval = EINVAL;
break;
}
ipc_answer_0(callid, retval);
}
}
 
/** Prepare the ramdisk image for operation. */
static bool rd_init(void)
{
rd_size = sysinfo_value("rd.size");
void *rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
if (rd_size == 0) {
printf(NAME ": No RAM disk found\n");
return false;
}
rd_addr = as_get_mappable_page(rd_size);
int flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
int retval = physmem_map(rd_ph_addr, rd_addr,
ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
if (retval < 0) {
printf(NAME ": Error mapping RAM disk\n");
return false;
}
printf(NAME ": Found RAM disk at %p, %d bytes\n", rd_ph_addr, rd_size);
int rc = devmap_driver_register(NAME, rd_connection);
if (rc < 0) {
printf(NAME ": Unable to register driver (%d)\n", rc);
return false;
}
dev_handle_t dev_handle;
if (devmap_device_register("initrd", &dev_handle) != EOK) {
devmap_hangup_phone(DEVMAP_DRIVER);
printf(NAME ": Unable to register device\n");
return false;
}
 
fibril_rwlock_initialize(&rd_lock);
return true;
}
 
int main(int argc, char **argv)
{
printf(NAME ": HelenOS RAM disk server\n");
if (!rd_init())
return -1;
printf(NAME ": Accepting connections\n");
async_manager();
 
/* Never reached */
return 0;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/bd/rd/Makefile
0,0 → 1,76
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
 
LIBC_PREFIX = ../../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = rd
SOURCES = \
rd.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/ns/task.c
0,0 → 1,414
/*
* Copyright (c) 2009 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#include <ipc/ipc.h>
#include <adt/hash_table.h>
#include <bool.h>
#include <errno.h>
#include <assert.h>
#include <stdio.h>
#include <macros.h>
#include "task.h"
#include "ns.h"
 
#define TASK_HASH_TABLE_CHAINS 256
#define P2I_HASH_TABLE_CHAINS 256
 
static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id);
 
/* TODO:
*
* As there is currently no convention that each task has to be waited
* for, the NS can leak memory because of the zombie tasks.
*
*/
 
/** Task hash table item. */
typedef struct {
link_t link;
task_id_t id; /**< Task ID. */
bool finished; /**< Task is done. */
bool have_rval; /**< Task returned a value. */
int retval; /**< The return value. */
} hashed_task_t;
 
/** Compute hash index into task hash table.
*
* @param key Pointer keys. However, only the first key (i.e. truncated task
* number) is used to compute the hash index.
*
* @return Hash index corresponding to key[0].
*
*/
static hash_index_t task_hash(unsigned long *key)
{
assert(key);
return (LOWER32(*key) % TASK_HASH_TABLE_CHAINS);
}
 
/** Compare a key with hashed item.
*
* @param key Array of keys.
* @param keys Must be less than or equal to 2.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
*
*/
static int task_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
assert(key);
assert(keys <= 2);
assert(item);
hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link);
if (keys == 2)
return ((LOWER32(key[1]) == UPPER32(ht->id))
&& (LOWER32(key[0]) == LOWER32(ht->id)));
else
return (LOWER32(key[0]) == LOWER32(ht->id));
}
 
/** Perform actions after removal of item from the hash table.
*
* @param item Item that was removed from the hash table.
*
*/
static void task_remove(link_t *item)
{
assert(item);
free(hash_table_get_instance(item, hashed_task_t, link));
}
 
/** Operations for task hash table. */
static hash_table_operations_t task_hash_table_ops = {
.hash = task_hash,
.compare = task_compare,
.remove_callback = task_remove
};
 
/** Task hash table structure. */
static hash_table_t task_hash_table;
 
typedef struct {
link_t link;
ipcarg_t phash; /**< Task ID. */
task_id_t id; /**< Task ID. */
} p2i_entry_t;
 
/** Compute hash index into task hash table.
*
* @param key Array of keys.
* @return Hash index corresponding to key[0].
*
*/
static hash_index_t p2i_hash(unsigned long *key)
{
assert(key);
return (*key % TASK_HASH_TABLE_CHAINS);
}
 
/** Compare a key with hashed item.
*
* @param key Array of keys.
* @param keys Must be less than or equal to 1.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
*
*/
static int p2i_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
assert(key);
assert(keys == 1);
assert(item);
 
p2i_entry_t *e = hash_table_get_instance(item, p2i_entry_t, link);
 
return (key[0] == e->phash);
}
 
/** Perform actions after removal of item from the hash table.
*
* @param item Item that was removed from the hash table.
*
*/
static void p2i_remove(link_t *item)
{
assert(item);
free(hash_table_get_instance(item, p2i_entry_t, link));
}
 
/** Operations for task hash table. */
static hash_table_operations_t p2i_ops = {
.hash = p2i_hash,
.compare = p2i_compare,
.remove_callback = p2i_remove
};
 
/** Map phone hash to task ID */
static hash_table_t phone_to_id;
 
/** Pending task wait structure. */
typedef struct {
link_t link;
task_id_t id; /**< Task ID. */
ipc_callid_t callid; /**< Call ID waiting for the connection */
} pending_wait_t;
 
static link_t pending_wait;
 
int task_init(void)
{
if (!hash_table_create(&task_hash_table, TASK_HASH_TABLE_CHAINS,
2, &task_hash_table_ops)) {
printf(NAME ": No memory available for tasks\n");
return ENOMEM;
}
 
if (!hash_table_create(&phone_to_id, P2I_HASH_TABLE_CHAINS,
1, &p2i_ops)) {
printf(NAME ": No memory available for tasks\n");
return ENOMEM;
}
list_initialize(&pending_wait);
return EOK;
}
 
/** Process pending wait requests */
void process_pending_wait(void)
{
link_t *cur;
task_exit_t texit;
loop:
for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) {
pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link);
unsigned long keys[2] = {
LOWER32(pr->id),
UPPER32(pr->id)
};
link_t *link = hash_table_find(&task_hash_table, keys);
if (!link)
continue;
hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link);
if (!ht->finished)
continue;
if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
texit = ht->have_rval ? TASK_EXIT_NORMAL :
TASK_EXIT_UNEXPECTED;
ipc_answer_2(pr->callid, EOK, texit,
ht->retval);
}
 
hash_table_remove(&task_hash_table, keys, 2);
list_remove(cur);
free(pr);
goto loop;
}
}
 
void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
{
ipcarg_t retval;
task_exit_t texit;
 
unsigned long keys[2] = {
LOWER32(id),
UPPER32(id)
};
 
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht = (link != NULL) ?
hash_table_get_instance(link, hashed_task_t, link) : NULL;
 
if (ht == NULL) {
/* No such task exists. */
retval = ENOENT;
goto out;
}
 
if (!ht->finished) {
/* Add to pending list */
pending_wait_t *pr =
(pending_wait_t *) malloc(sizeof(pending_wait_t));
if (!pr) {
retval = ENOMEM;
goto out;
}
pr->id = id;
pr->callid = callid;
list_append(&pr->link, &pending_wait);
return;
}
hash_table_remove(&task_hash_table, keys, 2);
retval = EOK;
out:
if (!(callid & IPC_CALLID_NOTIFICATION)) {
texit = ht->have_rval ? TASK_EXIT_NORMAL : TASK_EXIT_UNEXPECTED;
ipc_answer_2(callid, retval, texit, ht->retval);
}
}
 
int ns_task_id_intro(ipc_call_t *call)
{
task_id_t id;
unsigned long keys[2];
link_t *link;
p2i_entry_t *e;
hashed_task_t *ht;
 
id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
 
keys[0] = call->in_phone_hash;
 
link = hash_table_find(&phone_to_id, keys);
if (link != NULL)
return EEXISTS;
 
e = (p2i_entry_t *) malloc(sizeof(p2i_entry_t));
if (e == NULL)
return ENOMEM;
 
ht = (hashed_task_t *) malloc(sizeof(hashed_task_t));
if (ht == NULL)
return ENOMEM;
 
/* Insert to phone-to-id map. */
 
link_initialize(&e->link);
e->phash = call->in_phone_hash;
e->id = id;
hash_table_insert(&phone_to_id, keys, &e->link);
 
/* Insert to main table. */
 
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
 
link_initialize(&ht->link);
ht->id = id;
ht->finished = false;
ht->have_rval = false;
ht->retval = -1;
hash_table_insert(&task_hash_table, keys, &ht->link);
 
return EOK;
}
 
int ns_task_retval(ipc_call_t *call)
{
task_id_t id;
unsigned long keys[2];
int rc;
 
rc = get_id_by_phone(call->in_phone_hash, &id);
if (rc != EOK)
return rc;
 
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht = (link != NULL) ?
hash_table_get_instance(link, hashed_task_t, link) : NULL;
if ((ht == NULL) || ht->finished)
return EINVAL;
 
ht->finished = true;
ht->have_rval = true;
ht->retval = IPC_GET_ARG1(*call);
 
return EOK;
}
 
int ns_task_disconnect(ipc_call_t *call)
{
unsigned long keys[2];
task_id_t id;
int rc;
 
rc = get_id_by_phone(call->in_phone_hash, &id);
if (rc != EOK)
return rc;
 
/* Delete from phone-to-id map. */
keys[0] = call->in_phone_hash;
hash_table_remove(&phone_to_id, keys, 1);
 
/* Mark task as finished. */
keys[0] = LOWER32(id);
keys[1] = UPPER32(id);
 
link_t *link = hash_table_find(&task_hash_table, keys);
hashed_task_t *ht =
hash_table_get_instance(link, hashed_task_t, link);
if (ht == NULL)
return EOK;
 
ht->finished = true;
 
return EOK;
}
 
static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id)
{
unsigned long keys[1];
link_t *link;
p2i_entry_t *e;
 
keys[0] = phone_hash;
link = hash_table_find(&phone_to_id, keys);
if (link == NULL)
return ENOENT;
 
e = hash_table_get_instance(link, p2i_entry_t, link);
*id = e->id;
 
return EOK;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/ns.c
28,77 → 28,55
 
/** @addtogroup ns
* @{
*/
*/
 
/**
* @file ns.c
* @brief Naming service for HelenOS IPC.
* @file ns.c
* @brief Naming service for HelenOS IPC.
*/
 
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/ns.h>
#include <ipc/services.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <libadt/list.h>
#include <libadt/hash_table.h>
#include <as.h>
#include <ddi.h>
#include <event.h>
#include <macros.h>
#include <sysinfo.h>
#include <ddi.h>
#include <as.h>
#include "ns.h"
#include "service.h"
#include "clonable.h"
#include "task.h"
 
#define NAME "ns"
 
#define NS_HASH_TABLE_CHAINS 20
 
static int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call);
static int connect_to_service(ipcarg_t service, ipc_call_t *call,
ipc_callid_t callid);
 
/* Static functions implementing NS hash table operations. */
static hash_index_t ns_hash(unsigned long *key);
static int ns_compare(unsigned long *key, hash_count_t keys, link_t *item);
static void ns_remove(link_t *item);
 
/** Operations for NS hash table. */
static hash_table_operations_t ns_hash_table_ops = {
.hash = ns_hash,
.compare = ns_compare,
.remove_callback = ns_remove
};
 
/** NS hash table structure. */
static hash_table_t ns_hash_table;
 
/** NS hash table item. */
typedef struct {
link_t link;
ipcarg_t service; /**< Number of the service. */
ipcarg_t phone; /**< Phone registered with the service. */
ipcarg_t in_phone_hash; /**< Incoming phone hash. */
} hashed_service_t;
 
static void *clockaddr = NULL;
static void *klogaddr = NULL;
 
static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name,
void **addr)
static void get_as_area(ipc_callid_t callid, ipc_call_t *call, void *ph_addr,
size_t pages, void **addr)
{
void *ph_addr;
 
if (!*addr) {
ph_addr = (void *) sysinfo_value(name);
if (!ph_addr) {
if (ph_addr == NULL) {
ipc_answer_0(callid, ENOENT);
return;
}
if (*addr == NULL) {
*addr = as_get_mappable_page(pages * PAGE_SIZE);
if (*addr == NULL) {
ipc_answer_0(callid, ENOENT);
return;
}
*addr = as_get_mappable_page(PAGE_SIZE);
physmem_map(ph_addr, *addr, 1,
AS_AREA_READ | AS_AREA_CACHEABLE);
if (physmem_map(ph_addr, *addr, pages,
AS_AREA_READ | AS_AREA_CACHEABLE) != 0) {
ipc_answer_0(callid, ENOENT);
return;
}
}
ipc_answer_2(callid, EOK, (ipcarg_t) *addr, AS_AREA_READ);
}
 
106,30 → 84,42
{
printf(NAME ": HelenOS IPC Naming Service\n");
ipc_call_t call;
ipc_callid_t callid;
int rc = service_init();
if (rc != EOK)
return rc;
ipcarg_t retval;
 
if (!hash_table_create(&ns_hash_table, NS_HASH_TABLE_CHAINS, 3,
&ns_hash_table_ops)) {
printf(NAME ": No memory available\n");
return ENOMEM;
}
rc = clonable_init();
if (rc != EOK)
return rc;
rc = task_init();
if (rc != EOK)
return rc;
printf(NAME ": Accepting connections\n");
while (1) {
callid = ipc_wait_for_call(&call);
while (true) {
process_pending_conn();
process_pending_wait();
ipc_call_t call;
ipc_callid_t callid = ipc_wait_for_call(&call);
task_id_t id;
ipcarg_t retval;
switch (IPC_GET_METHOD(call)) {
case IPC_M_SHARE_IN:
switch (IPC_GET_ARG3(call)) {
case SERVICE_MEM_REALTIME:
get_as_area(callid, &call, "clock.faddr",
&clockaddr);
get_as_area(callid, &call,
(void *) sysinfo_value("clock.faddr"),
1, &clockaddr);
break;
case SERVICE_MEM_KLOG:
get_as_area(callid, &call, "klog.faddr",
&klogaddr);
get_as_area(callid, &call,
(void *) sysinfo_value("klog.faddr"),
sysinfo_value("klog.pages"), &klogaddr);
break;
default:
ipc_answer_0(callid, ENOENT);
136,29 → 126,56
}
continue;
case IPC_M_PHONE_HUNGUP:
retval = EOK;
retval = ns_task_disconnect(&call);
break;
case IPC_M_CONNECT_TO_ME:
/*
* Server requests service registration.
*/
retval = register_service(IPC_GET_ARG1(call),
IPC_GET_ARG5(call), &call);
if (service_clonable(IPC_GET_ARG1(call))) {
register_clonable(IPC_GET_ARG1(call),
IPC_GET_ARG5(call), &call, callid);
continue;
} else {
retval = register_service(IPC_GET_ARG1(call),
IPC_GET_ARG5(call), &call);
}
break;
case IPC_M_CONNECT_ME_TO:
/*
* Client requests to be connected to a service.
*/
retval = connect_to_service(IPC_GET_ARG1(call), &call,
callid);
if (service_clonable(IPC_GET_ARG1(call))) {
connect_to_clonable(IPC_GET_ARG1(call),
&call, callid);
continue;
} else {
connect_to_service(IPC_GET_ARG1(call), &call,
callid);
continue;
}
break;
case NS_PING:
retval = EOK;
break;
case NS_TASK_WAIT:
id = (task_id_t)
MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
wait_for_task(id, &call, callid);
continue;
case NS_ID_INTRO:
retval = ns_task_id_intro(&call);
break;
case NS_RETVAL:
retval = ns_task_retval(&call);
break;
default:
retval = ENOENT;
break;
}
if (!(callid & IPC_CALLID_NOTIFICATION)) {
if (!(callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(callid, retval);
}
}
/* Not reached */
165,115 → 182,6
return 0;
}
 
/** Register service.
*
* @param service Service to be registered.
* @param phone Phone to be used for connections to the service.
* @param call Pointer to call structure.
*
* @return Zero on success or a value from @ref errno.h.
*/
int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call)
{
unsigned long keys[3] = {
service,
call->in_phone_hash,
0
};
hashed_service_t *hs;
if (hash_table_find(&ns_hash_table, keys)) {
return EEXISTS;
}
hs = (hashed_service_t *) malloc(sizeof(hashed_service_t));
if (!hs) {
return ENOMEM;
}
link_initialize(&hs->link);
hs->service = service;
hs->phone = phone;
hs->in_phone_hash = call->in_phone_hash;
hash_table_insert(&ns_hash_table, keys, &hs->link);
return 0;
}
 
/** Connect client to service.
*
* @param service Service to be connected to.
* @param call Pointer to call structure.
* @param callid Call ID of the request.
*
* @return Zero on success or a value from @ref errno.h.
*/
int connect_to_service(ipcarg_t service, ipc_call_t *call, ipc_callid_t callid)
{
unsigned long keys[3] = { service, 0, 0 };
link_t *hlp;
hashed_service_t *hs;
hlp = hash_table_find(&ns_hash_table, keys);
if (!hlp) {
return ENOENT;
}
hs = hash_table_get_instance(hlp, hashed_service_t, link);
return ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
}
 
/** Compute hash index into NS hash table.
*
* @param key Pointer keys. However, only the first key (i.e. service number)
* is used to compute the hash index.
* @return Hash index corresponding to key[0].
*/
hash_index_t ns_hash(unsigned long *key)
{
assert(key);
return *key % NS_HASH_TABLE_CHAINS;
}
 
/** Compare a key with hashed item.
*
* This compare function always ignores the third key.
* It exists only to make it possible to remove records
* originating from connection with key[1] in_phone_hash
* value. Note that this is close to being classified
* as a nasty hack.
*
* @param key Array of keys.
* @param keys Must be lesser or equal to 3.
* @param item Pointer to a hash table item.
* @return Non-zero if the key matches the item, zero otherwise.
*/
int ns_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
hashed_service_t *hs;
 
assert(key);
assert(keys <= 3);
assert(item);
hs = hash_table_get_instance(item, hashed_service_t, link);
if (keys == 2)
return key[1] == hs->in_phone_hash;
else
return key[0] == hs->service;
}
 
/** Perform actions after removal of item from the hash table.
*
* @param item Item that was removed from the hash table.
*/
void ns_remove(link_t *item)
{
assert(item);
free(hash_table_get_instance(item, hashed_service_t, link));
}
 
/**
/**
* @}
*/
/branches/arm/uspace/srv/ns/task.h
0,0 → 1,54
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#ifndef NS_TASK_H__
#define NS_TASK_H__
 
#include <ipc/ipc.h>
#include <event.h>
 
extern int task_init(void);
extern void process_pending_wait(void);
 
extern void wait_notification(wait_type_t et, task_id_t id);
extern void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid);
 
extern int ns_task_id_intro(ipc_call_t *call);
extern int ns_task_disconnect(ipc_call_t *call);
extern int ns_task_retval(ipc_call_t *call);
 
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/clonable.c
0,0 → 1,143
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <adt/list.h>
#include <bool.h>
#include <errno.h>
#include <assert.h>
#include <stdio.h>
#include <malloc.h>
#include <loader/loader.h>
#include "clonable.h"
#include "ns.h"
 
/** Request for connection to a clonable service. */
typedef struct {
link_t link;
ipcarg_t service;
ipc_call_t call;
ipc_callid_t callid;
} cs_req_t;
 
/** List of clonable-service connection requests. */
static link_t cs_req;
 
int clonable_init(void)
{
list_initialize(&cs_req);
return EOK;
}
 
/** Return true if @a service is clonable. */
bool service_clonable(int service)
{
return (service == SERVICE_LOAD);
}
 
/** Register clonable service.
*
* @param service Service to be registered.
* @param phone Phone to be used for connections to the service.
* @param call Pointer to call structure.
*
*/
void register_clonable(ipcarg_t service, ipcarg_t phone, ipc_call_t *call,
ipc_callid_t callid)
{
if (list_empty(&cs_req)) {
/* There was no pending connection request. */
printf(NAME ": Unexpected clonable server.\n");
ipc_answer_0(callid, EBUSY);
return;
}
cs_req_t *csr = list_get_instance(cs_req.next, cs_req_t, link);
list_remove(&csr->link);
/* Currently we can only handle a single type of clonable service. */
assert(csr->service == SERVICE_LOAD);
ipc_answer_0(callid, EOK);
ipc_forward_fast(csr->callid, phone, IPC_GET_ARG2(csr->call),
IPC_GET_ARG3(csr->call), 0, IPC_FF_NONE);
free(csr);
ipc_hangup(phone);
}
 
/** Connect client to clonable service.
*
* @param service Service to be connected to.
* @param call Pointer to call structure.
* @param callid Call ID of the request.
*
* @return Zero on success or a value from @ref errno.h.
*
*/
void connect_to_clonable(ipcarg_t service, ipc_call_t *call,
ipc_callid_t callid)
{
assert(service == SERVICE_LOAD);
cs_req_t *csr = malloc(sizeof(cs_req_t));
if (csr == NULL) {
ipc_answer_0(callid, ENOMEM);
return;
}
/* Spawn a loader. */
int rc = loader_spawn("loader");
if (rc < 0) {
free(csr);
ipc_answer_0(callid, rc);
return;
}
csr->service = service;
csr->call = *call;
csr->callid = callid;
/*
* We can forward the call only after the server we spawned connects
* to us. Meanwhile we might need to service more connection requests.
* Thus we store the call in a queue.
*/
list_append(&csr->link, &cs_req);
}
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/service.c
0,0 → 1,254
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#include <ipc/ipc.h>
#include <adt/hash_table.h>
#include <assert.h>
#include <errno.h>
#include "service.h"
#include "ns.h"
 
#define SERVICE_HASH_TABLE_CHAINS 20
 
/** Service hash table item. */
typedef struct {
link_t link;
ipcarg_t service; /**< Number of the service. */
ipcarg_t phone; /**< Phone registered with the service. */
ipcarg_t in_phone_hash; /**< Incoming phone hash. */
} hashed_service_t;
 
/** Compute hash index into service hash table.
*
* @param key Pointer keys. However, only the first key (i.e. service number)
* is used to compute the hash index.
*
* @return Hash index corresponding to key[0].
*
*/
static hash_index_t service_hash(unsigned long *key)
{
assert(key);
return (*key % SERVICE_HASH_TABLE_CHAINS);
}
 
/** Compare a key with hashed item.
*
* This compare function always ignores the third key.
* It exists only to make it possible to remove records
* originating from connection with key[1] in_phone_hash
* value. Note that this is close to being classified
* as a nasty hack.
*
* @param key Array of keys.
* @param keys Must be lesser or equal to 3.
* @param item Pointer to a hash table item.
*
* @return Non-zero if the key matches the item, zero otherwise.
*
*/
static int service_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
assert(key);
assert(keys <= 3);
assert(item);
hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link);
if (keys == 2)
return (key[1] == hs->in_phone_hash);
else
return (key[0] == hs->service);
}
 
/** Perform actions after removal of item from the hash table.
*
* @param item Item that was removed from the hash table.
*
*/
static void service_remove(link_t *item)
{
assert(item);
free(hash_table_get_instance(item, hashed_service_t, link));
}
 
/** Operations for service hash table. */
static hash_table_operations_t service_hash_table_ops = {
.hash = service_hash,
.compare = service_compare,
.remove_callback = service_remove
};
 
/** Service hash table structure. */
static hash_table_t service_hash_table;
 
/** Pending connection structure. */
typedef struct {
link_t link;
ipcarg_t service; /**< Number of the service. */
ipc_callid_t callid; /**< Call ID waiting for the connection */
ipcarg_t arg2; /**< Second argument */
ipcarg_t arg3; /**< Third argument */
} pending_conn_t;
 
static link_t pending_conn;
 
int service_init(void)
{
if (!hash_table_create(&service_hash_table, SERVICE_HASH_TABLE_CHAINS,
3, &service_hash_table_ops)) {
printf(NAME ": No memory available for services\n");
return ENOMEM;
}
list_initialize(&pending_conn);
return EOK;
}
 
/** Process pending connection requests */
void process_pending_conn(void)
{
link_t *cur;
loop:
for (cur = pending_conn.next; cur != &pending_conn; cur = cur->next) {
pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link);
unsigned long keys[3] = {
pr->service,
0,
0
};
link_t *link = hash_table_find(&service_hash_table, keys);
if (!link)
continue;
hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link);
ipcarg_t retval = ipc_forward_fast(pr->callid, hs->phone,
pr->arg2, pr->arg3, 0, IPC_FF_NONE);
if (!(pr->callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(pr->callid, retval);
list_remove(cur);
free(pr);
goto loop;
}
}
 
/** Register service.
*
* @param service Service to be registered.
* @param phone Phone to be used for connections to the service.
* @param call Pointer to call structure.
*
* @return Zero on success or a value from @ref errno.h.
*
*/
int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call)
{
unsigned long keys[3] = {
service,
call->in_phone_hash,
0
};
if (hash_table_find(&service_hash_table, keys))
return EEXISTS;
hashed_service_t *hs = (hashed_service_t *) malloc(sizeof(hashed_service_t));
if (!hs)
return ENOMEM;
link_initialize(&hs->link);
hs->service = service;
hs->phone = phone;
hs->in_phone_hash = call->in_phone_hash;
hash_table_insert(&service_hash_table, keys, &hs->link);
return 0;
}
 
/** Connect client to service.
*
* @param service Service to be connected to.
* @param call Pointer to call structure.
* @param callid Call ID of the request.
*
* @return Zero on success or a value from @ref errno.h.
*
*/
void connect_to_service(ipcarg_t service, ipc_call_t *call, ipc_callid_t callid)
{
ipcarg_t retval;
unsigned long keys[3] = {
service,
0,
0
};
link_t *link = hash_table_find(&service_hash_table, keys);
if (!link) {
if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) {
/* Blocking connection, add to pending list */
pending_conn_t *pr =
(pending_conn_t *) malloc(sizeof(pending_conn_t));
if (!pr) {
retval = ENOMEM;
goto out;
}
pr->service = service;
pr->callid = callid;
pr->arg2 = IPC_GET_ARG2(*call);
pr->arg3 = IPC_GET_ARG3(*call);
list_append(&pr->link, &pending_conn);
return;
}
retval = ENOENT;
goto out;
}
hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link);
retval = ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
out:
if (!(callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(callid, retval);
}
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/clonable.h
0,0 → 1,51
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#ifndef NS_CLONABLE_H__
#define NS_CLONABLE_H__
 
#include <ipc/ipc.h>
#include <bool.h>
 
extern int clonable_init(void);
 
extern bool service_clonable(int service);
extern void register_clonable(ipcarg_t service, ipcarg_t phone,
ipc_call_t *call, ipc_callid_t callid);
extern void connect_to_clonable(ipcarg_t service, ipc_call_t *call,
ipc_callid_t callid);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/ns.h
0,0 → 1,42
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#ifndef NS_NS_H__
#define NS_NS_H__
 
#define NAME "ns"
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/service.h
0,0 → 1,49
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ns
* @{
*/
 
#ifndef NS_SERVICE_H__
#define NS_SERVICE_H__
 
#include <ipc/ipc.h>
 
extern int service_init(void);
extern void process_pending_conn(void);
 
extern int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call);
extern void connect_to_service(ipcarg_t service, ipc_call_t *call,
ipc_callid_t callid);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/ns/Makefile
31,6 → 31,7
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
40,7 → 41,10
 
OUTPUT = ns
SOURCES = \
ns.c
ns.c \
service.c \
clonable.c \
task.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
51,18 → 55,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/loader/main.c
27,12 → 27,12
*/
 
/** @addtogroup loader
* @brief Loads and runs programs from VFS.
* @brief Loads and runs programs from VFS.
* @{
*/
*/
/**
* @file
* @brief Loads and runs programs from VFS.
* @brief Loads and runs programs from VFS.
*
* The program loader is a special init binary. Its image is used
* to create a new task upon a @c task_spawn syscall. The syscall
50,20 → 50,20
#include <fcntl.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/loader.h>
#include <ipc/ns.h>
#include <macros.h>
#include <loader/pcb.h>
#include <errno.h>
#include <async.h>
#include <string.h>
#include <as.h>
 
#include <elf.h>
#include <elf_load.h>
 
/**
* Bias used for loading the dynamic linker. This will be soon replaced
* by automatic placement.
*/
#define RTLD_BIAS 0x80000
#define DPRINTF(...)
 
/** Pathname of the file that will be loaded */
static char *pathname = NULL;
78,28 → 78,38
/** Buffer holding all arguments */
static char *arg_buf = NULL;
 
/** Number of preset files */
static int filc = 0;
/** Preset files vector */
static fdi_node_t **filv = NULL;
/** Buffer holding all preset files */
static fdi_node_t *fil_buf = NULL;
 
static elf_info_t prog_info;
static elf_info_t interp_info;
 
static bool is_dyn_linked;
 
/** Used to limit number of connections to one. */
static bool connected;
 
static void loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
task_id_t task_id;
size_t len;
 
task_id = task_get_id();
 
if (!ipc_data_read_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
if (len > sizeof(task_id)) len = sizeof(task_id);
 
if (len > sizeof(task_id))
len = sizeof(task_id);
ipc_data_read_finalize(callid, &task_id, len);
ipc_answer_0(rid, EOK);
}
110,18 → 120,18
* @param rid
* @param request
*/
static void loader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t len;
char *name_buf;
 
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
name_buf = malloc(len + 1);
if (!name_buf) {
ipc_answer_0(callid, ENOMEM);
128,15 → 138,15
ipc_answer_0(rid, ENOMEM);
return;
}
 
ipc_data_write_finalize(callid, name_buf, len);
ipc_answer_0(rid, EOK);
 
if (pathname != NULL) {
free(pathname);
pathname = NULL;
}
 
name_buf[len] = '\0';
pathname = name_buf;
}
146,58 → 156,56
* @param rid
* @param request
*/
static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t buf_len, arg_len;
size_t buf_size, arg_size;
char *p;
int n;
 
if (!ipc_data_write_receive(&callid, &buf_len)) {
if (!ipc_data_write_receive(&callid, &buf_size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
if (arg_buf != NULL) {
free(arg_buf);
arg_buf = NULL;
}
 
if (argv != NULL) {
free(argv);
argv = NULL;
}
 
arg_buf = malloc(buf_len + 1);
arg_buf = malloc(buf_size + 1);
if (!arg_buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
ipc_data_write_finalize(callid, arg_buf, buf_len);
ipc_answer_0(rid, EOK);
 
arg_buf[buf_len] = '\0';
 
ipc_data_write_finalize(callid, arg_buf, buf_size);
arg_buf[buf_size] = '\0';
/*
* Count number of arguments
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
arg_len = strlen(p);
p = p + arg_len + 1;
while (p < arg_buf + buf_size) {
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
 
/* Allocate argv */
argv = malloc((n + 1) * sizeof(char *));
 
if (argv == NULL) {
free(arg_buf);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
207,18 → 215,84
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
while (p < arg_buf + buf_size) {
argv[n] = p;
 
arg_len = strlen(p);
p = p + arg_len + 1;
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
 
argc = n;
argv[n] = NULL;
 
ipc_answer_0(rid, EOK);
}
 
/** Receive a call setting preset files of the program to execute.
*
* @param rid
* @param request
*/
static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t buf_size;
if (!ipc_data_write_receive(&callid, &buf_size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
if ((buf_size % sizeof(fdi_node_t)) != 0) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
if (fil_buf != NULL) {
free(fil_buf);
fil_buf = NULL;
}
if (filv != NULL) {
free(filv);
filv = NULL;
}
fil_buf = malloc(buf_size);
if (!fil_buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
ipc_data_write_finalize(callid, fil_buf, buf_size);
int count = buf_size / sizeof(fdi_node_t);
/* Allocate filvv */
filv = malloc((count + 1) * sizeof(fdi_node_t *));
if (filv == NULL) {
free(fil_buf);
ipc_answer_0(rid, ENOMEM);
return;
}
/*
* Fill filv with argument pointers
*/
int i;
for (i = 0; i < count; i++)
filv[i] = &fil_buf[i];
filc = count;
filv[count] = NULL;
ipc_answer_0(rid, EOK);
}
 
/** Load the previously selected program.
*
* @param rid
225,51 → 299,43
* @param request
* @return 0 on success, !0 on error.
*/
static int loader_load(ipc_callid_t rid, ipc_call_t *request)
static int ldr_load(ipc_callid_t rid, ipc_call_t *request)
{
int rc;
 
// printf("Load program '%s'\n", pathname);
 
rc = elf_load_file(pathname, 0, &prog_info);
if (rc < 0) {
printf("failed to load program\n");
if (rc != EE_OK) {
DPRINTF("Failed to load executable '%s'.\n", pathname);
ipc_answer_0(rid, EINVAL);
return 1;
}
 
// printf("Create PCB\n");
elf_create_pcb(&prog_info, &pcb);
 
pcb.argc = argc;
pcb.argv = argv;
 
pcb.filc = filc;
pcb.filv = filv;
if (prog_info.interp == NULL) {
/* Statically linked program */
// printf("Run statically linked program\n");
// printf("entry point: 0x%llx\n", prog_info.entry);
is_dyn_linked = false;
ipc_answer_0(rid, EOK);
return 0;
}
 
printf("Load dynamic linker '%s'\n", prog_info.interp);
rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
if (rc < 0) {
printf("failed to load dynamic linker\n");
rc = elf_load_file(prog_info.interp, 0, &interp_info);
if (rc != EE_OK) {
DPRINTF("Failed to load interpreter '%s.'\n",
prog_info.interp);
ipc_answer_0(rid, EINVAL);
return 1;
}
 
/*
* Provide dynamic linker with some useful data
*/
pcb.rtld_dynamic = interp_info.dynamic;
pcb.rtld_bias = RTLD_BIAS;
 
is_dyn_linked = true;
ipc_answer_0(rid, EOK);
 
return 0;
}
 
280,24 → 346,28
* @param request
* @return 0 on success, !0 on error.
*/
static void loader_run(ipc_callid_t rid, ipc_call_t *request)
static void ldr_run(ipc_callid_t rid, ipc_call_t *request)
{
const char *cp;
/* Set the task name. */
cp = str_rchr(pathname, '/');
cp = (cp == NULL) ? pathname : (cp + 1);
task_set_name(cp);
if (is_dyn_linked == true) {
/* Dynamically linked program */
printf("run dynamic linker\n");
printf("entry point: 0x%llx\n", interp_info.entry);
close_console();
 
DPRINTF("Run ELF interpreter.\n");
DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
ipc_answer_0(rid, EOK);
elf_run(&interp_info, &pcb);
 
} else {
/* Statically linked program */
close_console();
ipc_answer_0(rid, EOK);
elf_run(&prog_info, &pcb);
}
 
}
/* Not reached */
}
 
306,33 → 376,50
* Receive and carry out commands (of which the last one should be
* to execute the loaded program).
*/
static void loader_connection(ipc_callid_t iid, ipc_call_t *icall)
static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
int retval;
 
/* Already have a connection? */
if (connected) {
ipc_answer_0(iid, ELIMIT);
return;
}
connected = true;
/* Accept the connection */
ipc_answer_0(iid, EOK);
/* Ignore parameters, the connection is already open */
(void)iid; (void)icall;
 
(void) iid;
(void) icall;
while (1) {
callid = async_get_call(&call);
 
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
exit(0);
case LOADER_GET_TASKID:
loader_get_taskid(callid, &call);
ldr_get_taskid(callid, &call);
continue;
case LOADER_SET_PATHNAME:
loader_set_pathname(callid, &call);
ldr_set_pathname(callid, &call);
continue;
case LOADER_SET_ARGS:
loader_set_args(callid, &call);
ldr_set_args(callid, &call);
continue;
case LOADER_SET_FILES:
ldr_set_files(callid, &call);
continue;
case LOADER_LOAD:
loader_load(callid, &call);
ldr_load(callid, &call);
continue;
case LOADER_RUN:
loader_run(callid, &call);
ldr_run(callid, &call);
/* Not reached */
default:
retval = ENOENT;
340,7 → 427,7
}
if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
printf("responding EINVAL to method %d\n",
DPRINTF("Responding EINVAL to method %d.\n",
IPC_GET_METHOD(call));
ipc_answer_0(callid, EINVAL);
}
351,31 → 438,28
*/
int main(int argc, char *argv[])
{
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t phone_hash;
ipcarg_t phonead;
task_id_t id;
int rc;
 
/* The first call only communicates the incoming phone hash */
callid = ipc_wait_for_call(&call);
connected = false;
 
if (IPC_GET_METHOD(call) != LOADER_HELLO) {
if (IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP)
ipc_answer_0(callid, EINVAL);
return 1;
}
/* Introduce this task to the NS (give it our task ID). */
id = task_get_id();
rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
if (rc != EOK)
return -1;
 
ipc_answer_0(callid, EOK);
phone_hash = call.in_phone_hash;
/* Set a handler of incomming connections. */
async_set_client_connection(ldr_connection);
/* Register at naming service. */
if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
return -2;
 
/*
* Up until now async must not be used as it couldn't
* handle incoming requests. (Which means e.g. printf()
* cannot be used)
*/
async_new_connection(phone_hash, 0, NULL, loader_connection);
async_manager();
 
/* not reached */
/* Never reached */
return 0;
}
 
/branches/arm/uspace/srv/loader/elf_load.c
57,6 → 57,8
#include "elf_load.h"
#include "arch.h"
 
#define DPRINTF(...)
 
static char *error_codes[] = {
"no error",
"invalid image",
72,7 → 74,7
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
 
/** Read until the buffer is read in its entirety. */
static int my_read(int fd, char *buf, size_t len)
static int my_read(int fd, void *buf, size_t len)
{
int cnt = 0;
do {
106,11 → 108,9
int fd;
int rc;
 
// printf("open and read '%s'...\n", file_name);
 
fd = open(file_name, O_RDONLY);
if (fd < 0) {
printf("failed opening file\n");
DPRINTF("failed opening file\n");
return -1;
}
 
171,19 → 171,18
 
rc = my_read(elf->fd, header, sizeof(elf_header_t));
if (rc < 0) {
printf("read error\n");
DPRINTF("Read error.\n");
return EE_INVALID;
}
 
elf->header = header;
 
// printf("ELF-load:");
/* Identify ELF */
if (header->e_ident[EI_MAG0] != ELFMAG0 ||
header->e_ident[EI_MAG1] != ELFMAG1 ||
header->e_ident[EI_MAG2] != ELFMAG2 ||
header->e_ident[EI_MAG3] != ELFMAG3) {
printf("invalid header\n");
DPRINTF("Invalid header.\n");
return EE_INVALID;
}
193,18 → 192,18
header->e_ident[EI_VERSION] != EV_CURRENT ||
header->e_version != EV_CURRENT ||
header->e_ident[EI_CLASS] != ELF_CLASS) {
printf("incompatible data/version/class\n");
DPRINTF("Incompatible data/version/class.\n");
return EE_INCOMPATIBLE;
}
 
if (header->e_phentsize != sizeof(elf_segment_header_t)) {
printf("e_phentsize:%d != %d\n", header->e_phentsize,
DPRINTF("e_phentsize:%d != %d\n", header->e_phentsize,
sizeof(elf_segment_header_t));
return EE_INCOMPATIBLE;
}
 
if (header->e_shentsize != sizeof(elf_section_header_t)) {
printf("e_shentsize:%d != %d\n", header->e_shentsize,
DPRINTF("e_shentsize:%d != %d\n", header->e_shentsize,
sizeof(elf_section_header_t));
return EE_INCOMPATIBLE;
}
211,23 → 210,19
 
/* Check if the object type is supported. */
if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
printf("Object type %d is not supported\n", header->e_type);
DPRINTF("Object type %d is not supported\n", header->e_type);
return EE_UNSUPPORTED;
}
 
/* Shared objects can be loaded with a bias */
// printf("Object type: %d\n", header->e_type);
if (header->e_type == ET_DYN)
elf->bias = so_bias;
else
elf->bias = 0;
 
// printf("Bias set to 0x%x\n", elf->bias);
elf->info->interp = NULL;
elf->info->dynamic = NULL;
 
// printf("parse segments\n");
 
/* Walk through all segment headers and process them. */
for (i = 0; i < header->e_phnum; i++) {
elf_segment_header_t segment_hdr;
239,7 → 234,7
rc = my_read(elf->fd, &segment_hdr,
sizeof(elf_segment_header_t));
if (rc < 0) {
printf("read error\n");
DPRINTF("Read error.\n");
return EE_INVALID;
}
 
248,7 → 243,7
return rc;
}
 
// printf("parse sections\n");
DPRINTF("Parse sections.\n");
 
/* Inspect all section headers and proccess them. */
for (i = 0; i < header->e_shnum; i++) {
261,7 → 256,7
rc = my_read(elf->fd, &section_hdr,
sizeof(elf_section_header_t));
if (rc < 0) {
printf("read error\n");
DPRINTF("Read error.\n");
return EE_INVALID;
}
 
273,7 → 268,7
elf->info->entry =
(entry_point_t)((uint8_t *)header->e_entry + elf->bias);
 
// printf("done\n");
DPRINTF("Done.\n");
 
return EE_OK;
}
316,7 → 311,7
case PT_LOPROC:
case PT_HIPROC:
default:
printf("segment p_type %d unknown\n", entry->p_type);
DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
return EE_UNSUPPORTED;
break;
}
336,21 → 331,26
int flags = 0;
uintptr_t bias;
uintptr_t base;
void *seg_ptr;
uintptr_t seg_addr;
size_t mem_sz;
int rc;
 
// printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
// entry->p_memsz);
bias = elf->bias;
 
seg_addr = entry->p_vaddr + bias;
seg_ptr = (void *) seg_addr;
 
DPRINTF("Load segment at addr 0x%x, size 0x%x\n", seg_addr,
entry->p_memsz);
 
if (entry->p_align > 1) {
if ((entry->p_offset % entry->p_align) !=
(entry->p_vaddr % entry->p_align)) {
printf("align check 1 failed offset%%align=%d, "
(seg_addr % entry->p_align)) {
DPRINTF("Align check 1 failed offset%%align=%d, "
"vaddr%%align=%d\n",
entry->p_offset % entry->p_align,
entry->p_vaddr % entry->p_align
seg_addr % entry->p_align
);
return EE_INVALID;
}
369,8 → 369,8
base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
mem_sz = entry->p_memsz + (entry->p_vaddr - base);
 
// printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
// entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
DPRINTF("Map to seg_addr=0x%x-0x%x.\n", seg_addr,
entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
 
/*
* For the course of loading, the area needs to be readable
379,17 → 379,16
a = as_area_create((uint8_t *)base + bias, mem_sz,
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
if (a == (void *)(-1)) {
printf("memory mapping failed\n");
DPRINTF("Memory mapping failed.\n");
return EE_MEMORY;
}
 
// printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
// entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
DPRINTF("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
base + bias, mem_sz, flags, (uintptr_t)a);
 
/*
* Load segment data
*/
// printf("seek to %d\n", entry->p_offset);
rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
if (rc < 0) {
printf("seek error\n");
396,28 → 395,25
return EE_INVALID;
}
 
// printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
/* rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
 
/* Long reads are not possible yet. Load segment picewise */
/* Long reads are not possible yet. Load segment piecewise. */
 
unsigned left, now;
uint8_t *dp;
 
left = entry->p_filesz;
dp = (uint8_t *)(entry->p_vaddr + bias);
dp = seg_ptr;
 
while (left > 0) {
now = 16384;
if (now > left) now = left;
 
// printf("read %d...", now);
rc = my_read(elf->fd, dp, now);
// printf("->%d\n", rc);
 
if (rc < 0) {
printf("read error\n");
DPRINTF("Read error.\n");
return EE_INVALID;
}
 
425,16 → 421,15
dp += now;
}
 
// printf("set area flags to %d\n", flags);
rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
rc = as_area_change_flags(seg_ptr, flags);
if (rc != 0) {
printf("failed to set memory area flags\n");
DPRINTF("Failed to set memory area flags.\n");
return EE_MEMORY;
}
 
if (flags & AS_AREA_EXEC) {
/* Enforce SMC coherence for the segment */
if (smc_coherence(entry->p_vaddr + bias, entry->p_filesz))
if (smc_coherence(seg_ptr, entry->p_filesz))
return EE_MEMORY;
}
 
465,7 → 460,7
/* Record pointer to dynamic section into info structure */
elf->info->dynamic =
(void *)((uint8_t *)entry->sh_addr + elf->bias);
printf("dynamic section found at 0x%x\n",
DPRINTF("Dynamic section found at 0x%x.\n",
(uintptr_t)elf->info->dynamic);
break;
default:
/branches/arm/uspace/srv/loader/arch/ia32/ia32.s
46,4 → 46,4
# Save a tiny bit of stack space
pop %ebp
 
jmp %eax
jmp *%eax
/branches/arm/uspace/srv/loader/arch/ia32/_link.ld.in
1,8 → 1,8
/*
/*
* The difference from _link.ld.in for regular statically-linked apps
* is the base address and the special interp section.
*/
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
/branches/arm/uspace/srv/loader/arch/ia32/Makefile.inc
27,4 → 27,4
#
 
CFLAGS += -D__32_BITS__
ARCH_SOURCES := arch/$(ARCH)/ia32.s
ARCH_SOURCES := arch/$(UARCH)/ia32.s
/branches/arm/uspace/srv/loader/arch/sparc64/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
/branches/arm/uspace/srv/loader/arch/sparc64/Makefile.inc
27,4 → 27,4
#
 
CFLAGS += -D__64_BITS__
ARCH_SOURCES := arch/$(ARCH)/sparc64.s
ARCH_SOURCES := arch/$(UARCH)/sparc64.s
/branches/arm/uspace/srv/loader/arch/ia64/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
12,15 → 12,10
*(.interp);
} :interp
 
. = 0x00084000 + SIZEOF_HEADERS;
/* On Itanium code sections must be aligned to 16 bytes. */
. = ALIGN(0x800000000 + SIZEOF_HEADERS, 16);
 
.init : {
LONG(0);
LONG(0);
LONG(0);
LONG(0);
LONG(0);
LONG(0);
*(.init);
} : text
.text : {
/branches/arm/uspace/srv/loader/arch/ia64/Makefile.inc
27,5 → 27,5
#
 
CFLAGS += -D__64_BITS__
ARCH_SOURCES := arch/$(ARCH)/ia64.s
ARCH_SOURCES := arch/$(UARCH)/ia64.s
AFLAGS += -xexplicit
/branches/arm/uspace/srv/loader/arch/arm32/_link.ld.in
1,8 → 1,8
/*
/*
* The only difference from _link.ld.in for regular statically-linked apps
* is the base address.
*/
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
/branches/arm/uspace/srv/loader/arch/arm32/Makefile.inc
27,4 → 27,4
#
 
CFLAGS += -D__32_BITS__
ARCH_SOURCES := arch/$(ARCH)/arm32.s
ARCH_SOURCES := arch/$(UARCH)/arm32.s
/branches/arm/uspace/srv/loader/arch/ppc32/_link.ld.in
1,8 → 1,8
/*
/*
* The only difference from _link.ld.in for regular statically-linked apps
* is the base address.
*/
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
/branches/arm/uspace/srv/loader/arch/ppc32/Makefile.inc
27,4 → 27,4
#
 
CFLAGS += -D__32_BITS__
ARCH_SOURCES := arch/$(ARCH)/ppc32.s
ARCH_SOURCES := arch/$(UARCH)/ppc32.s
/branches/arm/uspace/srv/loader/arch/ppc32/ppc32.s
36,5 → 36,5
# Jump to a program entry point
program_run:
mtctr %r3
mr %r3, %r4 # Pass pcb to the entry point in %r3
mr %r6, %r4 # Pass pcb to the entry point in %r6
bctr
/branches/arm/uspace/srv/loader/arch/amd64/_link.ld.in
1,4 → 1,4
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
/branches/arm/uspace/srv/loader/arch/amd64/Makefile.inc
27,4 → 27,4
#
 
CFLAGS += -D__64_BITS__
ARCH_SOURCES := arch/$(ARCH)/amd64.s
ARCH_SOURCES := arch/$(UARCH)/amd64.s
/branches/arm/uspace/srv/loader/arch/mips32/_link.ld.in
1,8 → 1,8
/*
/*
* The only difference from _link.ld.in for regular statically-linked apps
* is the base address.
*/
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
/branches/arm/uspace/srv/loader/arch/mips32/Makefile.inc
27,4 → 27,4
#
 
CFLAGS += -D__32_BITS__
ARCH_SOURCES := arch/$(ARCH)/mips32.s
ARCH_SOURCES := arch/$(UARCH)/mips32.s
/branches/arm/uspace/srv/loader/arch/mips32eb
0,0 → 1,0
link mips32
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/uspace/srv/loader/Makefile
27,30 → 27,19
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
include ../../../version
include ../../Makefile.config
 
## Setup toolchain
#
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
include arch/$(ARCH)/Makefile.inc
include arch/$(UARCH)/Makefile.inc
 
CFLAGS += -Iinclude
 
LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
DEFS += -DRELEASE=\"$(RELEASE)\"
 
ifdef REVISION
DEFS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
## Sources
#
 
70,18 → 59,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm arch/$(ARCH)/_link.ld Makefile.depend
-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm arch/$(UARCH)/_link.ld Makefile.depend
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS) arch/$(ARCH)/_link.ld
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map
$(OUTPUT): $(OBJECTS) $(LIBS) arch/$(UARCH)/_link.ld
$(LD) -T arch/$(UARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in
$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
 
%.o: %.S
/branches/arm/uspace/srv/fs/devfs/devfs_ops.c
0,0 → 1,531
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
/**
* @file devfs_ops.c
* @brief Implementation of VFS operations for the devfs file system server.
*/
 
#include <ipc/ipc.h>
#include <bool.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <libfs.h>
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <sys/stat.h>
#include "devfs.h"
#include "devfs_ops.h"
 
#define PLB_GET_CHAR(pos) (devfs_reg.plb_ro[pos % PLB_SIZE])
 
/** Opened devices structure */
typedef struct {
dev_handle_t handle;
int phone;
size_t refcount;
link_t link;
} device_t;
 
/** Hash table of opened devices */
static hash_table_t devices;
 
/** Hash table mutex */
static FIBRIL_MUTEX_INITIALIZE(devices_mutex);
 
#define DEVICES_KEYS 1
#define DEVICES_KEY_HANDLE 0
#define DEVICES_BUCKETS 256
 
/* Implementation of hash table interface for the nodes hash table. */
static hash_index_t devices_hash(unsigned long key[])
{
return key[DEVICES_KEY_HANDLE] % DEVICES_BUCKETS;
}
 
static int devices_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
device_t *dev = hash_table_get_instance(item, device_t, link);
return (dev->handle == (dev_handle_t) key[DEVICES_KEY_HANDLE]);
}
 
static void devices_remove_callback(link_t *item)
{
free(hash_table_get_instance(item, device_t, link));
}
 
static hash_table_operations_t devices_ops = {
.hash = devices_hash,
.compare = devices_compare,
.remove_callback = devices_remove_callback
};
 
bool devfs_init(void)
{
if (!hash_table_create(&devices, DEVICES_BUCKETS,
DEVICES_KEYS, &devices_ops))
return false;
if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)
return false;
return true;
}
 
void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
{
/* Accept the mount options */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *opts = malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(opts);
return;
}
free(opts);
ipc_answer_3(rid, EOK, 0, 0, 0);
}
 
void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
}
 
void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
{
ipcarg_t first = IPC_GET_ARG1(*request);
ipcarg_t last = IPC_GET_ARG2(*request);
dev_handle_t dev_handle = IPC_GET_ARG3(*request);
ipcarg_t lflag = IPC_GET_ARG4(*request);
fs_index_t index = IPC_GET_ARG5(*request);
/* Hierarchy is flat, no altroot is supported */
if (index != 0) {
ipc_answer_0(rid, ENOENT);
return;
}
if ((lflag & L_LINK) || (lflag & L_UNLINK)) {
ipc_answer_0(rid, ENOTSUP);
return;
}
/* Eat slash */
if (PLB_GET_CHAR(first) == '/') {
first++;
first %= PLB_SIZE;
}
if (first >= last) {
/* Root entry */
if (!(lflag & L_FILE))
ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, 0, 0, 0);
else
ipc_answer_0(rid, ENOENT);
} else {
if (!(lflag & L_DIRECTORY)) {
size_t len;
if (last >= first)
len = last - first + 1;
else
len = first + PLB_SIZE - last + 1;
char *name = (char *) malloc(len + 1);
if (name == NULL) {
ipc_answer_0(rid, ENOMEM);
return;
}
size_t i;
for (i = 0; i < len; i++)
name[i] = PLB_GET_CHAR(first + i);
name[len] = 0;
dev_handle_t handle;
if (devmap_device_get_handle(name, &handle, 0) != EOK) {
free(name);
ipc_answer_0(rid, ENOENT);
return;
}
if (lflag & L_OPEN) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) handle
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
int phone = devmap_device_connect(handle, 0);
if (phone < 0) {
fibril_mutex_unlock(&devices_mutex);
free(name);
ipc_answer_0(rid, ENOENT);
return;
}
device_t *dev = (device_t *) malloc(sizeof(device_t));
if (dev == NULL) {
fibril_mutex_unlock(&devices_mutex);
free(name);
ipc_answer_0(rid, ENOMEM);
return;
}
dev->handle = handle;
dev->phone = phone;
dev->refcount = 1;
hash_table_insert(&devices, key, &dev->link);
} else {
device_t *dev = hash_table_get_instance(lnk, device_t, link);
dev->refcount++;
}
fibril_mutex_unlock(&devices_mutex);
}
free(name);
ipc_answer_5(rid, EOK, devfs_reg.fs_handle, dev_handle, handle, 0, 1);
} else
ipc_answer_0(rid, ENOENT);
}
}
 
void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t handle = IPC_GET_ARG2(*request);
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) handle
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
int phone = devmap_device_connect(handle, 0);
if (phone < 0) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
device_t *dev = (device_t *) malloc(sizeof(device_t));
if (dev == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOMEM);
return;
}
dev->handle = handle;
dev->phone = phone;
dev->refcount = 1;
hash_table_insert(&devices, key, &dev->link);
} else {
device_t *dev = hash_table_get_instance(lnk, device_t, link);
dev->refcount++;
}
fibril_mutex_unlock(&devices_mutex);
ipc_answer_3(rid, EOK, 0, 1, L_FILE);
}
 
void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size) ||
size != sizeof(struct stat)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
struct stat stat;
memset(&stat, 0, sizeof(struct stat));
 
stat.fs_handle = devfs_reg.fs_handle;
stat.dev_handle = dev_handle;
stat.index = index;
stat.lnkcnt = 1;
stat.is_file = (index != 0);
stat.size = 0;
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk != NULL)
stat.devfs_stat.device = (dev_handle_t)index;
fibril_mutex_unlock(&devices_mutex);
}
 
ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
ipc_answer_0(rid, EOK);
}
 
void devfs_read(ipc_callid_t rid, ipc_call_t *request)
{
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
off_t pos = (off_t) IPC_GET_ARG3(*request);
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
device_t *dev = hash_table_get_instance(lnk, device_t, link);
ipc_callid_t callid;
if (!ipc_data_read_receive(&callid, NULL)) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
/* Make a request at the driver */
ipc_call_t answer;
aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request),
IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
IPC_GET_ARG3(*request), &answer);
/* Forward the IPC_M_DATA_READ request to the driver */
ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
fibril_mutex_unlock(&devices_mutex);
/* Wait for reply from the driver. */
ipcarg_t rc;
async_wait_for(msg, &rc);
size_t bytes = IPC_GET_ARG1(answer);
/* Driver reply is the final result of the whole operation */
ipc_answer_1(rid, rc, bytes);
} else {
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
size_t count = devmap_device_get_count();
dev_desc_t *desc = malloc(count * sizeof(dev_desc_t));
if (desc == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_1(rid, ENOMEM, 0);
return;
}
size_t max = devmap_device_get_devices(count, desc);
if (pos < max) {
ipc_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
} else {
ipc_answer_0(callid, ENOENT);
ipc_answer_1(rid, ENOENT, 0);
return;
}
free(desc);
ipc_answer_1(rid, EOK, 1);
}
}
 
void devfs_write(ipc_callid_t rid, ipc_call_t *request)
{
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
off_t pos = (off_t) IPC_GET_ARG3(*request);
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
device_t *dev = hash_table_get_instance(lnk, device_t, link);
ipc_callid_t callid;
if (!ipc_data_write_receive(&callid, NULL)) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
/* Make a request at the driver */
ipc_call_t answer;
aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request),
IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
IPC_GET_ARG3(*request), &answer);
/* Forward the IPC_M_DATA_WRITE request to the driver */
ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
fibril_mutex_unlock(&devices_mutex);
/* Wait for reply from the driver. */
ipcarg_t rc;
async_wait_for(msg, &rc);
size_t bytes = IPC_GET_ARG1(answer);
/* Driver reply is the final result of the whole operation */
ipc_answer_1(rid, rc, bytes);
} else {
/* Read-only filesystem */
ipc_answer_0(rid, ENOTSUP);
}
}
 
void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
}
 
void devfs_close(ipc_callid_t rid, ipc_call_t *request)
{
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
device_t *dev = hash_table_get_instance(lnk, device_t, link);
dev->refcount--;
if (dev->refcount == 0) {
ipc_hangup(dev->phone);
hash_table_remove(&devices, key, DEVICES_KEYS);
}
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, EOK);
} else
ipc_answer_0(rid, ENOTSUP);
}
 
void devfs_sync(ipc_callid_t rid, ipc_call_t *request)
{
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
};
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
device_t *dev = hash_table_get_instance(lnk, device_t, link);
/* Make a request at the driver */
ipc_call_t answer;
aid_t msg = async_send_2(dev->phone, IPC_GET_METHOD(*request),
IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
fibril_mutex_unlock(&devices_mutex);
/* Wait for reply from the driver */
ipcarg_t rc;
async_wait_for(msg, &rc);
/* Driver reply is the final result of the whole operation */
ipc_answer_0(rid, rc);
} else
ipc_answer_0(rid, ENOTSUP);
}
 
void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/devfs/devfs.c
0,0 → 1,141
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
/**
* @file devfs.c
* @brief Devices file system.
*
* Every device registered to device mapper is represented as a file in this
* file system.
*/
 
#include <stdio.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <async.h>
#include <errno.h>
#include <libfs.h>
#include "devfs.h"
#include "devfs_ops.h"
 
#define NAME "devfs"
 
static vfs_info_t devfs_vfs_info = {
.name = "devfs",
};
 
fs_reg_t devfs_reg;
 
static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall)
{
if (iid)
ipc_answer_0(iid, EOK);
while (true) {
ipc_call_t call;
ipc_callid_t callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
return;
case VFS_OUT_MOUNTED:
devfs_mounted(callid, &call);
break;
case VFS_OUT_MOUNT:
devfs_mount(callid, &call);
break;
case VFS_OUT_LOOKUP:
devfs_lookup(callid, &call);
break;
case VFS_OUT_OPEN_NODE:
devfs_open_node(callid, &call);
break;
case VFS_OUT_STAT:
devfs_stat(callid, &call);
break;
case VFS_OUT_READ:
devfs_read(callid, &call);
break;
case VFS_OUT_WRITE:
devfs_write(callid, &call);
break;
case VFS_OUT_TRUNCATE:
devfs_truncate(callid, &call);
break;
case VFS_OUT_CLOSE:
devfs_close(callid, &call);
break;
case VFS_OUT_SYNC:
devfs_sync(callid, &call);
break;
case VFS_OUT_DESTROY:
devfs_destroy(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
}
}
}
 
int main(int argc, char *argv[])
{
printf(NAME ": HelenOS Device Filesystem\n");
if (!devfs_init()) {
printf(NAME ": failed to initialize devfs\n");
return -1;
}
int vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
if (vfs_phone < EOK) {
printf(NAME ": Unable to connect to VFS\n");
return -1;
}
int rc = fs_register(vfs_phone, &devfs_reg, &devfs_vfs_info,
devfs_connection);
if (rc != EOK) {
printf(NAME ": Failed to register file system (%d)\n", rc);
return rc;
}
printf(NAME ": Accepting connections\n");
async_manager();
/* Not reached */
return 0;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/devfs/devfs_ops.h
0,0 → 1,57
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
#ifndef DEVFS_DEVFS_OPS_H_
#define DEVFS_DEVFS_OPS_H_
 
#include <ipc/ipc.h>
#include <bool.h>
 
extern bool devfs_init(void);
 
extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
extern void devfs_mount(ipc_callid_t, ipc_call_t *);
extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
extern void devfs_stat(ipc_callid_t, ipc_call_t *);
extern void devfs_sync(ipc_callid_t, ipc_call_t *);
extern void devfs_read(ipc_callid_t, ipc_call_t *);
extern void devfs_write(ipc_callid_t, ipc_call_t *);
extern void devfs_truncate(ipc_callid_t, ipc_call_t *);
extern void devfs_close(ipc_callid_t, ipc_call_t *);
extern void devfs_destroy(ipc_callid_t, ipc_call_t *);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/devfs/Makefile
0,0 → 1,82
#
# Copyright (c) 2005 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
LIBC_PREFIX = ../../../lib/libc
LIBFS_PREFIX = ../../../lib/libfs
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I $(LIBFS_PREFIX)
 
LIBS = \
$(LIBFS_PREFIX)/libfs.a \
$(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = devfs
SOURCES = \
devfs.c \
devfs_ops.c
 
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/fs/devfs/devfs.h
0,0 → 1,44
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
#ifndef DEVFS_DEVFS_H_
#define DEVFS_DEVFS_H_
 
#include <libfs.h>
 
extern fs_reg_t devfs_reg;
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/tmpfs/tmpfs_ops.c
47,7 → 47,7
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include <libadt/hash_table.h>
#include <adt/hash_table.h>
#include <as.h>
#include <libfs.h>
 
54,53 → 54,50
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
#define DENTRIES_BUCKETS 256
#define NODES_BUCKETS 256
 
#define NAMES_BUCKETS 4
/** All root nodes have index 0. */
#define TMPFS_SOME_ROOT 0
/** Global counter for assigning node indices. Shared by all instances. */
fs_index_t tmpfs_next_index = 1;
 
/*
* For now, we don't distinguish between different dev_handles/instances. All
* requests resolve to the only instance, rooted in the following variable.
*/
static tmpfs_dentry_t *root;
 
/*
* Implementation of the libfs interface.
*/
 
/* Forward declarations of static functions. */
static void *tmpfs_match(void *, const char *);
static void *tmpfs_node_get(dev_handle_t, fs_index_t);
static void tmpfs_node_put(void *);
static void *tmpfs_create_node(int);
static bool tmpfs_link_node(void *, void *, const char *);
static int tmpfs_unlink_node(void *, void *);
static int tmpfs_destroy_node(void *);
static fs_node_t *tmpfs_match(fs_node_t *, const char *);
static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t);
static void tmpfs_node_put(fs_node_t *);
static fs_node_t *tmpfs_create_node(dev_handle_t, int);
static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *);
static int tmpfs_unlink_node(fs_node_t *, fs_node_t *, const char *);
static int tmpfs_destroy_node(fs_node_t *);
 
/* Implementation of helper functions. */
static fs_index_t tmpfs_index_get(void *nodep)
static fs_index_t tmpfs_index_get(fs_node_t *fn)
{
return ((tmpfs_dentry_t *) nodep)->index;
return TMPFS_NODE(fn)->index;
}
 
static size_t tmpfs_size_get(void *nodep)
static size_t tmpfs_size_get(fs_node_t *fn)
{
return ((tmpfs_dentry_t *) nodep)->size;
return TMPFS_NODE(fn)->size;
}
 
static unsigned tmpfs_lnkcnt_get(void *nodep)
static unsigned tmpfs_lnkcnt_get(fs_node_t *fn)
{
return ((tmpfs_dentry_t *) nodep)->lnkcnt;
return TMPFS_NODE(fn)->lnkcnt;
}
 
static bool tmpfs_has_children(void *nodep)
static bool tmpfs_has_children(fs_node_t *fn)
{
return ((tmpfs_dentry_t *) nodep)->child != NULL;
return !list_empty(&TMPFS_NODE(fn)->cs_head);
}
 
static void *tmpfs_root_get(dev_handle_t dev_handle)
static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle)
{
return root;
return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);
}
 
static char tmpfs_plb_get_char(unsigned pos)
108,14 → 105,14
return tmpfs_reg.plb_ro[pos % PLB_SIZE];
}
 
static bool tmpfs_is_directory(void *nodep)
static bool tmpfs_is_directory(fs_node_t *fn)
{
return ((tmpfs_dentry_t *) nodep)->type == TMPFS_DIRECTORY;
return TMPFS_NODE(fn)->type == TMPFS_DIRECTORY;
}
 
static bool tmpfs_is_file(void *nodep)
static bool tmpfs_is_file(fs_node_t *fn)
{
return ((tmpfs_dentry_t *) nodep)->type == TMPFS_FILE;
return TMPFS_NODE(fn)->type == TMPFS_FILE;
}
 
/** libfs operations */
137,259 → 134,231
.is_file = tmpfs_is_file
};
 
/** Hash table of all directory entries. */
hash_table_t dentries;
/** Hash table of all TMPFS nodes. */
hash_table_t nodes;
 
/* Implementation of hash table interface for the dentries hash table. */
static hash_index_t dentries_hash(unsigned long *key)
{
return *key % DENTRIES_BUCKETS;
}
#define NODES_KEY_INDEX 0
#define NODES_KEY_DEV 1
 
static int dentries_compare(unsigned long *key, hash_count_t keys,
link_t *item)
/* Implementation of hash table interface for the nodes hash table. */
static hash_index_t nodes_hash(unsigned long key[])
{
tmpfs_dentry_t *dentry = hash_table_get_instance(item, tmpfs_dentry_t,
dh_link);
return dentry->index == *key;
return key[NODES_KEY_INDEX] % NODES_BUCKETS;
}
 
static void dentries_remove_callback(link_t *item)
static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
nh_link);
return (nodep->index == key[NODES_KEY_INDEX] &&
nodep->dev_handle == key[NODES_KEY_DEV]);
}
 
/** TMPFS dentries hash table operations. */
hash_table_operations_t dentries_ops = {
.hash = dentries_hash,
.compare = dentries_compare,
.remove_callback = dentries_remove_callback
};
 
fs_index_t tmpfs_next_index = 1;
 
typedef struct {
char *name;
tmpfs_dentry_t *parent;
link_t link;
} tmpfs_name_t;
 
/* Implementation of hash table interface for the names hash table. */
static hash_index_t names_hash(unsigned long *key)
static void nodes_remove_callback(link_t *item)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) *key;
return dentry->index % NAMES_BUCKETS;
}
 
static int names_compare(unsigned long *key, hash_count_t keys, link_t *item)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) *key;
tmpfs_name_t *namep = hash_table_get_instance(item, tmpfs_name_t,
link);
return dentry == namep->parent;
}
 
static void names_remove_callback(link_t *item)
{
tmpfs_name_t *namep = hash_table_get_instance(item, tmpfs_name_t,
link);
free(namep->name);
free(namep);
}
 
/** TMPFS node names hash table operations. */
static hash_table_operations_t names_ops = {
.hash = names_hash,
.compare = names_compare,
.remove_callback = names_remove_callback
/** TMPFS nodes hash table operations. */
hash_table_operations_t nodes_ops = {
.hash = nodes_hash,
.compare = nodes_compare,
.remove_callback = nodes_remove_callback
};
 
static void tmpfs_name_initialize(tmpfs_name_t *namep)
static void tmpfs_node_initialize(tmpfs_node_t *nodep)
{
namep->name = NULL;
namep->parent = NULL;
link_initialize(&namep->link);
nodep->bp = NULL;
nodep->index = 0;
nodep->dev_handle = 0;
nodep->type = TMPFS_NONE;
nodep->lnkcnt = 0;
nodep->size = 0;
nodep->data = NULL;
link_initialize(&nodep->nh_link);
list_initialize(&nodep->cs_head);
}
 
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
static void tmpfs_dentry_initialize(tmpfs_dentry_t *dentryp)
{
dentry->index = 0;
dentry->sibling = NULL;
dentry->child = NULL;
dentry->type = TMPFS_NONE;
dentry->lnkcnt = 0;
dentry->size = 0;
dentry->data = NULL;
link_initialize(&dentry->dh_link);
return (bool)hash_table_create(&dentry->names, NAMES_BUCKETS, 1,
&names_ops);
link_initialize(&dentryp->link);
dentryp->name = NULL;
dentryp->node = NULL;
}
 
static bool tmpfs_init(void)
bool tmpfs_init(void)
{
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))
return false;
root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
if (!root) {
hash_table_destroy(&dentries);
return false;
}
root->lnkcnt = 0; /* FS root is not linked */
return true;
}
 
/** Compare one component of path to a directory entry.
*
* @param parentp Pointer to node from which we descended.
* @param childp Pointer to node to compare the path component with.
* @param component Array of characters holding component name.
*
* @return True on match, false otherwise.
*/
static bool
tmpfs_match_one(tmpfs_dentry_t *parentp, tmpfs_dentry_t *childp,
const char *component)
static bool tmpfs_instance_init(dev_handle_t dev_handle)
{
unsigned long key = (unsigned long) parentp;
link_t *hlp = hash_table_find(&childp->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
return !strcmp(namep->name, component);
fs_node_t *rfn;
rfn = tmpfs_create_node(dev_handle, L_DIRECTORY);
if (!rfn)
return false;
TMPFS_NODE(rfn)->lnkcnt = 0; /* FS root is not linked */
return true;
}
 
void *tmpfs_match(void *prnt, const char *component)
fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component)
{
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
tmpfs_dentry_t *childp = parentp->child;
tmpfs_node_t *parentp = TMPFS_NODE(pfn);
link_t *lnk;
 
while (childp && !tmpfs_match_one(parentp, childp, component))
childp = childp->sibling;
for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
lnk = lnk->next) {
tmpfs_dentry_t *dentryp = list_get_instance(lnk, tmpfs_dentry_t,
link);
if (!str_cmp(dentryp->name, component))
return FS_NODE(dentryp->node);
}
 
return (void *) childp;
return NULL;
}
 
void *
tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
{
unsigned long key = index;
link_t *lnk = hash_table_find(&dentries, &key);
unsigned long key[] = {
[NODES_KEY_INDEX] = index,
[NODES_KEY_DEV] = dev_handle
};
link_t *lnk = hash_table_find(&nodes, key);
if (!lnk)
return NULL;
return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link);
return FS_NODE(hash_table_get_instance(lnk, tmpfs_node_t, nh_link));
}
 
void tmpfs_node_put(void *node)
void tmpfs_node_put(fs_node_t *fn)
{
/* nothing to do */
}
 
void *tmpfs_create_node(int lflag)
fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
{
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
 
tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
if (!node)
tmpfs_node_t *nodep = malloc(sizeof(tmpfs_node_t));
if (!nodep)
return NULL;
 
if (!tmpfs_dentry_initialize(node)) {
free(node);
tmpfs_node_initialize(nodep);
nodep->bp = malloc(sizeof(fs_node_t));
if (!nodep->bp) {
free(nodep);
return NULL;
}
node->index = tmpfs_next_index++;
fs_node_initialize(nodep->bp);
nodep->bp->data = nodep; /* link the FS and TMPFS nodes */
if (!tmpfs_root_get(dev_handle))
nodep->index = TMPFS_SOME_ROOT;
else
nodep->index = tmpfs_next_index++;
nodep->dev_handle = dev_handle;
if (lflag & L_DIRECTORY)
node->type = TMPFS_DIRECTORY;
nodep->type = TMPFS_DIRECTORY;
else
node->type = TMPFS_FILE;
nodep->type = TMPFS_FILE;
 
/* Insert the new node into the dentry hash table. */
unsigned long key = node->index;
hash_table_insert(&dentries, &key, &node->dh_link);
return (void *) node;
/* Insert the new node into the nodes hash table. */
unsigned long key[] = {
[NODES_KEY_INDEX] = nodep->index,
[NODES_KEY_DEV] = nodep->dev_handle
};
hash_table_insert(&nodes, key, &nodep->nh_link);
return FS_NODE(nodep);
}
 
bool tmpfs_link_node(void *prnt, void *chld, const char *nm)
int tmpfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
{
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
tmpfs_node_t *parentp = TMPFS_NODE(pfn);
tmpfs_node_t *childp = TMPFS_NODE(cfn);
tmpfs_dentry_t *dentryp;
link_t *lnk;
 
assert(parentp->type == TMPFS_DIRECTORY);
 
tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t));
if (!namep)
return false;
tmpfs_name_initialize(namep);
size_t len = strlen(nm);
namep->name = malloc(len + 1);
if (!namep->name) {
free(namep);
return false;
/* Check for duplicit entries. */
for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
lnk = lnk->next) {
dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
if (!str_cmp(dentryp->name, nm))
return EEXIST;
}
strcpy(namep->name, nm);
namep->parent = parentp;
childp->lnkcnt++;
 
unsigned long key = (unsigned long) parentp;
hash_table_insert(&childp->names, &key, &namep->link);
/* Allocate and initialize the dentry. */
dentryp = malloc(sizeof(tmpfs_dentry_t));
if (!dentryp)
return ENOMEM;
tmpfs_dentry_initialize(dentryp);
 
/* Insert the new node into the namespace. */
if (parentp->child) {
tmpfs_dentry_t *tmp = parentp->child;
while (tmp->sibling)
tmp = tmp->sibling;
tmp->sibling = childp;
} else {
parentp->child = childp;
/* Populate and link the new dentry. */
size_t size = str_size(nm);
dentryp->name = malloc(size + 1);
if (!dentryp->name) {
free(dentryp);
return ENOMEM;
}
str_cpy(dentryp->name, size + 1, nm);
dentryp->node = childp;
childp->lnkcnt++;
list_append(&dentryp->link, &parentp->cs_head);
 
return true;
return EOK;
}
 
int tmpfs_unlink_node(void *prnt, void *chld)
int tmpfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
{
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *)prnt;
tmpfs_dentry_t *childp = (tmpfs_dentry_t *)chld;
tmpfs_node_t *parentp = TMPFS_NODE(pfn);
tmpfs_node_t *childp = NULL;
tmpfs_dentry_t *dentryp;
link_t *lnk;
 
if (!parentp)
return EBUSY;
for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head;
lnk = lnk->next) {
dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
if (!str_cmp(dentryp->name, nm)) {
childp = dentryp->node;
assert(FS_NODE(childp) == cfn);
break;
}
}
 
if (childp->child)
if (!childp)
return ENOENT;
if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_head))
return ENOTEMPTY;
 
if (parentp->child == childp) {
parentp->child = childp->sibling;
} else {
/* TODO: consider doubly linked list for organizing siblings. */
tmpfs_dentry_t *tmp = parentp->child;
while (tmp->sibling != childp)
tmp = tmp->sibling;
tmp->sibling = childp->sibling;
}
childp->sibling = NULL;
 
unsigned long key = (unsigned long) parentp;
hash_table_remove(&childp->names, &key, 1);
 
list_remove(&dentryp->link);
free(dentryp);
childp->lnkcnt--;
 
return EOK;
}
 
int tmpfs_destroy_node(void *nodep)
int tmpfs_destroy_node(fs_node_t *fn)
{
tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
tmpfs_node_t *nodep = TMPFS_NODE(fn);
assert(!dentry->lnkcnt);
assert(!dentry->child);
assert(!dentry->sibling);
assert(!nodep->lnkcnt);
assert(list_empty(&nodep->cs_head));
 
unsigned long key = dentry->index;
hash_table_remove(&dentries, &key, 1);
unsigned long key[] = {
[NODES_KEY_INDEX] = nodep->index,
[NODES_KEY_DEV] = nodep->dev_handle
};
hash_table_remove(&nodes, key, 2);
 
hash_table_destroy(&dentry->names);
 
if (dentry->type == TMPFS_FILE)
free(dentry->data);
free(dentry);
if (nodep->type == TMPFS_FILE)
free(nodep->data);
free(nodep->bp);
free(nodep);
return EOK;
}
 
397,31 → 366,50
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 
/* Initialize TMPFS. */
if (!root && !tmpfs_init()) {
/* accept the mount options */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *opts = malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(opts);
return;
}
opts[size] = '\0';
 
if (dev_handle >= 0) {
/* Initialize TMPFS instance. */
if (!tmpfs_instance_init(dev_handle)) {
ipc_answer_0(rid, ENOMEM);
return;
}
 
tmpfs_node_t *rootp = TMPFS_NODE(tmpfs_root_get(dev_handle));
if (str_cmp(opts, "restore") == 0) {
if (tmpfs_restore(dev_handle))
ipc_answer_3(rid, EOK, root->index, root->size,
root->lnkcnt);
ipc_answer_3(rid, EOK, rootp->index, rootp->size,
rootp->lnkcnt);
else
ipc_answer_0(rid, ELIMIT);
} else {
ipc_answer_3(rid, EOK, root->index, root->size, root->lnkcnt);
ipc_answer_3(rid, EOK, rootp->index, rootp->size,
rootp->lnkcnt);
}
}
 
void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t mp_index = (fs_index_t) IPC_GET_ARG2(*request);
fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request);
ipc_answer_0(rid, ENOTSUP);
libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
436,24 → 424,27
off_t pos = (off_t)IPC_GET_ARG3(*request);
 
/*
* Lookup the respective dentry.
* Lookup the respective TMPFS node.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[NODES_KEY_INDEX] = index,
[NODES_KEY_DEV] = dev_handle,
};
hlp = hash_table_find(&nodes, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
}
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
dh_link);
tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
nh_link);
 
/*
* Receive the read request.
*/
ipc_callid_t callid;
size_t len;
if (!ipc_data_read_receive(&callid, &len)) {
size_t size;
if (!ipc_data_read_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
460,15 → 451,16
}
 
size_t bytes;
if (dentry->type == TMPFS_FILE) {
bytes = max(0, min(dentry->size - pos, len));
(void) ipc_data_read_finalize(callid, dentry->data + pos,
if (nodep->type == TMPFS_FILE) {
bytes = max(0, min(nodep->size - pos, size));
(void) ipc_data_read_finalize(callid, nodep->data + pos,
bytes);
} else {
tmpfs_dentry_t *dentryp;
link_t *lnk;
int i;
tmpfs_dentry_t *cur;
assert(dentry->type == TMPFS_DIRECTORY);
assert(nodep->type == TMPFS_DIRECTORY);
/*
* Yes, we really use O(n) algorithm here.
475,24 → 467,21
* If it bothers someone, it could be fixed by introducing a
* hash table.
*/
for (i = 0, cur = dentry->child; i < pos && cur; i++,
cur = cur->sibling)
for (i = 0, lnk = nodep->cs_head.next;
i < pos && lnk != &nodep->cs_head;
i++, lnk = lnk->next)
;
 
if (!cur) {
if (lnk == &nodep->cs_head) {
ipc_answer_0(callid, ENOENT);
ipc_answer_1(rid, ENOENT, 0);
return;
}
 
unsigned long key = (unsigned long) dentry;
link_t *hlp = hash_table_find(&cur->names, &key);
assert(hlp);
tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t,
link);
dentryp = list_get_instance(lnk, tmpfs_dentry_t, link);
 
(void) ipc_data_read_finalize(callid, namep->name,
strlen(namep->name) + 1);
(void) ipc_data_read_finalize(callid, dentryp->name,
str_size(dentryp->name) + 1);
bytes = 1;
}
 
509,24 → 498,27
off_t pos = (off_t)IPC_GET_ARG3(*request);
 
/*
* Lookup the respective dentry.
* Lookup the respective TMPFS node.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[NODES_KEY_INDEX] = index,
[NODES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&nodes, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
}
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
dh_link);
tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
nh_link);
 
/*
* Receive the write request.
*/
ipc_callid_t callid;
size_t len;
if (!ipc_data_write_receive(&callid, &len)) {
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
535,13 → 527,13
/*
* Check whether the file needs to grow.
*/
if (pos + len <= dentry->size) {
if (pos + size <= nodep->size) {
/* The file size is not changing. */
(void) ipc_data_write_finalize(callid, dentry->data + pos, len);
ipc_answer_2(rid, EOK, len, dentry->size);
(void) ipc_data_write_finalize(callid, nodep->data + pos, size);
ipc_answer_2(rid, EOK, size, nodep->size);
return;
}
size_t delta = (pos + len) - dentry->size;
size_t delta = (pos + size) - nodep->size;
/*
* At this point, we are deliberately extremely straightforward and
* simply realloc the contents of the file on every write that grows the
549,18 → 541,18
* our heap allocator can save us and just grow the block whenever
* possible.
*/
void *newdata = realloc(dentry->data, dentry->size + delta);
void *newdata = realloc(nodep->data, nodep->size + delta);
if (!newdata) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_2(rid, EOK, 0, dentry->size);
ipc_answer_2(rid, EOK, 0, nodep->size);
return;
}
/* Clear any newly allocated memory in order to emulate gaps. */
memset(newdata + dentry->size, 0, delta);
dentry->size += delta;
dentry->data = newdata;
(void) ipc_data_write_finalize(callid, dentry->data + pos, len);
ipc_answer_2(rid, EOK, len, dentry->size);
memset(newdata + nodep->size, 0, delta);
nodep->size += delta;
nodep->data = newdata;
(void) ipc_data_write_finalize(callid, nodep->data + pos, size);
ipc_answer_2(rid, EOK, size, nodep->size);
}
 
void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
570,37 → 562,45
size_t size = (off_t)IPC_GET_ARG3(*request);
 
/*
* Lookup the respective dentry.
* Lookup the respective TMPFS node.
*/
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[NODES_KEY_INDEX] = index,
[NODES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&nodes, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
}
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
dh_link);
tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
nh_link);
 
if (size == dentry->size) {
if (size == nodep->size) {
ipc_answer_0(rid, EOK);
return;
}
 
void *newdata = realloc(dentry->data, size);
void *newdata = realloc(nodep->data, size);
if (!newdata) {
ipc_answer_0(rid, ENOMEM);
return;
}
if (size > dentry->size) {
size_t delta = size - dentry->size;
memset(newdata + dentry->size, 0, delta);
if (size > nodep->size) {
size_t delta = size - nodep->size;
memset(newdata + nodep->size, 0, delta);
}
dentry->size = size;
dentry->data = newdata;
nodep->size = size;
nodep->data = newdata;
ipc_answer_0(rid, EOK);
}
 
void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, EOK);
}
 
void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
608,18 → 608,37
int rc;
 
link_t *hlp;
unsigned long key = index;
hlp = hash_table_find(&dentries, &key);
unsigned long key[] = {
[NODES_KEY_INDEX] = index,
[NODES_KEY_DEV] = dev_handle
};
hlp = hash_table_find(&nodes, key);
if (!hlp) {
ipc_answer_0(rid, ENOENT);
return;
}
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
dh_link);
rc = tmpfs_destroy_node(dentry);
tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
nh_link);
rc = tmpfs_destroy_node(FS_NODE(nodep));
ipc_answer_0(rid, rc);
}
 
void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request)
{
libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
{
/* Dummy implementation */
ipc_answer_0(rid, EOK);
}
 
/**
* @}
*/
*/
/branches/arm/uspace/srv/fs/tmpfs/tmpfs.h
38,12 → 38,15
#include <atomic.h>
#include <sys/types.h>
#include <bool.h>
#include <libadt/hash_table.h>
#include <adt/hash_table.h>
 
#ifndef dprintf
#define dprintf(...) printf(__VA_ARGS__)
#endif
 
#define TMPFS_NODE(node) ((node) ? (tmpfs_node_t *)(node)->data : NULL)
#define FS_NODE(node) ((node) ? (node)->bp : NULL)
 
typedef enum {
TMPFS_NONE,
TMPFS_FILE,
50,22 → 53,33
TMPFS_DIRECTORY
} tmpfs_dentry_type_t;
 
/* forward declaration */
struct tmpfs_node;
 
typedef struct tmpfs_dentry {
link_t link; /**< Linkage for the list of siblings. */
struct tmpfs_node *node;/**< Back pointer to TMPFS node. */
char *name; /**< Name of dentry. */
} tmpfs_dentry_t;
 
typedef struct tmpfs_node {
fs_node_t *bp; /**< Back pointer to the FS node. */
fs_index_t index; /**< TMPFS node index. */
link_t dh_link; /**< Dentries hash table link. */
struct tmpfs_dentry *sibling;
struct tmpfs_dentry *child;
hash_table_t names; /**< All names linking to this TMPFS node. */
dev_handle_t dev_handle;/**< Device handle. */
link_t nh_link; /**< Nodes hash table link. */
tmpfs_dentry_type_t type;
unsigned lnkcnt; /**< Link count. */
size_t size; /**< File size if type is TMPFS_FILE. */
void *data; /**< File content's if type is TMPFS_FILE. */
} tmpfs_dentry_t;
link_t cs_head; /**< Head of child's siblings list. */
} tmpfs_node_t;
 
extern fs_reg_t tmpfs_reg;
 
extern libfs_ops_t tmpfs_libfs_ops;
 
extern bool tmpfs_init(void);
 
extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
72,7 → 86,11
extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
 
extern bool tmpfs_restore(dev_handle_t);
 
/branches/arm/uspace/srv/fs/tmpfs/tmpfs.c
55,16 → 55,6
 
vfs_info_t tmpfs_vfs_info = {
.name = "tmpfs",
.ops = {
[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_MOUNTED)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL,
[IPC_METHOD_TO_VFS_OP(VFS_DESTROY)] = VFS_OP_DEFINED,
}
};
 
fs_reg_t tmpfs_reg;
106,27 → 96,41
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case VFS_MOUNTED:
case IPC_M_PHONE_HUNGUP:
return;
case VFS_OUT_MOUNTED:
tmpfs_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
tmpfs_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
tmpfs_lookup(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
tmpfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_OUT_WRITE:
tmpfs_write(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_OUT_TRUNCATE:
tmpfs_truncate(callid, &call);
break;
case VFS_DESTROY:
case VFS_OUT_CLOSE:
tmpfs_close(callid, &call);
break;
case VFS_OUT_DESTROY:
tmpfs_destroy(callid, &call);
break;
case VFS_OUT_OPEN_NODE:
tmpfs_open_node(callid, &call);
break;
case VFS_OUT_STAT:
tmpfs_stat(callid, &call);
break;
case VFS_OUT_SYNC:
tmpfs_sync(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
136,24 → 140,26
 
int main(int argc, char **argv)
{
int vfs_phone;
 
printf(NAME ": HelenOS TMPFS file system server\n");
 
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
while (vfs_phone < EOK) {
usleep(10000);
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
if (!tmpfs_init()) {
printf(NAME ": failed to initialize TMPFS\n");
return -1;
}
int rc;
rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
 
int vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
if (vfs_phone < EOK) {
printf(NAME ": Unable to connect to VFS\n");
return -1;
}
 
int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
tmpfs_connection);
if (rc != EOK) {
printf(NAME ": Failed to register file system (%d)\n", rc);
return rc;
}
 
printf(NAME ": Accepting connections\n");
async_manager();
/* not reached */
/branches/arm/uspace/srv/fs/tmpfs/tmpfs_dump.c
38,17 → 38,12
 
#include "tmpfs.h"
#include "../../vfs/vfs.h"
#include <ipc/ipc.h>
#include <async.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <as.h>
#include <libfs.h>
#include <ipc/services.h>
#include <ipc/devmap.h>
#include <sys/mman.h>
#include <libblock.h>
#include <byteorder.h>
 
#define TMPFS_BLOCK_SIZE 1024
59,19 → 54,21
} __attribute__((packed));
 
static bool
tmpfs_restore_recursion(int phone, void *block, off_t *bufpos, size_t *buflen,
off_t *pos, tmpfs_dentry_t *parent)
tmpfs_restore_recursion(dev_handle_t dev, off_t *bufpos, size_t *buflen,
off_t *pos, fs_node_t *pfn)
{
struct rdentry entry;
libfs_ops_t *ops = &tmpfs_libfs_ops;
int rc;
do {
char *fname;
tmpfs_dentry_t *node;
fs_node_t *fn;
tmpfs_node_t *nodep;
uint32_t size;
if (!libfs_blockread(phone, block, bufpos, buflen, pos, &entry,
sizeof(entry), TMPFS_BLOCK_SIZE))
if (block_seqread(dev, bufpos, buflen, pos, &entry,
sizeof(entry), TMPFS_BLOCK_SIZE) != EOK)
return false;
entry.len = uint32_t_le2host(entry.len);
84,40 → 81,42
if (fname == NULL)
return false;
node = (tmpfs_dentry_t *) ops->create(L_FILE);
if (node == NULL) {
fn = ops->create(dev, L_FILE);
if (fn == NULL) {
free(fname);
return false;
}
if (!libfs_blockread(phone, block, bufpos, buflen, pos,
fname, entry.len, TMPFS_BLOCK_SIZE)) {
ops->destroy((void *) node);
if (block_seqread(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
ops->destroy(fn);
free(fname);
return false;
}
fname[entry.len] = 0;
if (!ops->link((void *) parent, (void *) node, fname)) {
ops->destroy((void *) node);
rc = ops->link(pfn, fn, fname);
if (rc != EOK) {
ops->destroy(fn);
free(fname);
return false;
}
free(fname);
if (!libfs_blockread(phone, block, bufpos, buflen, pos,
&size, sizeof(size), TMPFS_BLOCK_SIZE))
if (block_seqread(dev, bufpos, buflen, pos, &size,
sizeof(size), TMPFS_BLOCK_SIZE) != EOK)
return false;
size = uint32_t_le2host(size);
node->data = malloc(size);
if (node->data == NULL)
nodep = TMPFS_NODE(fn);
nodep->data = malloc(size);
if (nodep->data == NULL)
return false;
node->size = size;
if (!libfs_blockread(phone, block, bufpos, buflen, pos,
node->data, size, TMPFS_BLOCK_SIZE))
nodep->size = size;
if (block_seqread(dev, bufpos, buflen, pos, nodep->data,
size, TMPFS_BLOCK_SIZE) != EOK)
return false;
break;
126,29 → 125,30
if (fname == NULL)
return false;
node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY);
if (node == NULL) {
fn = ops->create(dev, L_DIRECTORY);
if (fn == NULL) {
free(fname);
return false;
}
if (!libfs_blockread(phone, block, bufpos, buflen, pos,
fname, entry.len, TMPFS_BLOCK_SIZE)) {
ops->destroy((void *) node);
if (block_seqread(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
ops->destroy(fn);
free(fname);
return false;
}
fname[entry.len] = 0;
if (!ops->link((void *) parent, (void *) node, fname)) {
ops->destroy((void *) node);
 
rc = ops->link(pfn, fn, fname);
if (rc != EOK) {
ops->destroy(fn);
free(fname);
return false;
}
free(fname);
if (!tmpfs_restore_recursion(phone, block, bufpos,
buflen, pos, node))
if (!tmpfs_restore_recursion(dev, bufpos, buflen, pos,
fn))
return false;
break;
163,49 → 163,34
bool tmpfs_restore(dev_handle_t dev)
{
libfs_ops_t *ops = &tmpfs_libfs_ops;
int rc;
 
void *block = mmap(NULL, TMPFS_BLOCK_SIZE,
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
rc = block_init(dev, TMPFS_BLOCK_SIZE);
if (rc != EOK)
return false;
if (block == NULL)
return false;
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, dev);
 
if (phone < 0) {
munmap(block, TMPFS_BLOCK_SIZE);
return false;
}
if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) !=
EOK)
goto error;
off_t bufpos = 0;
size_t buflen = 0;
off_t pos = 0;
char tag[6];
if (!libfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5,
TMPFS_BLOCK_SIZE))
if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5,
TMPFS_BLOCK_SIZE) != EOK)
goto error;
tag[5] = 0;
if (strcmp(tag, "TMPFS") != 0)
if (str_cmp(tag, "TMPFS") != 0)
goto error;
if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos,
if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos,
ops->root_get(dev)))
goto error;
ipc_hangup(phone);
munmap(block, TMPFS_BLOCK_SIZE);
block_fini(dev);
return true;
error:
ipc_hangup(phone);
munmap(block, TMPFS_BLOCK_SIZE);
block_fini(dev);
return false;
}
 
/branches/arm/uspace/srv/fs/tmpfs/Makefile
31,12 → 31,17
 
LIBC_PREFIX = ../../../lib/libc
LIBFS_PREFIX = ../../../lib/libfs
LIBBLOCK_PREFIX = ../../../lib/libblock
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I $(LIBFS_PREFIX)
CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX)
 
LIBS = $(LIBC_PREFIX)/libc.a $(LIBFS_PREFIX)/libfs.a
LIBS = \
$(LIBFS_PREFIX)/libfs.a \
$(LIBBLOCK_PREFIX)/libblock.a \
$(LIBC_PREFIX)/libc.a
 
## Sources
#
56,18 → 61,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/fs/fat/fat_ops.c
36,8 → 36,11
*/
 
#include "fat.h"
#include "fat_dentry.h"
#include "fat_fat.h"
#include "../../vfs/vfs.h"
#include <libfs.h>
#include <libblock.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/devmap.h>
45,234 → 48,26
#include <errno.h>
#include <string.h>
#include <byteorder.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <adt/hash_table.h>
#include <adt/list.h>
#include <assert.h>
#include <futex.h>
#include <fibril_sync.h>
#include <sys/mman.h>
#include <align.h>
 
#define BS_BLOCK 0
#define BS_SIZE 512
#define FAT_NODE(node) ((node) ? (fat_node_t *) (node)->data : NULL)
#define FS_NODE(node) ((node) ? (node)->bp : NULL)
 
/** Futex protecting the list of cached free FAT nodes. */
static futex_t ffn_futex = FUTEX_INITIALIZER;
/** Mutex protecting the list of cached free FAT nodes. */
static FIBRIL_MUTEX_INITIALIZE(ffn_mutex);
 
/** List of cached free FAT nodes. */
static LIST_INITIALIZE(ffn_head);
 
#define FAT_NAME_LEN 8
#define FAT_EXT_LEN 3
 
#define FAT_PAD ' '
 
#define FAT_DENTRY_UNUSED 0x00
#define FAT_DENTRY_E5_ESC 0x05
#define FAT_DENTRY_DOT 0x2e
#define FAT_DENTRY_ERASED 0xe5
 
#define min(a, b) ((a) < (b) ? (a) : (b))
 
static void dentry_name_canonify(fat_dentry_t *d, char *buf)
{
int i;
 
for (i = 0; i < FAT_NAME_LEN; i++) {
if (d->name[i] == FAT_PAD)
break;
if (d->name[i] == FAT_DENTRY_E5_ESC)
*buf++ = 0xe5;
else
*buf++ = d->name[i];
}
if (d->ext[0] != FAT_PAD)
*buf++ = '.';
for (i = 0; i < FAT_EXT_LEN; i++) {
if (d->ext[i] == FAT_PAD) {
*buf = '\0';
return;
}
if (d->ext[i] == FAT_DENTRY_E5_ESC)
*buf++ = 0xe5;
else
*buf++ = d->ext[i];
}
*buf = '\0';
}
 
static int dev_phone = -1; /* FIXME */
static void *dev_buffer = NULL; /* FIXME */
 
/* TODO move somewhere else */
typedef struct {
void *data;
size_t size;
} block_t;
 
static block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
{
/* FIXME */
block_t *b;
off_t bufpos = 0;
size_t buflen = 0;
off_t pos = offset * bs;
 
assert(dev_phone != -1);
assert(dev_buffer);
 
b = malloc(sizeof(block_t));
if (!b)
return NULL;
b->data = malloc(bs);
if (!b->data) {
free(b);
return NULL;
}
b->size = bs;
 
if (!libfs_blockread(dev_phone, dev_buffer, &bufpos, &buflen, &pos,
b->data, bs, bs)) {
free(b->data);
free(b);
return NULL;
}
 
return b;
}
 
static void block_put(block_t *block)
{
/* FIXME */
free(block->data);
free(block);
}
 
#define FAT_BS(b) ((fat_bs_t *)((b)->data))
 
#define FAT_CLST_RES0 0x0000
#define FAT_CLST_RES1 0x0001
#define FAT_CLST_FIRST 0x0002
#define FAT_CLST_BAD 0xfff7
#define FAT_CLST_LAST1 0xfff8
#define FAT_CLST_LAST8 0xffff
 
/* internally used to mark root directory's parent */
#define FAT_CLST_ROOTPAR FAT_CLST_RES0
/* internally used to mark root directory */
#define FAT_CLST_ROOT FAT_CLST_RES1
 
#define fat_block_get(np, off) \
_fat_block_get((np)->idx->dev_handle, (np)->firstc, (off))
 
static block_t *
_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset)
{
block_t *bb;
block_t *b;
unsigned bps;
unsigned spc;
unsigned rscnt; /* block address of the first FAT */
unsigned fatcnt;
unsigned rde;
unsigned rds; /* root directory size */
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters;
fat_cluster_t clst = firstc;
unsigned i;
 
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
spc = FAT_BS(bb)->spc;
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
fatcnt = FAT_BS(bb)->fatcnt;
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
block_put(bb);
 
rds = (sizeof(fat_dentry_t) * rde) / bps;
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
ssa = rscnt + fatcnt * sf + rds;
 
if (firstc == FAT_CLST_ROOT) {
/* root directory special case */
assert(offset < rds);
b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps);
return b;
}
 
clusters = offset / spc;
for (i = 0; i < clusters; i++) {
unsigned fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec, bps);
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
assert(clst < FAT_CLST_LAST1);
block_put(b);
}
 
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
offset % spc, bps);
 
return b;
}
 
/** Return number of blocks allocated to a file.
*
* @param dev_handle Device handle of the device with the file.
* @param firstc First cluster of the file.
*
* @return Number of blocks allocated to the file.
*/
static uint16_t
_fat_blcks_get(dev_handle_t dev_handle, fat_cluster_t firstc)
{
block_t *bb;
block_t *b;
unsigned bps;
unsigned spc;
unsigned rscnt; /* block address of the first FAT */
unsigned clusters = 0;
fat_cluster_t clst = firstc;
 
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
spc = FAT_BS(bb)->spc;
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
block_put(bb);
 
if (firstc == FAT_CLST_RES0) {
/* No space allocated to the file. */
return 0;
}
 
while (clst < FAT_CLST_LAST1) {
unsigned fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST);
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec, bps);
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
block_put(b);
clusters++;
}
 
return clusters * spc;
}
 
static void fat_node_initialize(fat_node_t *node)
{
futex_initialize(&node->lock, 1);
fibril_mutex_initialize(&node->lock);
node->bp = NULL;
node->idx = NULL;
node->type = 0;
link_initialize(&node->ffn_link);
282,52 → 77,83
node->dirty = false;
}
 
static uint16_t fat_bps_get(dev_handle_t dev_handle)
static void fat_node_sync(fat_node_t *node)
{
block_t *bb;
block_t *b;
fat_bs_t *bs;
fat_dentry_t *d;
uint16_t bps;
unsigned dps;
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
assert(bb != NULL);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
block_put(bb);
assert(node->dirty);
 
return bps;
}
bs = block_bb_get(node->idx->dev_handle);
bps = uint16_t_le2host(bs->bps);
dps = bps / sizeof(fat_dentry_t);
/* Read the block that contains the dentry of interest. */
b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc,
(node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
 
typedef enum {
FAT_DENTRY_SKIP,
FAT_DENTRY_LAST,
FAT_DENTRY_VALID
} fat_dentry_clsf_t;
d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);
 
static fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d)
{
if (d->attr & FAT_ATTR_VOLLABEL) {
/* volume label entry */
return FAT_DENTRY_SKIP;
d->firstc = host2uint16_t_le(node->firstc);
if (node->type == FAT_FILE) {
d->size = host2uint32_t_le(node->size);
} else if (node->type == FAT_DIRECTORY) {
d->attr = FAT_ATTR_SUBDIR;
}
if (d->name[0] == FAT_DENTRY_ERASED) {
/* not-currently-used entry */
return FAT_DENTRY_SKIP;
}
if (d->name[0] == FAT_DENTRY_UNUSED) {
/* never used entry */
return FAT_DENTRY_LAST;
}
if (d->name[0] == FAT_DENTRY_DOT) {
/*
* Most likely '.' or '..'.
* It cannot occur in a regular file name.
*/
return FAT_DENTRY_SKIP;
}
return FAT_DENTRY_VALID;
/* TODO: update other fields? (e.g time fields) */
b->dirty = true; /* need to sync block */
block_put(b);
}
 
static void fat_node_sync(fat_node_t *node)
static fat_node_t *fat_node_get_new(void)
{
/* TODO */
fs_node_t *fn;
fat_node_t *nodep;
 
fibril_mutex_lock(&ffn_mutex);
if (!list_empty(&ffn_head)) {
/* Try to use a cached free node structure. */
fat_idx_t *idxp_tmp;
nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
if (!fibril_mutex_trylock(&nodep->lock))
goto skip_cache;
idxp_tmp = nodep->idx;
if (!fibril_mutex_trylock(&idxp_tmp->lock)) {
fibril_mutex_unlock(&nodep->lock);
goto skip_cache;
}
list_remove(&nodep->ffn_link);
fibril_mutex_unlock(&ffn_mutex);
if (nodep->dirty)
fat_node_sync(nodep);
idxp_tmp->nodep = NULL;
fibril_mutex_unlock(&nodep->lock);
fibril_mutex_unlock(&idxp_tmp->lock);
fn = FS_NODE(nodep);
} else {
skip_cache:
/* Try to allocate a new node structure. */
fibril_mutex_unlock(&ffn_mutex);
fn = (fs_node_t *)malloc(sizeof(fs_node_t));
if (!fn)
return NULL;
nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!nodep) {
free(fn);
return NULL;
}
}
fat_node_initialize(nodep);
fs_node_initialize(fn);
fn->data = nodep;
nodep->bp = fn;
return nodep;
}
 
/** Internal version of fat_node_get().
334,12 → 160,14
*
* @param idxp Locked index structure.
*/
static void *fat_node_get_core(fat_idx_t *idxp)
static fat_node_t *fat_node_get_core(fat_idx_t *idxp)
{
block_t *b;
fat_bs_t *bs;
fat_dentry_t *d;
fat_node_t *nodep = NULL;
unsigned bps;
unsigned spc;
unsigned dps;
 
if (idxp->nodep) {
347,10 → 175,10
* We are lucky.
* The node is already instantiated in memory.
*/
futex_down(&idxp->nodep->lock);
fibril_mutex_lock(&idxp->nodep->lock);
if (!idxp->nodep->refcnt++)
list_remove(&idxp->nodep->ffn_link);
futex_up(&idxp->nodep->lock);
fibril_mutex_unlock(&idxp->nodep->lock);
return idxp->nodep;
}
 
360,41 → 188,18
assert(idxp->pfc);
 
futex_down(&ffn_futex);
if (!list_empty(&ffn_head)) {
/* Try to use a cached free node structure. */
fat_idx_t *idxp_tmp;
nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
if (futex_trydown(&nodep->lock) == ESYNCH_WOULD_BLOCK)
goto skip_cache;
idxp_tmp = nodep->idx;
if (futex_trydown(&idxp_tmp->lock) == ESYNCH_WOULD_BLOCK) {
futex_up(&nodep->lock);
goto skip_cache;
}
list_remove(&nodep->ffn_link);
futex_up(&ffn_futex);
if (nodep->dirty)
fat_node_sync(nodep);
idxp_tmp->nodep = NULL;
futex_up(&nodep->lock);
futex_up(&idxp_tmp->lock);
} else {
skip_cache:
/* Try to allocate a new node structure. */
futex_up(&ffn_futex);
nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!nodep)
return NULL;
}
fat_node_initialize(nodep);
nodep = fat_node_get_new();
if (!nodep)
return NULL;
 
bps = fat_bps_get(idxp->dev_handle);
bs = block_bb_get(idxp->dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
dps = bps / sizeof(fat_dentry_t);
 
/* Read the block that contains the dentry of interest. */
b = _fat_block_get(idxp->dev_handle, idxp->pfc,
(idxp->pdi * sizeof(fat_dentry_t)) / bps);
b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc,
(idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
assert(b);
 
d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);
410,7 → 215,7
* defined for the directory entry type. We must determine the
* size of the directory by walking the FAT.
*/
nodep->size = bps * _fat_blcks_get(idxp->dev_handle,
nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle,
uint16_t_le2host(d->firstc));
} else {
nodep->type = FAT_FILE;
429,10 → 234,33
return nodep;
}
 
/*
* Forward declarations of FAT libfs operations.
*/
static fs_node_t *fat_node_get(dev_handle_t, fs_index_t);
static void fat_node_put(fs_node_t *);
static fs_node_t *fat_create_node(dev_handle_t, int);
static int fat_destroy_node(fs_node_t *);
static int fat_link(fs_node_t *, fs_node_t *, const char *);
static int fat_unlink(fs_node_t *, fs_node_t *, const char *);
static fs_node_t *fat_match(fs_node_t *, const char *);
static fs_index_t fat_index_get(fs_node_t *);
static size_t fat_size_get(fs_node_t *);
static unsigned fat_lnkcnt_get(fs_node_t *);
static bool fat_has_children(fs_node_t *);
static fs_node_t *fat_root_get(dev_handle_t);
static char fat_plb_get_char(unsigned);
static bool fat_is_directory(fs_node_t *);
static bool fat_is_file(fs_node_t *node);
 
/*
* FAT libfs operations.
*/
 
/** Instantiate a FAT in-core node. */
static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
fs_node_t *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
{
void *node;
fat_node_t *nodep;
fat_idx_t *idxp;
 
idxp = fat_idx_get_by_index(dev_handle, index);
439,47 → 267,333
if (!idxp)
return NULL;
/* idxp->lock held */
node = fat_node_get_core(idxp);
futex_up(&idxp->lock);
return node;
nodep = fat_node_get_core(idxp);
fibril_mutex_unlock(&idxp->lock);
return FS_NODE(nodep);
}
 
static void fat_node_put(void *node)
void fat_node_put(fs_node_t *fn)
{
fat_node_t *nodep = (fat_node_t *)node;
fat_node_t *nodep = FAT_NODE(fn);
bool destroy = false;
 
futex_down(&nodep->lock);
fibril_mutex_lock(&nodep->lock);
if (!--nodep->refcnt) {
futex_down(&ffn_futex);
list_append(&nodep->ffn_link, &ffn_head);
futex_up(&ffn_futex);
if (nodep->idx) {
fibril_mutex_lock(&ffn_mutex);
list_append(&nodep->ffn_link, &ffn_head);
fibril_mutex_unlock(&ffn_mutex);
} else {
/*
* The node does not have any index structure associated
* with itself. This can only mean that we are releasing
* the node after a failed attempt to allocate the index
* structure for it.
*/
destroy = true;
}
}
futex_up(&nodep->lock);
fibril_mutex_unlock(&nodep->lock);
if (destroy) {
free(nodep->bp);
free(nodep);
}
}
 
static void *fat_create(int flags)
fs_node_t *fat_create_node(dev_handle_t dev_handle, int flags)
{
return NULL; /* not supported at the moment */
fat_idx_t *idxp;
fat_node_t *nodep;
fat_bs_t *bs;
fat_cluster_t mcl, lcl;
uint16_t bps;
int rc;
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
if (flags & L_DIRECTORY) {
/* allocate a cluster */
rc = fat_alloc_clusters(bs, dev_handle, 1, &mcl, &lcl);
if (rc != EOK)
return NULL;
}
 
nodep = fat_node_get_new();
if (!nodep) {
fat_free_clusters(bs, dev_handle, mcl);
return NULL;
}
idxp = fat_idx_get_new(dev_handle);
if (!idxp) {
fat_free_clusters(bs, dev_handle, mcl);
fat_node_put(FS_NODE(nodep));
return NULL;
}
/* idxp->lock held */
if (flags & L_DIRECTORY) {
int i;
block_t *b;
 
/*
* Populate the new cluster with unused dentries.
*/
for (i = 0; i < bs->spc; i++) {
b = _fat_block_get(bs, dev_handle, mcl, i,
BLOCK_FLAGS_NOREAD);
/* mark all dentries as never-used */
memset(b->data, 0, bps);
b->dirty = false;
block_put(b);
}
nodep->type = FAT_DIRECTORY;
nodep->firstc = mcl;
nodep->size = bps * bs->spc;
} else {
nodep->type = FAT_FILE;
nodep->firstc = FAT_CLST_RES0;
nodep->size = 0;
}
nodep->lnkcnt = 0; /* not linked anywhere */
nodep->refcnt = 1;
nodep->dirty = true;
 
nodep->idx = idxp;
idxp->nodep = nodep;
 
fibril_mutex_unlock(&idxp->lock);
return FS_NODE(nodep);
}
 
static int fat_destroy(void *node)
int fat_destroy_node(fs_node_t *fn)
{
return ENOTSUP; /* not supported at the moment */
fat_node_t *nodep = FAT_NODE(fn);
fat_bs_t *bs;
 
/*
* The node is not reachable from the file system. This means that the
* link count should be zero and that the index structure cannot be
* found in the position hash. Obviously, we don't need to lock the node
* nor its index structure.
*/
assert(nodep->lnkcnt == 0);
 
/*
* The node may not have any children.
*/
assert(fat_has_children(fn) == false);
 
bs = block_bb_get(nodep->idx->dev_handle);
if (nodep->firstc != FAT_CLST_RES0) {
assert(nodep->size);
/* Free all clusters allocated to the node. */
fat_free_clusters(bs, nodep->idx->dev_handle, nodep->firstc);
}
 
fat_idx_destroy(nodep->idx);
free(nodep->bp);
free(nodep);
return EOK;
}
 
static bool fat_link(void *prnt, void *chld, const char *name)
int fat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
{
return false; /* not supported at the moment */
fat_node_t *parentp = FAT_NODE(pfn);
fat_node_t *childp = FAT_NODE(cfn);
fat_dentry_t *d;
fat_bs_t *bs;
block_t *b;
int i, j;
uint16_t bps;
unsigned dps;
unsigned blocks;
fat_cluster_t mcl, lcl;
int rc;
 
fibril_mutex_lock(&childp->lock);
if (childp->lnkcnt == 1) {
/*
* On FAT, we don't support multiple hard links.
*/
fibril_mutex_unlock(&childp->lock);
return EMLINK;
}
assert(childp->lnkcnt == 0);
fibril_mutex_unlock(&childp->lock);
 
if (!fat_dentry_name_verify(name)) {
/*
* Attempt to create unsupported name.
*/
return ENOTSUP;
}
 
/*
* Get us an unused parent node's dentry or grow the parent and allocate
* a new one.
*/
fibril_mutex_lock(&parentp->idx->lock);
bs = block_bb_get(parentp->idx->dev_handle);
bps = uint16_t_le2host(bs->bps);
dps = bps / sizeof(fat_dentry_t);
 
blocks = parentp->size / bps;
 
for (i = 0; i < blocks; i++) {
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
for (j = 0; j < dps; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
case FAT_DENTRY_SKIP:
case FAT_DENTRY_VALID:
/* skipping used and meta entries */
continue;
case FAT_DENTRY_FREE:
case FAT_DENTRY_LAST:
/* found an empty slot */
goto hit;
}
}
block_put(b);
}
j = 0;
/*
* We need to grow the parent in order to create a new unused dentry.
*/
if (parentp->idx->pfc == FAT_CLST_ROOT) {
/* Can't grow the root directory. */
fibril_mutex_unlock(&parentp->idx->lock);
return ENOSPC;
}
rc = fat_alloc_clusters(bs, parentp->idx->dev_handle, 1, &mcl, &lcl);
if (rc != EOK) {
fibril_mutex_unlock(&parentp->idx->lock);
return rc;
}
fat_append_clusters(bs, parentp, mcl);
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NOREAD);
d = (fat_dentry_t *)b->data;
/*
* Clear all dentries in the block except for the first one (the first
* dentry will be cleared in the next step).
*/
memset(d + 1, 0, bps - sizeof(fat_dentry_t));
 
hit:
/*
* At this point we only establish the link between the parent and the
* child. The dentry, except of the name and the extension, will remain
* uninitialized until the corresponding node is synced. Thus the valid
* dentry data is kept in the child node structure.
*/
memset(d, 0, sizeof(fat_dentry_t));
fat_dentry_name_set(d, name);
b->dirty = true; /* need to sync block */
block_put(b);
fibril_mutex_unlock(&parentp->idx->lock);
 
fibril_mutex_lock(&childp->idx->lock);
/*
* If possible, create the Sub-directory Identifier Entry and the
* Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries
* are not mandatory according to Standard ECMA-107 and HelenOS VFS does
* not use them anyway, so this is rather a sign of our good will.
*/
b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE);
d = (fat_dentry_t *)b->data;
if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
str_cmp(d->name, FAT_NAME_DOT) == 0) {
memset(d, 0, sizeof(fat_dentry_t));
str_cpy(d->name, 8, FAT_NAME_DOT);
str_cpy(d->ext, 3, FAT_EXT_PAD);
d->attr = FAT_ATTR_SUBDIR;
d->firstc = host2uint16_t_le(childp->firstc);
/* TODO: initialize also the date/time members. */
}
d++;
if (fat_classify_dentry(d) == FAT_DENTRY_LAST ||
str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) {
memset(d, 0, sizeof(fat_dentry_t));
str_cpy(d->name, 8, FAT_NAME_DOT_DOT);
str_cpy(d->ext, 3, FAT_EXT_PAD);
d->attr = FAT_ATTR_SUBDIR;
d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
host2uint16_t_le(FAT_CLST_RES0) :
host2uint16_t_le(parentp->firstc);
/* TODO: initialize also the date/time members. */
}
b->dirty = true; /* need to sync block */
block_put(b);
 
childp->idx->pfc = parentp->firstc;
childp->idx->pdi = i * dps + j;
fibril_mutex_unlock(&childp->idx->lock);
 
fibril_mutex_lock(&childp->lock);
childp->lnkcnt = 1;
childp->dirty = true; /* need to sync node */
fibril_mutex_unlock(&childp->lock);
 
/*
* Hash in the index structure into the position hash.
*/
fat_idx_hashin(childp->idx);
 
return EOK;
}
 
static int fat_unlink(void *prnt, void *chld)
int fat_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
{
return ENOTSUP; /* not supported at the moment */
fat_node_t *parentp = FAT_NODE(pfn);
fat_node_t *childp = FAT_NODE(cfn);
fat_bs_t *bs;
fat_dentry_t *d;
uint16_t bps;
block_t *b;
 
if (!parentp)
return EBUSY;
if (fat_has_children(cfn))
return ENOTEMPTY;
 
fibril_mutex_lock(&parentp->lock);
fibril_mutex_lock(&childp->lock);
assert(childp->lnkcnt == 1);
fibril_mutex_lock(&childp->idx->lock);
bs = block_bb_get(childp->idx->dev_handle);
bps = uint16_t_le2host(bs->bps);
 
b = _fat_block_get(bs, childp->idx->dev_handle, childp->idx->pfc,
(childp->idx->pdi * sizeof(fat_dentry_t)) / bps,
BLOCK_FLAGS_NONE);
d = (fat_dentry_t *)b->data +
(childp->idx->pdi % (bps / sizeof(fat_dentry_t)));
/* mark the dentry as not-currently-used */
d->name[0] = FAT_DENTRY_ERASED;
b->dirty = true; /* need to sync block */
block_put(b);
 
/* remove the index structure from the position hash */
fat_idx_hashout(childp->idx);
/* clear position information */
childp->idx->pfc = FAT_CLST_RES0;
childp->idx->pdi = 0;
fibril_mutex_unlock(&childp->idx->lock);
childp->lnkcnt = 0;
childp->dirty = true;
fibril_mutex_unlock(&childp->lock);
fibril_mutex_unlock(&parentp->lock);
 
return EOK;
}
 
static void *fat_match(void *prnt, const char *component)
fs_node_t *fat_match(fs_node_t *pfn, const char *component)
{
fat_node_t *parentp = (fat_node_t *)prnt;
fat_bs_t *bs;
fat_node_t *parentp = FAT_NODE(pfn);
char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
unsigned i, j;
unsigned bps; /* bytes per sector */
488,34 → 602,31
fat_dentry_t *d;
block_t *b;
 
futex_down(&parentp->idx->lock);
bps = fat_bps_get(parentp->idx->dev_handle);
fibril_mutex_lock(&parentp->idx->lock);
bs = block_bb_get(parentp->idx->dev_handle);
bps = uint16_t_le2host(bs->bps);
dps = bps / sizeof(fat_dentry_t);
blocks = parentp->size / bps + (parentp->size % bps != 0);
blocks = parentp->size / bps;
for (i = 0; i < blocks; i++) {
unsigned dentries;
b = fat_block_get(parentp, i);
dentries = (i == blocks - 1) ?
parentp->size % sizeof(fat_dentry_t) :
dps;
for (j = 0; j < dentries; j++) {
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
for (j = 0; j < dps; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
case FAT_DENTRY_SKIP:
case FAT_DENTRY_FREE:
continue;
case FAT_DENTRY_LAST:
block_put(b);
futex_up(&parentp->idx->lock);
fibril_mutex_unlock(&parentp->idx->lock);
return NULL;
default:
case FAT_DENTRY_VALID:
dentry_name_canonify(d, name);
fat_dentry_name_get(d, name);
break;
}
if (stricmp(name, component) == 0) {
if (fat_dentry_namecmp(name, component) == 0) {
/* hit */
void *node;
fat_node_t *nodep;
/*
* Assume tree hierarchy for locking. We
* already have the parent and now we are going
525,7 → 636,7
fat_idx_t *idx = fat_idx_get_by_pos(
parentp->idx->dev_handle, parentp->firstc,
i * dps + j);
futex_up(&parentp->idx->lock);
fibril_mutex_unlock(&parentp->idx->lock);
if (!idx) {
/*
* Can happen if memory is low or if we
534,39 → 645,38
block_put(b);
return NULL;
}
node = fat_node_get_core(idx);
futex_up(&idx->lock);
nodep = fat_node_get_core(idx);
fibril_mutex_unlock(&idx->lock);
block_put(b);
return node;
return FS_NODE(nodep);
}
}
block_put(b);
}
futex_up(&parentp->idx->lock);
 
fibril_mutex_unlock(&parentp->idx->lock);
return NULL;
}
 
static fs_index_t fat_index_get(void *node)
fs_index_t fat_index_get(fs_node_t *fn)
{
fat_node_t *fnodep = (fat_node_t *)node;
if (!fnodep)
return 0;
return fnodep->idx->index;
return FAT_NODE(fn)->idx->index;
}
 
static size_t fat_size_get(void *node)
size_t fat_size_get(fs_node_t *fn)
{
return ((fat_node_t *)node)->size;
return FAT_NODE(fn)->size;
}
 
static unsigned fat_lnkcnt_get(void *node)
unsigned fat_lnkcnt_get(fs_node_t *fn)
{
return ((fat_node_t *)node)->lnkcnt;
return FAT_NODE(fn)->lnkcnt;
}
 
static bool fat_has_children(void *node)
bool fat_has_children(fs_node_t *fn)
{
fat_node_t *nodep = (fat_node_t *)node;
fat_bs_t *bs;
fat_node_t *nodep = FAT_NODE(fn);
unsigned bps;
unsigned dps;
unsigned blocks;
575,65 → 685,63
 
if (nodep->type != FAT_DIRECTORY)
return false;
 
futex_down(&nodep->idx->lock);
bps = fat_bps_get(nodep->idx->dev_handle);
fibril_mutex_lock(&nodep->idx->lock);
bs = block_bb_get(nodep->idx->dev_handle);
bps = uint16_t_le2host(bs->bps);
dps = bps / sizeof(fat_dentry_t);
 
blocks = nodep->size / bps + (nodep->size % bps != 0);
blocks = nodep->size / bps;
 
for (i = 0; i < blocks; i++) {
unsigned dentries;
fat_dentry_t *d;
b = fat_block_get(nodep, i);
dentries = (i == blocks - 1) ?
nodep->size % sizeof(fat_dentry_t) :
dps;
for (j = 0; j < dentries; j++) {
b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE);
for (j = 0; j < dps; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
case FAT_DENTRY_SKIP:
case FAT_DENTRY_FREE:
continue;
case FAT_DENTRY_LAST:
block_put(b);
futex_up(&nodep->idx->lock);
fibril_mutex_unlock(&nodep->idx->lock);
return false;
default:
case FAT_DENTRY_VALID:
block_put(b);
futex_up(&nodep->idx->lock);
fibril_mutex_unlock(&nodep->idx->lock);
return true;
}
block_put(b);
futex_up(&nodep->idx->lock);
fibril_mutex_unlock(&nodep->idx->lock);
return true;
}
block_put(b);
}
 
futex_up(&nodep->idx->lock);
fibril_mutex_unlock(&nodep->idx->lock);
return false;
}
 
static void *fat_root_get(dev_handle_t dev_handle)
fs_node_t *fat_root_get(dev_handle_t dev_handle)
{
return fat_node_get(dev_handle, 0);
}
 
static char fat_plb_get_char(unsigned pos)
char fat_plb_get_char(unsigned pos)
{
return fat_reg.plb_ro[pos % PLB_SIZE];
}
 
static bool fat_is_directory(void *node)
bool fat_is_directory(fs_node_t *fn)
{
return ((fat_node_t *)node)->type == FAT_DIRECTORY;
return FAT_NODE(fn)->type == FAT_DIRECTORY;
}
 
static bool fat_is_file(void *node)
bool fat_is_file(fs_node_t *fn)
{
return ((fat_node_t *)node)->type == FAT_FILE;
return FAT_NODE(fn)->type == FAT_FILE;
}
 
/** libfs operations */
641,8 → 749,8
.match = fat_match,
.node_get = fat_node_get,
.node_put = fat_node_put,
.create = fat_create,
.destroy = fat_destroy,
.create = fat_create_node,
.destroy = fat_destroy_node,
.link = fat_link,
.unlink = fat_unlink,
.index_get = fat_index_get,
655,68 → 763,103
.is_file = fat_is_file
};
 
/*
* VFS operations.
*/
 
void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
block_t *bb;
enum cache_mode cmode;
fat_bs_t *bs;
uint16_t bps;
uint16_t rde;
int rc;
 
/*
* For now, we don't bother to remember dev_handle, dev_phone or
* dev_buffer in some data structure. We use global variables because we
* know there will be at most one mount on this file system.
* Of course, this is a huge TODO item.
*/
dev_buffer = mmap(NULL, BS_SIZE, PROTO_READ | PROTO_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!dev_buffer) {
/* accept the mount options */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *opts = malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(opts);
return;
}
opts[size] = '\0';
 
dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, dev_handle);
/* Check for option enabling write through. */
if (str_cmp(opts, "wtcache") == 0)
cmode = CACHE_MODE_WT;
else
cmode = CACHE_MODE_WB;
 
if (dev_phone < 0) {
munmap(dev_buffer, BS_SIZE);
ipc_answer_0(rid, dev_phone);
/* initialize libblock */
rc = block_init(dev_handle, BS_SIZE);
if (rc != EOK) {
ipc_answer_0(rid, rc);
return;
}
 
rc = ipc_share_out_start(dev_phone, dev_buffer,
AS_AREA_READ | AS_AREA_WRITE);
/* prepare the boot block */
rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE);
if (rc != EOK) {
munmap(dev_buffer, BS_SIZE);
block_fini(dev_handle);
ipc_answer_0(rid, rc);
return;
}
 
/* get the buffer with the boot sector */
bs = block_bb_get(dev_handle);
/* Read the number of root directory entries. */
bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
block_put(bb);
bps = uint16_t_le2host(bs->bps);
rde = uint16_t_le2host(bs->root_ent_max);
 
if (bps != BS_SIZE) {
munmap(dev_buffer, BS_SIZE);
block_fini(dev_handle);
ipc_answer_0(rid, ENOTSUP);
return;
}
 
/* Initialize the block cache */
rc = block_cache_init(dev_handle, bps, 0 /* XXX */, cmode);
if (rc != EOK) {
block_fini(dev_handle);
ipc_answer_0(rid, rc);
return;
}
 
rc = fat_idx_init_by_dev_handle(dev_handle);
if (rc != EOK) {
munmap(dev_buffer, BS_SIZE);
block_fini(dev_handle);
ipc_answer_0(rid, rc);
return;
}
 
/* Initialize the root node. */
fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
if (!rfn) {
block_fini(dev_handle);
fat_idx_fini_by_dev_handle(dev_handle);
ipc_answer_0(rid, ENOMEM);
return;
}
fs_node_initialize(rfn);
fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!rootp) {
munmap(dev_buffer, BS_SIZE);
free(rfn);
block_fini(dev_handle);
fat_idx_fini_by_dev_handle(dev_handle);
ipc_answer_0(rid, ENOMEM);
return;
725,8 → 868,9
 
fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0);
if (!ridxp) {
munmap(dev_buffer, BS_SIZE);
free(rfn);
free(rootp);
block_fini(dev_handle);
fat_idx_fini_by_dev_handle(dev_handle);
ipc_answer_0(rid, ENOMEM);
return;
741,8 → 885,10
rootp->size = rde * sizeof(fat_dentry_t);
rootp->idx = ridxp;
ridxp->nodep = rootp;
rootp->bp = rfn;
rfn->data = rootp;
futex_up(&ridxp->lock);
fibril_mutex_unlock(&ridxp->lock);
 
ipc_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
}
749,7 → 895,7
 
void fat_mount(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
762,25 → 908,31
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
off_t pos = (off_t)IPC_GET_ARG3(*request);
fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
uint16_t bps = fat_bps_get(dev_handle);
fs_node_t *fn = fat_node_get(dev_handle, index);
fat_node_t *nodep;
fat_bs_t *bs;
uint16_t bps;
size_t bytes;
block_t *b;
 
if (!nodep) {
if (!fn) {
ipc_answer_0(rid, ENOENT);
return;
}
nodep = FAT_NODE(fn);
 
ipc_callid_t callid;
size_t len;
if (!ipc_data_read_receive(&callid, &len)) {
fat_node_put(nodep);
fat_node_put(fn);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
 
if (nodep->type == FAT_FILE) {
/*
* Our strategy for regular file reads is to read one block at
787,11 → 939,19
* most and make use of the possibility to return less data than
* requested. This keeps the code very simple.
*/
bytes = min(len, bps - pos % bps);
b = fat_block_get(nodep, pos / bps);
(void) ipc_data_read_finalize(callid, b->data + pos % bps,
bytes);
block_put(b);
if (pos >= nodep->size) {
/* reading beyond the EOF */
bytes = 0;
(void) ipc_data_read_finalize(callid, NULL, 0);
} else {
bytes = min(len, bps - pos % bps);
bytes = min(bytes, nodep->size - pos);
b = fat_block_get(bs, nodep, pos / bps,
BLOCK_FLAGS_NONE);
(void) ipc_data_read_finalize(callid, b->data + pos % bps,
bytes);
block_put(b);
}
} else {
unsigned bnum;
off_t spos = pos;
812,7 → 972,7
while (bnum < nodep->size / bps) {
off_t o;
 
b = fat_block_get(nodep, bnum);
b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE);
for (o = pos % (bps / sizeof(fat_dentry_t));
o < bps / sizeof(fat_dentry_t);
o++, pos++) {
819,6 → 979,7
d = ((fat_dentry_t *)b->data) + o;
switch (fat_classify_dentry(d)) {
case FAT_DENTRY_SKIP:
case FAT_DENTRY_FREE:
continue;
case FAT_DENTRY_LAST:
block_put(b);
825,7 → 986,7
goto miss;
default:
case FAT_DENTRY_VALID:
dentry_name_canonify(d, name);
fat_dentry_name_get(d, name);
block_put(b);
goto hit;
}
834,19 → 995,224
bnum++;
}
miss:
fat_node_put(nodep);
fat_node_put(fn);
ipc_answer_0(callid, ENOENT);
ipc_answer_1(rid, ENOENT, 0);
return;
hit:
(void) ipc_data_read_finalize(callid, name, strlen(name) + 1);
(void) ipc_data_read_finalize(callid, name, str_size(name) + 1);
bytes = (pos - spos) + 1;
}
 
fat_node_put(nodep);
fat_node_put(fn);
ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
}
 
void fat_write(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
off_t pos = (off_t)IPC_GET_ARG3(*request);
fs_node_t *fn = fat_node_get(dev_handle, index);
fat_node_t *nodep;
fat_bs_t *bs;
size_t bytes;
block_t *b;
uint16_t bps;
unsigned spc;
unsigned bpc; /* bytes per cluster */
off_t boundary;
int flags = BLOCK_FLAGS_NONE;
if (!fn) {
ipc_answer_0(rid, ENOENT);
return;
}
nodep = FAT_NODE(fn);
ipc_callid_t callid;
size_t len;
if (!ipc_data_write_receive(&callid, &len)) {
fat_node_put(fn);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
bpc = bps * spc;
 
/*
* In all scenarios, we will attempt to write out only one block worth
* of data at maximum. There might be some more efficient approaches,
* but this one greatly simplifies fat_write(). Note that we can afford
* to do this because the client must be ready to handle the return
* value signalizing a smaller number of bytes written.
*/
bytes = min(len, bps - pos % bps);
if (bytes == bps)
flags |= BLOCK_FLAGS_NOREAD;
boundary = ROUND_UP(nodep->size, bpc);
if (pos < boundary) {
/*
* This is the easier case - we are either overwriting already
* existing contents or writing behind the EOF, but still within
* the limits of the last cluster. The node size may grow to the
* next block size boundary.
*/
fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
b = fat_block_get(bs, nodep, pos / bps, flags);
(void) ipc_data_write_finalize(callid, b->data + pos % bps,
bytes);
b->dirty = true; /* need to sync block */
block_put(b);
if (pos + bytes > nodep->size) {
nodep->size = pos + bytes;
nodep->dirty = true; /* need to sync node */
}
ipc_answer_2(rid, EOK, bytes, nodep->size);
fat_node_put(fn);
return;
} else {
/*
* This is the more difficult case. We must allocate new
* clusters for the node and zero them out.
*/
int status;
unsigned nclsts;
fat_cluster_t mcl, lcl;
nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
/* create an independent chain of nclsts clusters in all FATs */
status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
if (status != EOK) {
/* could not allocate a chain of nclsts clusters */
fat_node_put(fn);
ipc_answer_0(callid, status);
ipc_answer_0(rid, status);
return;
}
/* zero fill any gaps */
fat_fill_gap(bs, nodep, mcl, pos);
b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc,
flags);
(void) ipc_data_write_finalize(callid, b->data + pos % bps,
bytes);
b->dirty = true; /* need to sync block */
block_put(b);
/*
* Append the cluster chain starting in mcl to the end of the
* node's cluster chain.
*/
fat_append_clusters(bs, nodep, mcl);
nodep->size = pos + bytes;
nodep->dirty = true; /* need to sync node */
ipc_answer_2(rid, EOK, bytes, nodep->size);
fat_node_put(fn);
return;
}
}
 
void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
size_t size = (off_t)IPC_GET_ARG3(*request);
fs_node_t *fn = fat_node_get(dev_handle, index);
fat_node_t *nodep;
fat_bs_t *bs;
uint16_t bps;
uint8_t spc;
unsigned bpc; /* bytes per cluster */
int rc;
 
if (!fn) {
ipc_answer_0(rid, ENOENT);
return;
}
nodep = FAT_NODE(fn);
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
bpc = bps * spc;
 
if (nodep->size == size) {
rc = EOK;
} else if (nodep->size < size) {
/*
* The standard says we have the freedom to grow the node.
* For now, we simply return an error.
*/
rc = EINVAL;
} else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {
/*
* The node will be shrunk, but no clusters will be deallocated.
*/
nodep->size = size;
nodep->dirty = true; /* need to sync node */
rc = EOK;
} else {
/*
* The node will be shrunk, clusters will be deallocated.
*/
if (size == 0) {
fat_chop_clusters(bs, nodep, FAT_CLST_RES0);
} else {
fat_cluster_t lastc;
(void) fat_cluster_walk(bs, dev_handle, nodep->firstc,
&lastc, (size - 1) / bpc);
fat_chop_clusters(bs, nodep, lastc);
}
nodep->size = size;
nodep->dirty = true; /* need to sync node */
rc = EOK;
}
fat_node_put(fn);
ipc_answer_0(rid, rc);
return;
}
 
void fat_close(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, EOK);
}
 
void fat_destroy(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
int rc;
 
fs_node_t *fn = fat_node_get(dev_handle, index);
if (!fn) {
ipc_answer_0(rid, ENOENT);
return;
}
 
rc = fat_destroy_node(fn);
ipc_answer_0(rid, rc);
}
 
void fat_open_node(ipc_callid_t rid, ipc_call_t *request)
{
libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_stat(ipc_callid_t rid, ipc_call_t *request)
{
libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_sync(ipc_callid_t rid, ipc_call_t *request)
{
/* Dummy implementation */
ipc_answer_0(rid, EOK);
}
 
/**
* @}
*/
*/
/branches/arm/uspace/srv/fs/fat/fat.h
33,7 → 33,9
#ifndef FAT_FAT_H_
#define FAT_FAT_H_
 
#include "fat_fat.h"
#include <ipc/ipc.h>
#include <fibril_sync.h>
#include <libfs.h>
#include <atomic.h>
#include <sys/types.h>
44,7 → 46,12
#define dprintf(...) printf(__VA_ARGS__)
#endif
 
typedef struct {
#define min(a, b) ((a) < (b) ? (a) : (b))
 
#define BS_BLOCK 0
#define BS_SIZE 512
 
typedef struct fat_bs {
uint8_t ji[3]; /**< Jump instruction. */
uint8_t oem_name[8];
/* BIOS Parameter Block */
115,34 → 122,6
};
} __attribute__ ((packed)) fat_bs_t;
 
#define FAT_ATTR_RDONLY (1 << 0)
#define FAT_ATTR_VOLLABEL (1 << 3)
#define FAT_ATTR_SUBDIR (1 << 4)
 
typedef struct {
uint8_t name[8];
uint8_t ext[3];
uint8_t attr;
uint8_t reserved;
uint8_t ctime_fine;
uint16_t ctime;
uint16_t cdate;
uint16_t adate;
union {
uint16_t eaidx; /* FAT12/FAT16 */
uint16_t firstc_hi; /* FAT32 */
};
uint16_t mtime;
uint16_t mdate;
union {
uint16_t firstc; /* FAT12/FAT16 */
uint16_t firstc_lo; /* FAT32 */
};
uint32_t size;
} __attribute__ ((packed)) fat_dentry_t;
 
typedef uint16_t fat_cluster_t;
 
typedef enum {
FAT_INVALID,
FAT_DIRECTORY,
182,7 → 161,7
/** Used indices (index) hash table link. */
link_t uih_link;
 
futex_t lock;
fibril_mutex_t lock;
dev_handle_t dev_handle;
fs_index_t index;
/**
200,7 → 179,10
 
/** FAT in-core node. */
typedef struct fat_node {
futex_t lock;
/** Back pointer to the FS node. */
fs_node_t *bp;
fibril_mutex_t lock;
fat_node_type_t type;
fat_idx_t *idx;
/**
223,9 → 205,21
extern void fat_mount(ipc_callid_t, ipc_call_t *);
extern void fat_lookup(ipc_callid_t, ipc_call_t *);
extern void fat_read(ipc_callid_t, ipc_call_t *);
extern void fat_write(ipc_callid_t, ipc_call_t *);
extern void fat_truncate(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_close(ipc_callid_t, ipc_call_t *);
extern void fat_destroy(ipc_callid_t, ipc_call_t *);
extern void fat_open_node(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_sync(ipc_callid_t, ipc_call_t *);
 
extern fat_idx_t *fat_idx_get_new(dev_handle_t);
extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned);
extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t);
extern void fat_idx_destroy(fat_idx_t *);
extern void fat_idx_hashin(fat_idx_t *);
extern void fat_idx_hashout(fat_idx_t *);
 
extern int fat_idx_init(void);
extern void fat_idx_fini(void);
/branches/arm/uspace/srv/fs/fat/fat.c
49,15 → 49,6
 
vfs_info_t fat_vfs_info = {
.name = "fat",
.ops = {
[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_NULL,
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL,
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL,
[IPC_METHOD_TO_VFS_OP(VFS_MOUNTED)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL,
}
};
 
fs_reg_t fat_reg;
98,18 → 89,41
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case VFS_MOUNTED:
case IPC_M_PHONE_HUNGUP:
return;
case VFS_OUT_MOUNTED:
fat_mounted(callid, &call);
break;
case VFS_MOUNT:
case VFS_OUT_MOUNT:
fat_mount(callid, &call);
break;
case VFS_LOOKUP:
case VFS_OUT_LOOKUP:
fat_lookup(callid, &call);
break;
case VFS_READ:
case VFS_OUT_READ:
fat_read(callid, &call);
break;
case VFS_OUT_WRITE:
fat_write(callid, &call);
break;
case VFS_OUT_TRUNCATE:
fat_truncate(callid, &call);
break;
case VFS_OUT_STAT:
fat_stat(callid, &call);
break;
case VFS_OUT_CLOSE:
fat_close(callid, &call);
break;
case VFS_OUT_DESTROY:
fat_destroy(callid, &call);
break;
case VFS_OUT_OPEN_NODE:
fat_open_node(callid, &call);
break;
case VFS_OUT_SYNC:
fat_sync(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
122,16 → 136,16
int vfs_phone;
int rc;
 
printf("FAT: HelenOS FAT file system server.\n");
printf("fat: HelenOS FAT file system server.\n");
 
rc = fat_idx_init();
if (rc != EOK)
goto err;
 
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
while (vfs_phone < EOK) {
usleep(10000);
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
if (vfs_phone < EOK) {
printf("fat: failed to connect to VFS\n");
return -1;
}
rc = fs_register(vfs_phone, &fat_reg, &fat_vfs_info, fat_connection);
/branches/arm/uspace/srv/fs/fat/fat_idx.c
39,10 → 39,10
#include "../../vfs/vfs.h"
#include <errno.h>
#include <string.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <adt/hash_table.h>
#include <adt/list.h>
#include <assert.h>
#include <futex.h>
#include <fibril_sync.h>
 
/** Each instance of this type describes one interval of freed VFS indices. */
typedef struct {
68,8 → 68,8
link_t freed_head;
} unused_t;
 
/** Futex protecting the list of unused structures. */
static futex_t unused_futex = FUTEX_INITIALIZER;
/** Mutex protecting the list of unused structures. */
static FIBRIL_MUTEX_INITIALIZE(unused_lock);
 
/** List of unused structures. */
static LIST_INITIALIZE(unused_head);
89,7 → 89,7
link_t *l;
 
if (lock)
futex_down(&unused_futex);
fibril_mutex_lock(&unused_lock);
for (l = unused_head.next; l != &unused_head; l = l->next) {
u = list_get_instance(l, unused_t, link);
if (u->dev_handle == dev_handle)
96,12 → 96,12
return u;
}
if (lock)
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return NULL;
}
 
/** Futex protecting the up_hash and ui_hash. */
static futex_t used_futex = FUTEX_INITIALIZER;
/** Mutex protecting the up_hash and ui_hash. */
static FIBRIL_MUTEX_INITIALIZE(used_lock);
 
/**
* Global hash table of all used fat_idx_t structures.
214,7 → 214,7
};
 
/** Allocate a VFS index which is not currently in use. */
static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index)
static bool fat_index_alloc(dev_handle_t dev_handle, fs_index_t *index)
{
unused_t *u;
231,7 → 231,7
*/
*index = u->next++;
--u->remaining;
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return true;
}
} else {
244,7 → 244,7
list_remove(&f->link);
free(f);
}
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return true;
}
/*
252,7 → 252,7
* theoretically still possible (e.g. too many open unlinked nodes or
* too many zero-sized nodes).
*/
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return false;
}
 
276,7 → 276,7
}
 
/** Free a VFS index, which is no longer in use. */
static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index)
static void fat_index_free(dev_handle_t dev_handle, fs_index_t index)
{
unused_t *u;
 
302,7 → 302,7
if (lnk->prev != &u->freed_head)
try_coalesce_intervals(lnk->prev, lnk,
lnk);
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return;
}
if (f->last == index - 1) {
310,7 → 310,7
if (lnk->next != &u->freed_head)
try_coalesce_intervals(lnk, lnk->next,
lnk);
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return;
}
if (index > f->first) {
321,7 → 321,7
n->first = index;
n->last = index;
list_insert_before(&n->link, lnk);
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return;
}
 
335,9 → 335,55
n->last = index;
list_append(&n->link, &u->freed_head);
}
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
}
 
static fat_idx_t *fat_idx_create(dev_handle_t dev_handle)
{
fat_idx_t *fidx;
 
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
if (!fidx)
return NULL;
if (!fat_index_alloc(dev_handle, &fidx->index)) {
free(fidx);
return NULL;
}
link_initialize(&fidx->uph_link);
link_initialize(&fidx->uih_link);
fibril_mutex_initialize(&fidx->lock);
fidx->dev_handle = dev_handle;
fidx->pfc = FAT_CLST_RES0; /* no parent yet */
fidx->pdi = 0;
fidx->nodep = NULL;
 
return fidx;
}
 
fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle)
{
fat_idx_t *fidx;
 
fibril_mutex_lock(&used_lock);
fidx = fat_idx_create(dev_handle);
if (!fidx) {
fibril_mutex_unlock(&used_lock);
return NULL;
}
unsigned long ikey[] = {
[UIH_DH_KEY] = dev_handle,
[UIH_INDEX_KEY] = fidx->index,
};
hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
fibril_mutex_lock(&fidx->lock);
fibril_mutex_unlock(&used_lock);
 
return fidx;
}
 
fat_idx_t *
fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi)
{
349,21 → 395,16
[UPH_PDI_KEY] = pdi,
};
 
futex_down(&used_futex);
fibril_mutex_lock(&used_lock);
l = hash_table_find(&up_hash, pkey);
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
} else {
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
fidx = fat_idx_create(dev_handle);
if (!fidx) {
futex_up(&used_futex);
fibril_mutex_unlock(&used_lock);
return NULL;
}
if (!fat_idx_alloc(dev_handle, &fidx->index)) {
free(fidx);
futex_up(&used_futex);
return NULL;
}
unsigned long ikey[] = {
[UIH_DH_KEY] = dev_handle,
370,23 → 411,44
[UIH_INDEX_KEY] = fidx->index,
};
link_initialize(&fidx->uph_link);
link_initialize(&fidx->uih_link);
futex_initialize(&fidx->lock, 1);
fidx->dev_handle = dev_handle;
fidx->pfc = pfc;
fidx->pdi = pdi;
fidx->nodep = NULL;
 
hash_table_insert(&up_hash, pkey, &fidx->uph_link);
hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
}
futex_down(&fidx->lock);
futex_up(&used_futex);
fibril_mutex_lock(&fidx->lock);
fibril_mutex_unlock(&used_lock);
 
return fidx;
}
 
void fat_idx_hashin(fat_idx_t *idx)
{
unsigned long pkey[] = {
[UPH_DH_KEY] = idx->dev_handle,
[UPH_PFC_KEY] = idx->pfc,
[UPH_PDI_KEY] = idx->pdi,
};
 
fibril_mutex_lock(&used_lock);
hash_table_insert(&up_hash, pkey, &idx->uph_link);
fibril_mutex_unlock(&used_lock);
}
 
void fat_idx_hashout(fat_idx_t *idx)
{
unsigned long pkey[] = {
[UPH_DH_KEY] = idx->dev_handle,
[UPH_PFC_KEY] = idx->pfc,
[UPH_PDI_KEY] = idx->pdi,
};
 
fibril_mutex_lock(&used_lock);
hash_table_remove(&up_hash, pkey, 3);
fibril_mutex_unlock(&used_lock);
}
 
fat_idx_t *
fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index)
{
397,17 → 459,44
[UIH_INDEX_KEY] = index,
};
 
futex_down(&used_futex);
fibril_mutex_lock(&used_lock);
l = hash_table_find(&ui_hash, ikey);
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uih_link);
futex_down(&fidx->lock);
fibril_mutex_lock(&fidx->lock);
}
futex_up(&used_futex);
fibril_mutex_unlock(&used_lock);
 
return fidx;
}
 
/** Destroy the index structure.
*
* @param idx The index structure to be destroyed.
*/
void fat_idx_destroy(fat_idx_t *idx)
{
unsigned long ikey[] = {
[UIH_DH_KEY] = idx->dev_handle,
[UIH_INDEX_KEY] = idx->index,
};
 
assert(idx->pfc == FAT_CLST_RES0);
 
fibril_mutex_lock(&used_lock);
/*
* Since we can only free unlinked nodes, the index structure is not
* present in the position hash (uph). We therefore hash it out from
* the index hash only.
*/
hash_table_remove(&ui_hash, ikey, 2);
fibril_mutex_unlock(&used_lock);
/* Release the VFS index. */
fat_index_free(idx->dev_handle, idx->index);
/* Deallocate the structure. */
free(idx);
}
 
int fat_idx_init(void)
{
if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops))
435,12 → 524,12
if (!u)
return ENOMEM;
unused_initialize(u, dev_handle);
futex_down(&unused_futex);
fibril_mutex_lock(&unused_lock);
if (!unused_find(dev_handle, false))
list_append(&u->link, &unused_head);
else
rc = EEXIST;
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
return rc;
}
 
451,7 → 540,7
u = unused_find(dev_handle, true);
assert(u);
list_remove(&u->link);
futex_up(&unused_futex);
fibril_mutex_unlock(&unused_lock);
 
while (!list_empty(&u->freed_head)) {
freed_t *f;
/branches/arm/uspace/srv/fs/fat/fat_fat.c
0,0 → 1,455
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
/**
* @file fat_fat.c
* @brief Functions that manipulate the File Allocation Tables.
*/
 
#include "fat_fat.h"
#include "fat_dentry.h"
#include "fat.h"
#include "../../vfs/vfs.h"
#include <libfs.h>
#include <libblock.h>
#include <errno.h>
#include <byteorder.h>
#include <align.h>
#include <assert.h>
#include <fibril_sync.h>
#include <mem.h>
 
/**
* The fat_alloc_lock mutex protects all copies of the File Allocation Table
* during allocation of clusters. The lock does not have to be held durring
* deallocation of clusters.
*/
static FIBRIL_MUTEX_INITIALIZE(fat_alloc_lock);
 
/** Walk the cluster chain.
*
* @param bs Buffer holding the boot sector for the file.
* @param dev_handle Device handle of the device with the file.
* @param firstc First cluster to start the walk with.
* @param lastc If non-NULL, output argument hodling the last cluster number visited.
* @param max_clusters Maximum number of clusters to visit.
*
* @return Number of clusters seen during the walk.
*/
uint16_t
fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
fat_cluster_t *lastc, uint16_t max_clusters)
{
block_t *b;
unsigned bps;
unsigned rscnt; /* block address of the first FAT */
uint16_t clusters = 0;
fat_cluster_t clst = firstc;
 
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
 
if (firstc == FAT_CLST_RES0) {
/* No space allocated to the file. */
if (lastc)
*lastc = firstc;
return 0;
}
 
while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
bn_t fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST);
if (lastc)
*lastc = clst; /* remember the last cluster number */
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
block_put(b);
clusters++;
}
 
if (lastc && clst < FAT_CLST_LAST1)
*lastc = clst;
 
return clusters;
}
 
/** Read block from file located on a FAT file system.
*
* @param bs Buffer holding the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param firstc First cluster used by the file. Can be zero if the file
* is empty.
* @param bn Block number.
* @param flags Flags passed to libblock.
*
* @return Block structure holding the requested block.
*/
block_t *
_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
bn_t bn, int flags)
{
block_t *b;
unsigned bps;
unsigned rscnt; /* block address of the first FAT */
unsigned rde;
unsigned rds; /* root directory size */
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters, max_clusters;
fat_cluster_t lastc;
 
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
rde = uint16_t_le2host(bs->root_ent_max);
sf = uint16_t_le2host(bs->sec_per_fat);
 
rds = (sizeof(fat_dentry_t) * rde) / bps;
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
ssa = rscnt + bs->fatcnt * sf + rds;
 
if (firstc == FAT_CLST_ROOT) {
/* root directory special case */
assert(bn < rds);
b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn, flags);
return b;
}
 
max_clusters = bn / bs->spc;
clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,
max_clusters);
assert(clusters == max_clusters);
 
b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +
bn % bs->spc, flags);
 
return b;
}
 
/** Fill the gap between EOF and a new file position.
*
* @param bs Buffer holding the boot sector for nodep.
* @param nodep FAT node with the gap.
* @param mcl First cluster in an independent cluster chain that will
* be later appended to the end of the node's own cluster
* chain. If pos is still in the last allocated cluster,
* this argument is ignored.
* @param pos Position in the last node block.
*/
void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
{
uint16_t bps;
unsigned spc;
block_t *b;
off_t o, boundary;
 
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
boundary = ROUND_UP(nodep->size, bps * spc);
 
/* zero out already allocated space */
for (o = nodep->size; o < pos && o < boundary;
o = ALIGN_DOWN(o + bps, bps)) {
int flags = (o % bps == 0) ?
BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
b = fat_block_get(bs, nodep, o / bps, flags);
memset(b->data + o % bps, 0, bps - o % bps);
b->dirty = true; /* need to sync node */
block_put(b);
}
if (o >= pos)
return;
/* zero out the initial part of the new cluster chain */
for (o = boundary; o < pos; o += bps) {
b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,
(o - boundary) / bps, BLOCK_FLAGS_NOREAD);
memset(b->data, 0, min(bps, pos - o));
b->dirty = true; /* need to sync node */
block_put(b);
}
}
 
/** Get cluster from the first FAT.
*
* @param bs Buffer holding the boot sector for the file system.
* @param dev_handle Device handle for the file system.
* @param clst Cluster which to get.
*
* @return Value found in the cluster.
*/
fat_cluster_t
fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst)
{
block_t *b;
uint16_t bps;
uint16_t rscnt;
fat_cluster_t *cp, value;
 
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
 
b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps,
BLOCK_FLAGS_NONE);
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
value = uint16_t_le2host(*cp);
block_put(b);
return value;
}
 
/** Set cluster in one instance of FAT.
*
* @param bs Buffer holding the boot sector for the file system.
* @param dev_handle Device handle for the file system.
* @param fatno Number of the FAT instance where to make the change.
* @param clst Cluster which is to be set.
* @param value Value to set the cluster with.
*/
void
fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
fat_cluster_t clst, fat_cluster_t value)
{
block_t *b;
uint16_t bps;
uint16_t rscnt;
uint16_t sf;
fat_cluster_t *cp;
 
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
sf = uint16_t_le2host(bs->sec_per_fat);
 
assert(fatno < bs->fatcnt);
b = block_get(dev_handle, rscnt + sf * fatno +
(clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
*cp = host2uint16_t_le(value);
b->dirty = true; /* need to sync block */
block_put(b);
}
 
/** Replay the allocatoin of clusters in all shadow instances of FAT.
*
* @param bs Buffer holding the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param lifo Chain of allocated clusters.
* @param nclsts Number of clusters in the lifo chain.
*/
void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle,
fat_cluster_t *lifo, unsigned nclsts)
{
uint8_t fatno;
unsigned c;
 
for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
for (c = 0; c < nclsts; c++) {
fat_set_cluster(bs, dev_handle, fatno, lifo[c],
c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
}
}
}
 
/** Allocate clusters in all copies of FAT.
*
* This function will attempt to allocate the requested number of clusters in
* all instances of the FAT. The FAT will be altered so that the allocated
* clusters form an independent chain (i.e. a chain which does not belong to any
* file yet).
*
* @param bs Buffer holding the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param nclsts Number of clusters to allocate.
* @param mcl Output parameter where the first cluster in the chain
* will be returned.
* @param lcl Output parameter where the last cluster in the chain
* will be returned.
*
* @return EOK on success, a negative error code otherwise.
*/
int
fat_alloc_clusters(fat_bs_t *bs, dev_handle_t dev_handle, unsigned nclsts,
fat_cluster_t *mcl, fat_cluster_t *lcl)
{
uint16_t bps;
uint16_t rscnt;
uint16_t sf;
block_t *blk;
fat_cluster_t *lifo; /* stack for storing free cluster numbers */
unsigned found = 0; /* top of the free cluster number stack */
unsigned b, c, cl;
 
lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));
if (!lifo)
return ENOMEM;
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
sf = uint16_t_le2host(bs->sec_per_fat);
/*
* Search FAT1 for unused clusters.
*/
fibril_mutex_lock(&fat_alloc_lock);
for (b = 0, cl = 0; b < sf; b++) {
blk = block_get(dev_handle, rscnt + b, BLOCK_FLAGS_NONE);
for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
if (uint16_t_le2host(*clst) == FAT_CLST_RES0) {
/*
* The cluster is free. Put it into our stack
* of found clusters and mark it as non-free.
*/
lifo[found] = cl;
*clst = (found == 0) ?
host2uint16_t_le(FAT_CLST_LAST1) :
host2uint16_t_le(lifo[found - 1]);
blk->dirty = true; /* need to sync block */
if (++found == nclsts) {
/* we are almost done */
block_put(blk);
/* update the shadow copies of FAT */
fat_alloc_shadow_clusters(bs,
dev_handle, lifo, nclsts);
*mcl = lifo[found - 1];
*lcl = lifo[0];
free(lifo);
fibril_mutex_unlock(&fat_alloc_lock);
return EOK;
}
}
}
block_put(blk);
}
fibril_mutex_unlock(&fat_alloc_lock);
 
/*
* We could not find enough clusters. Now we need to free the clusters
* we have allocated so far.
*/
while (found--) {
fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
FAT_CLST_RES0);
}
free(lifo);
return ENOSPC;
}
 
/** Free clusters forming a cluster chain in all copies of FAT.
*
* @param bs Buffer hodling the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param firstc First cluster in the chain which is to be freed.
*/
void
fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc)
{
unsigned fatno;
fat_cluster_t nextc;
 
/* Mark all clusters in the chain as free in all copies of FAT. */
while (firstc < FAT_CLST_LAST1) {
assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD);
nextc = fat_get_cluster(bs, dev_handle, firstc);
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_set_cluster(bs, dev_handle, fatno, firstc,
FAT_CLST_RES0);
firstc = nextc;
}
}
 
/** Append a cluster chain to the last file cluster in all FATs.
*
* @param bs Buffer holding the boot sector of the file system.
* @param nodep Node representing the file.
* @param mcl First cluster of the cluster chain to append.
*/
void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl)
{
dev_handle_t dev_handle = nodep->idx->dev_handle;
fat_cluster_t lcl;
uint8_t fatno;
 
if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl,
(uint16_t) -1) == 0) {
/* No clusters allocated to the node yet. */
nodep->firstc = mcl;
nodep->dirty = true; /* need to sync node */
return;
}
 
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
}
 
/** Chop off node clusters in all copies of FAT.
*
* @param bs Buffer holding the boot sector of the file system.
* @param nodep FAT node where the chopping will take place.
* @param lastc Last cluster which will remain in the node. If this
* argument is FAT_CLST_RES0, then all clusters will
* be chopped off.
*/
void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
{
dev_handle_t dev_handle = nodep->idx->dev_handle;
if (lastc == FAT_CLST_RES0) {
/* The node will have zero size and no clusters allocated. */
fat_free_clusters(bs, dev_handle, nodep->firstc);
nodep->firstc = FAT_CLST_RES0;
nodep->dirty = true; /* need to sync node */
} else {
fat_cluster_t nextc;
unsigned fatno;
 
nextc = fat_get_cluster(bs, dev_handle, lastc);
 
/* Terminate the cluster chain in all copies of FAT. */
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1);
 
/* Free all following clusters. */
fat_free_clusters(bs, dev_handle, nextc);
}
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/fat/Makefile
31,12 → 31,17
 
LIBC_PREFIX = ../../../lib/libc
LIBFS_PREFIX = ../../../lib/libfs
LIBBLOCK_PREFIX = ../../../lib/libblock
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I $(LIBFS_PREFIX)
CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX)
 
LIBS = $(LIBC_PREFIX)/libc.a $(LIBFS_PREFIX)/libfs.a
LIBS = \
$(LIBFS_PREFIX)/libfs.a \
$(LIBBLOCK_PREFIX)/libblock.a \
$(LIBC_PREFIX)/libc.a
 
## Sources
#
45,7 → 50,9
SOURCES = \
fat.c \
fat_ops.c \
fat_idx.c
fat_idx.c \
fat_dentry.c \
fat_fat.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
56,18 → 63,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/fs/fat/fat_dentry.c
0,0 → 1,243
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
/**
* @file fat_dentry.c
* @brief Functions that work with FAT directory entries.
*/
 
#include "fat_dentry.h"
#include <ctype.h>
#include <string.h>
 
static bool is_d_char(const char ch)
{
if (isalnum(ch) || ch == '_')
return true;
else
return false;
}
 
/** Compare path component with the name read from the dentry.
*
* This function compares the path component with the name read from the dentry.
* The comparison is case insensitive and tolerates a mismatch on the trailing
* dot character at the end of the name (i.e. when there is a dot, but no
* extension).
*
* @param name Node name read from the dentry.
* @param component Path component.
*
* @return Zero on match, non-zero otherwise.
*/
int fat_dentry_namecmp(char *name, const char *component)
{
int rc;
size_t size;
 
if (!(rc = stricmp(name, component)))
return rc;
if (!str_chr(name, '.')) {
/*
* There is no '.' in the name, so we know that there is enough
* space for appending an extra '.' to name.
*/
size = str_size(name);
name[size] = '.';
name[size + 1] = '\0';
rc = stricmp(name, component);
}
return rc;
}
 
bool fat_dentry_name_verify(const char *name)
{
unsigned i, dot;
bool dot_found = false;
 
for (i = 0; name[i]; i++) {
if (name[i] == '.') {
if (dot_found) {
return false;
} else {
dot_found = true;
dot = i;
}
} else {
if (!is_d_char(name[i]))
return false;
}
}
 
if (dot_found) {
if (dot > FAT_NAME_LEN)
return false;
if (i - dot > FAT_EXT_LEN + 1)
return false;
} else {
if (i > FAT_NAME_LEN)
return false;
}
 
return true;
}
 
void fat_dentry_name_get(const fat_dentry_t *d, char *buf)
{
unsigned int i;
for (i = 0; i < FAT_NAME_LEN; i++) {
if (d->name[i] == FAT_PAD)
break;
if (d->name[i] == FAT_DENTRY_E5_ESC)
*buf++ = 0xe5;
else {
if (d->lcase & FAT_LCASE_LOWER_NAME)
*buf++ = tolower(d->name[i]);
else
*buf++ = d->name[i];
}
}
if (d->ext[0] != FAT_PAD)
*buf++ = '.';
for (i = 0; i < FAT_EXT_LEN; i++) {
if (d->ext[i] == FAT_PAD) {
*buf = '\0';
return;
}
if (d->ext[i] == FAT_DENTRY_E5_ESC)
*buf++ = 0xe5;
else {
if (d->lcase & FAT_LCASE_LOWER_EXT)
*buf++ = tolower(d->ext[i]);
else
*buf++ = d->ext[i];
}
}
*buf = '\0';
}
 
void fat_dentry_name_set(fat_dentry_t *d, const char *name)
{
unsigned int i;
const char fake_ext[] = " ";
bool lower_name = true;
bool lower_ext = true;
for (i = 0; i < FAT_NAME_LEN; i++) {
switch ((uint8_t) *name) {
case 0xe5:
d->name[i] = FAT_DENTRY_E5_ESC;
name++;
break;
case '\0':
case '.':
d->name[i] = FAT_PAD;
break;
default:
if (isalpha(*name)) {
if (!islower(*name))
lower_name = false;
}
d->name[i] = toupper(*name++);
break;
}
}
if (*name++ != '.')
name = fake_ext;
for (i = 0; i < FAT_EXT_LEN; i++) {
switch ((uint8_t) *name) {
case 0xe5:
d->ext[i] = FAT_DENTRY_E5_ESC;
name++;
break;
case '\0':
d->ext[i] = FAT_PAD;
break;
default:
if (isalpha(*name)) {
if (!islower(*name))
lower_ext = false;
}
d->ext[i] = toupper(*name++);
break;
}
}
if (lower_name)
d->lcase |= FAT_LCASE_LOWER_NAME;
else
d->lcase &= ~FAT_LCASE_LOWER_NAME;
if (lower_ext)
d->lcase |= FAT_LCASE_LOWER_EXT;
else
d->lcase &= ~FAT_LCASE_LOWER_EXT;
}
 
fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d)
{
if (d->attr & FAT_ATTR_VOLLABEL) {
/* volume label entry */
return FAT_DENTRY_SKIP;
}
if (d->name[0] == FAT_DENTRY_ERASED) {
/* not-currently-used entry */
return FAT_DENTRY_FREE;
}
if (d->name[0] == FAT_DENTRY_UNUSED) {
/* never used entry */
return FAT_DENTRY_LAST;
}
if (d->name[0] == FAT_DENTRY_DOT) {
/*
* Most likely '.' or '..'.
* It cannot occur in a regular file name.
*/
return FAT_DENTRY_SKIP;
}
return FAT_DENTRY_VALID;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/fat/fat_dentry.h
0,0 → 1,99
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
#ifndef FAT_FAT_DENTRY_H_
#define FAT_FAT_DENTRY_H_
 
#include <stdint.h>
#include <bool.h>
 
#define FAT_NAME_LEN 8
#define FAT_EXT_LEN 3
 
#define FAT_NAME_DOT ". "
#define FAT_NAME_DOT_DOT ".. "
#define FAT_EXT_PAD " "
 
#define FAT_ATTR_RDONLY (1 << 0)
#define FAT_ATTR_VOLLABEL (1 << 3)
#define FAT_ATTR_SUBDIR (1 << 4)
 
#define FAT_LCASE_LOWER_NAME 0x08
#define FAT_LCASE_LOWER_EXT 0x10
 
#define FAT_PAD ' '
 
#define FAT_DENTRY_UNUSED 0x00
#define FAT_DENTRY_E5_ESC 0x05
#define FAT_DENTRY_DOT 0x2e
#define FAT_DENTRY_ERASED 0xe5
 
typedef enum {
FAT_DENTRY_SKIP,
FAT_DENTRY_LAST,
FAT_DENTRY_FREE,
FAT_DENTRY_VALID
} fat_dentry_clsf_t;
 
typedef struct {
uint8_t name[8];
uint8_t ext[3];
uint8_t attr;
uint8_t lcase;
uint8_t ctime_fine;
uint16_t ctime;
uint16_t cdate;
uint16_t adate;
union {
uint16_t eaidx; /* FAT12/FAT16 */
uint16_t firstc_hi; /* FAT32 */
} __attribute__ ((packed));
uint16_t mtime;
uint16_t mdate;
union {
uint16_t firstc; /* FAT12/FAT16 */
uint16_t firstc_lo; /* FAT32 */
} __attribute__ ((packed));
uint32_t size;
} __attribute__ ((packed)) fat_dentry_t;
 
extern int fat_dentry_namecmp(char *, const char *);
extern bool fat_dentry_name_verify(const char *);
extern void fat_dentry_name_get(const fat_dentry_t *, char *);
extern void fat_dentry_name_set(fat_dentry_t *, const char *);
extern fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/fs/fat/fat_fat.h
0,0 → 1,91
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fs
* @{
*/
 
#ifndef FAT_FAT_FAT_H_
#define FAT_FAT_FAT_H_
 
#include "../../vfs/vfs.h"
#include <stdint.h>
#include <libblock.h>
 
#define FAT1 0
 
#define FAT_CLST_RES0 0x0000
#define FAT_CLST_RES1 0x0001
#define FAT_CLST_FIRST 0x0002
#define FAT_CLST_BAD 0xfff7
#define FAT_CLST_LAST1 0xfff8
#define FAT_CLST_LAST8 0xffff
 
/* internally used to mark root directory's parent */
#define FAT_CLST_ROOTPAR FAT_CLST_RES0
/* internally used to mark root directory */
#define FAT_CLST_ROOT FAT_CLST_RES1
 
/* forward declarations */
struct block;
struct fat_node;
struct fat_bs;
 
typedef uint16_t fat_cluster_t;
 
#define fat_clusters_get(bs, dh, fc) \
fat_cluster_walk((bs), (dh), (fc), NULL, (uint16_t) -1)
extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,
fat_cluster_t *, uint16_t);
 
#define fat_block_get(bs, np, bn, flags) \
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags))
 
extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,
fat_cluster_t, bn_t, int);
extern void fat_append_clusters(struct fat_bs *, struct fat_node *,
fat_cluster_t);
extern void fat_chop_clusters(struct fat_bs *, struct fat_node *,
fat_cluster_t);
extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned,
fat_cluster_t *, fat_cluster_t *);
extern void fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);
extern void fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,
fat_cluster_t *, unsigned);
extern fat_cluster_t fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
extern void fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned,
fat_cluster_t, fat_cluster_t);
extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
off_t);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/arch/sparc64/src/scanc.c
File deleted
/branches/arm/uspace/srv/kbd/arch/sparc64/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/sparc64/include/scanc.h
File deleted
/branches/arm/uspace/srv/kbd/arch/sparc64/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/ia64/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/ia64/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/include/scanc.h
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/include/pl050.h
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/src/kbd_gxemul.c
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/src/scanc.c
File deleted
/branches/arm/uspace/srv/kbd/arch/arm32/src/kbd_icp.c
File deleted
/branches/arm/uspace/srv/kbd/arch/mips32eb
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/uspace/srv/kbd/arch/ppc32/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/ppc32/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/amd64
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/uspace/srv/kbd/arch/ppc64/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/ppc64/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/mips32/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/mips32/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/ia32/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/arch/ia32/src/scanc.c
File deleted
/branches/arm/uspace/srv/kbd/arch/ia32/src/mouse.c
File deleted
/branches/arm/uspace/srv/kbd/arch/ia32/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/arch/ia32/include/scanc.h
File deleted
/branches/arm/uspace/srv/kbd/ctl/pc.c
0,0 → 1,234
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief PC keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
 
enum dec_state {
ds_s,
ds_e
};
 
static enum dec_state ds;
 
static int scanmap_simple[] = {
 
[0x29] = KC_BACKTICK,
 
[0x02] = KC_1,
[0x03] = KC_2,
[0x04] = KC_3,
[0x05] = KC_4,
[0x06] = KC_5,
[0x07] = KC_6,
[0x08] = KC_7,
[0x09] = KC_8,
[0x0a] = KC_9,
[0x0b] = KC_0,
 
[0x0c] = KC_MINUS,
[0x0d] = KC_EQUALS,
[0x0e] = KC_BACKSPACE,
 
[0x0f] = KC_TAB,
 
[0x10] = KC_Q,
[0x11] = KC_W,
[0x12] = KC_E,
[0x13] = KC_R,
[0x14] = KC_T,
[0x15] = KC_Y,
[0x16] = KC_U,
[0x17] = KC_I,
[0x18] = KC_O,
[0x19] = KC_P,
 
[0x1a] = KC_LBRACKET,
[0x1b] = KC_RBRACKET,
 
[0x3a] = KC_CAPS_LOCK,
 
[0x1e] = KC_A,
[0x1f] = KC_S,
[0x20] = KC_D,
[0x21] = KC_F,
[0x22] = KC_G,
[0x23] = KC_H,
[0x24] = KC_J,
[0x25] = KC_K,
[0x26] = KC_L,
 
[0x27] = KC_SEMICOLON,
[0x28] = KC_QUOTE,
[0x2b] = KC_BACKSLASH,
 
[0x2a] = KC_LSHIFT,
 
[0x2c] = KC_Z,
[0x2d] = KC_X,
[0x2e] = KC_C,
[0x2f] = KC_V,
[0x30] = KC_B,
[0x31] = KC_N,
[0x32] = KC_M,
 
[0x33] = KC_COMMA,
[0x34] = KC_PERIOD,
[0x35] = KC_SLASH,
 
[0x36] = KC_RSHIFT,
 
[0x1d] = KC_LCTRL,
[0x38] = KC_LALT,
[0x39] = KC_SPACE,
 
[0x01] = KC_ESCAPE,
 
[0x3b] = KC_F1,
[0x3c] = KC_F2,
[0x3d] = KC_F3,
[0x3e] = KC_F4,
[0x3f] = KC_F5,
[0x40] = KC_F6,
[0x41] = KC_F7,
 
[0x42] = KC_F8,
[0x43] = KC_F9,
[0x44] = KC_F10,
 
[0x57] = KC_F11,
[0x58] = KC_F12,
 
[0x46] = KC_SCROLL_LOCK,
 
[0x1c] = KC_ENTER,
 
[0x45] = KC_NUM_LOCK,
[0x37] = KC_NTIMES,
[0x4a] = KC_NMINUS,
[0x4e] = KC_NPLUS,
[0x47] = KC_N7,
[0x48] = KC_N8,
[0x49] = KC_N9,
[0x4b] = KC_N4,
[0x4c] = KC_N5,
[0x4d] = KC_N6,
[0x4f] = KC_N1,
[0x50] = KC_N2,
[0x51] = KC_N3,
[0x52] = KC_N0,
[0x53] = KC_NPERIOD
};
 
static int scanmap_e0[] = {
[0x38] = KC_RALT,
[0x1d] = KC_RSHIFT,
 
[0x37] = KC_PRTSCR,
 
[0x52] = KC_INSERT,
[0x47] = KC_HOME,
[0x49] = KC_PAGE_UP,
 
[0x53] = KC_DELETE,
[0x4f] = KC_END,
[0x51] = KC_PAGE_DOWN,
 
[0x48] = KC_UP,
[0x4b] = KC_LEFT,
[0x50] = KC_DOWN,
[0x4d] = KC_RIGHT,
 
[0x35] = KC_NSLASH,
[0x1c] = KC_NENTER
};
 
int kbd_ctl_init(void)
{
ds = ds_s;
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
console_ev_type_t type;
unsigned int key;
int *map;
size_t map_length;
 
if (scancode == 0xe0) {
ds = ds_e;
return;
}
 
switch (ds) {
case ds_s:
map = scanmap_simple;
map_length = sizeof(scanmap_simple) / sizeof(int);
break;
case ds_e:
map = scanmap_e0;
map_length = sizeof(scanmap_e0) / sizeof(int);
break;
default:
map = NULL;
map_length = 0;
}
 
ds = ds_s;
 
if (scancode & 0x80) {
scancode &= ~0x80;
type = KEY_RELEASE;
} else {
type = KEY_PRESS;
}
 
if ((scancode < 0) || ((size_t) scancode >= map_length))
return;
 
key = map[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/ctl/stty.c
0,0 → 1,228
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief Serial TTY-like keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stroke.h>
 
/** Scancode parser */
static gsp_t sp;
 
/** Current parser state */
static int ds;
 
#include <stdio.h>
 
int seq_defs[] = {
/* Not shifted */
 
0, KC_BACKTICK, 0x60, GSP_END,
 
0, KC_1, 0x31, GSP_END,
0, KC_2, 0x32, GSP_END,
0, KC_3, 0x33, GSP_END,
0, KC_4, 0x34, GSP_END,
0, KC_5, 0x35, GSP_END,
0, KC_6, 0x36, GSP_END,
0, KC_7, 0x37, GSP_END,
0, KC_8, 0x38, GSP_END,
0, KC_9, 0x39, GSP_END,
0, KC_0, 0x30, GSP_END,
 
0, KC_MINUS, 0x2d, GSP_END,
0, KC_EQUALS, 0x3d, GSP_END,
0, KC_BACKSPACE, 0x08, GSP_END,
 
0, KC_TAB, 0x09, GSP_END,
 
0, KC_Q, 0x71, GSP_END,
0, KC_W, 0x77, GSP_END,
0, KC_E, 0x65, GSP_END,
0, KC_R, 0x72, GSP_END,
0, KC_T, 0x74, GSP_END,
0, KC_Y, 0x79, GSP_END,
0, KC_U, 0x75, GSP_END,
0, KC_I, 0x69, GSP_END,
0, KC_O, 0x6f, GSP_END,
0, KC_P, 0x70, GSP_END,
 
0, KC_LBRACKET, 0x5b, GSP_END,
0, KC_RBRACKET, 0x5d, GSP_END,
 
0, KC_A, 0x61, GSP_END,
0, KC_S, 0x73, GSP_END,
0, KC_D, 0x64, GSP_END,
0, KC_F, 0x66, GSP_END,
0, KC_G, 0x67, GSP_END,
0, KC_H, 0x68, GSP_END,
0, KC_J, 0x6a, GSP_END,
0, KC_K, 0x6b, GSP_END,
0, KC_L, 0x6c, GSP_END,
 
0, KC_SEMICOLON, 0x3b, GSP_END,
0, KC_QUOTE, 0x27, GSP_END,
0, KC_BACKSLASH, 0x5c, GSP_END,
 
0, KC_Z, 0x7a, GSP_END,
0, KC_X, 0x78, GSP_END,
0, KC_C, 0x63, GSP_END,
0, KC_V, 0x76, GSP_END,
0, KC_B, 0x62, GSP_END,
0, KC_N, 0x6e, GSP_END,
0, KC_M, 0x6d, GSP_END,
 
0, KC_COMMA, 0x2c, GSP_END,
0, KC_PERIOD, 0x2e, GSP_END,
0, KC_SLASH, 0x2f, GSP_END,
 
/* Shifted */
 
KM_SHIFT, KC_BACKTICK, 0x7e, GSP_END,
 
KM_SHIFT, KC_1, 0x21, GSP_END,
KM_SHIFT, KC_2, 0x40, GSP_END,
KM_SHIFT, KC_3, 0x23, GSP_END,
KM_SHIFT, KC_4, 0x24, GSP_END,
KM_SHIFT, KC_5, 0x25, GSP_END,
KM_SHIFT, KC_6, 0x5e, GSP_END,
KM_SHIFT, KC_7, 0x26, GSP_END,
KM_SHIFT, KC_8, 0x2a, GSP_END,
KM_SHIFT, KC_9, 0x28, GSP_END,
KM_SHIFT, KC_0, 0x29, GSP_END,
 
KM_SHIFT, KC_MINUS, 0x5f, GSP_END,
KM_SHIFT, KC_EQUALS, 0x2b, GSP_END,
 
KM_SHIFT, KC_Q, 0x51, GSP_END,
KM_SHIFT, KC_W, 0x57, GSP_END,
KM_SHIFT, KC_E, 0x45, GSP_END,
KM_SHIFT, KC_R, 0x52, GSP_END,
KM_SHIFT, KC_T, 0x54, GSP_END,
KM_SHIFT, KC_Y, 0x59, GSP_END,
KM_SHIFT, KC_U, 0x55, GSP_END,
KM_SHIFT, KC_I, 0x49, GSP_END,
KM_SHIFT, KC_O, 0x4f, GSP_END,
KM_SHIFT, KC_P, 0x50, GSP_END,
 
KM_SHIFT, KC_LBRACKET, 0x7b, GSP_END,
KM_SHIFT, KC_RBRACKET, 0x7d, GSP_END,
 
KM_SHIFT, KC_A, 0x41, GSP_END,
KM_SHIFT, KC_S, 0x53, GSP_END,
KM_SHIFT, KC_D, 0x44, GSP_END,
KM_SHIFT, KC_F, 0x46, GSP_END,
KM_SHIFT, KC_G, 0x47, GSP_END,
KM_SHIFT, KC_H, 0x48, GSP_END,
KM_SHIFT, KC_J, 0x4a, GSP_END,
KM_SHIFT, KC_K, 0x4b, GSP_END,
KM_SHIFT, KC_L, 0x4c, GSP_END,
 
KM_SHIFT, KC_SEMICOLON, 0x3a, GSP_END,
KM_SHIFT, KC_QUOTE, 0x22, GSP_END,
KM_SHIFT, KC_BACKSLASH, 0x7c, GSP_END,
 
KM_SHIFT, KC_Z, 0x5a, GSP_END,
KM_SHIFT, KC_X, 0x58, GSP_END,
KM_SHIFT, KC_C, 0x43, GSP_END,
KM_SHIFT, KC_V, 0x56, GSP_END,
KM_SHIFT, KC_B, 0x42, GSP_END,
KM_SHIFT, KC_N, 0x4e, GSP_END,
KM_SHIFT, KC_M, 0x4d, GSP_END,
 
KM_SHIFT, KC_COMMA, 0x3c, GSP_END,
KM_SHIFT, KC_PERIOD, 0x3e, GSP_END,
KM_SHIFT, KC_SLASH, 0x3f, GSP_END,
 
/* ... */
 
0, KC_SPACE, 0x20, GSP_END,
0, KC_ENTER, 0x0a, GSP_END,
0, KC_ENTER, 0x0d, GSP_END,
 
0, KC_ESCAPE, 0x1b, 0x1b, GSP_END,
 
0, KC_F1, 0x1b, 0x4f, 0x50, GSP_END,
0, KC_F2, 0x1b, 0x4f, 0x51, GSP_END,
0, KC_F3, 0x1b, 0x4f, 0x52, GSP_END,
0, KC_F4, 0x1b, 0x4f, 0x53, GSP_END,
0, KC_F5, 0x1b, 0x5b, 0x31, 0x35, 0x7e, GSP_END,
0, KC_F6, 0x1b, 0x5b, 0x31, 0x37, 0x7e, GSP_END,
0, KC_F7, 0x1b, 0x5b, 0x31, 0x38, 0x7e, GSP_END,
0, KC_F8, 0x1b, 0x5b, 0x31, 0x39, 0x7e, GSP_END,
0, KC_F9, 0x1b, 0x5b, 0x32, 0x30, 0x7e, GSP_END,
0, KC_F10, 0x1b, 0x5b, 0x32, 0x31, 0x7e, GSP_END,
0, KC_F11, 0x1b, 0x5b, 0x32, 0x33, 0x7e, GSP_END,
0, KC_F12, 0x1b, 0x5b, 0x32, 0x34, 0x7e, GSP_END,
 
0, KC_INSERT, 0x1b, 0x5b, 0x32, 0x7e, GSP_END,
0, KC_HOME, 0x1b, 0x5b, 0x48, GSP_END,
0, KC_PAGE_UP, 0x1b, 0x5b, 0x35, 0x7e, GSP_END,
0, KC_DELETE, 0x1b, 0x5b, 0x33, 0x7e, GSP_END,
0, KC_END, 0x1b, 0x5b, 0x46, GSP_END,
0, KC_PAGE_DOWN, 0x1b, 0x5b, 0x36, 0x7e, GSP_END,
 
0, KC_UP, 0x1b, 0x5b, 0x41, GSP_END,
0, KC_LEFT, 0x1b, 0x5b, 0x44, GSP_END,
0, KC_DOWN, 0x1b, 0x5b, 0x42, GSP_END,
0, KC_RIGHT, 0x1b, 0x5b, 0x43, GSP_END,
 
0, 0
};
 
int kbd_ctl_init(void)
{
ds = 0;
 
gsp_init(&sp);
return gsp_insert_defs(&sp, seq_defs);
}
 
void kbd_ctl_parse_scancode(int scancode)
{
unsigned mods, key;
 
ds = gsp_step(&sp, ds, scancode, &mods, &key);
if (key != 0) {
stroke_sim(mods, key);
}
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/ctl/sun.c
0,0 → 1,209
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief Sun keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
 
#define KBD_KEY_RELEASE 0x80
#define KBD_ALL_KEYS_UP 0x7f
 
static int scanmap_simple[];
 
int kbd_ctl_init(void)
{
return 0;
}
 
void kbd_ctl_parse_scancode(int scancode)
{
console_ev_type_t type;
unsigned int key;
 
if (scancode < 0 || scancode >= 0x100)
return;
 
if (scancode == KBD_ALL_KEYS_UP)
return;
 
if (scancode & KBD_KEY_RELEASE) {
scancode &= ~KBD_KEY_RELEASE;
type = KEY_RELEASE;
} else {
type = KEY_PRESS;
}
 
key = scanmap_simple[scancode];
if (key != 0)
kbd_push_ev(type, key);
}
 
/** Primary meaning of scancodes. */
static int scanmap_simple[] = {
[0x00] = 0,
[0x01] = 0,
[0x02] = 0,
[0x03] = 0,
[0x04] = 0,
[0x05] = KC_F1,
[0x06] = KC_F2,
[0x07] = KC_F10,
[0x08] = KC_F3,
[0x09] = KC_F11,
[0x0a] = KC_F4,
[0x0b] = KC_F12,
[0x0c] = KC_F5,
[0x0d] = KC_RALT,
[0x0e] = KC_F6,
[0x0f] = 0,
[0x10] = KC_F7,
[0x11] = KC_F8,
[0x12] = KC_F9,
[0x13] = KC_LALT,
[0x14] = KC_UP,
[0x15] = KC_PAUSE,
[0x16] = 0,
[0x17] = KC_SCROLL_LOCK,
[0x18] = KC_LEFT,
[0x19] = 0,
[0x1a] = 0,
[0x1b] = KC_DOWN,
[0x1c] = KC_RIGHT,
[0x1d] = KC_ESCAPE,
[0x1e] = KC_1,
[0x1f] = KC_2,
[0x20] = KC_3,
[0x21] = KC_4,
[0x22] = KC_5,
[0x23] = KC_6,
[0x24] = KC_7,
[0x25] = KC_8,
[0x26] = KC_9,
[0x27] = KC_0,
[0x28] = KC_MINUS,
[0x29] = KC_EQUALS,
[0x2a] = KC_BACKTICK,
[0x2b] = KC_BACKSPACE,
[0x2c] = KC_INSERT,
[0x2d] = 0,
[0x2e] = KC_NSLASH,
[0x2f] = KC_NTIMES,
[0x30] = 0,
[0x31] = 0,
[0x32] = KC_NPERIOD,
[0x33] = 0,
[0x34] = KC_HOME,
[0x35] = KC_TAB,
[0x36] = KC_Q,
[0x37] = KC_W,
[0x38] = KC_E,
[0x39] = KC_R,
[0x3a] = KC_T,
[0x3b] = KC_Y,
[0x3c] = KC_U,
[0x3d] = KC_I,
[0x3e] = KC_O,
[0x3f] = KC_P,
[0x40] = KC_LBRACKET,
[0x41] = KC_RBRACKET,
[0x42] = KC_DELETE,
[0x43] = 0,
[0x44] = KC_N7,
[0x45] = KC_N8,
[0x46] = KC_N9,
[0x47] = KC_NMINUS,
[0x48] = 0,
[0x49] = 0,
[0x4a] = KC_END,
[0x4b] = 0,
[0x4c] = KC_LCTRL,
[0x4d] = KC_A,
[0x4e] = KC_S,
[0x4f] = KC_D,
[0x50] = KC_F,
[0x51] = KC_G,
[0x52] = KC_H,
[0x53] = KC_J,
[0x54] = KC_K,
[0x55] = KC_L,
[0x56] = KC_SEMICOLON,
[0x57] = KC_QUOTE,
[0x58] = KC_BACKSLASH,
[0x59] = KC_ENTER,
[0x5a] = KC_NENTER,
[0x5b] = KC_N4,
[0x5c] = KC_N5,
[0x5d] = KC_N6,
[0x5e] = KC_N0,
[0x5f] = 0,
[0x60] = KC_PAGE_UP,
[0x61] = 0,
[0x62] = KC_NUM_LOCK,
[0x63] = KC_LSHIFT,
[0x64] = KC_Z,
[0x65] = KC_X,
[0x66] = KC_C,
[0x67] = KC_V,
[0x68] = KC_B,
[0x69] = KC_N,
[0x6a] = KC_M,
[0x6b] = KC_COMMA,
[0x6c] = KC_PERIOD,
[0x6d] = KC_SLASH,
[0x6e] = KC_RSHIFT,
[0x6f] = 0,
[0x70] = KC_N1,
[0x71] = KC_N2,
[0x72] = KC_N3,
[0x73] = 0,
[0x74] = 0,
[0x75] = 0,
[0x76] = 0,
[0x77] = KC_CAPS_LOCK,
[0x78] = 0,
[0x79] = KC_SPACE,
[0x7a] = 0,
[0x7b] = KC_PAGE_DOWN,
[0x7c] = 0,
[0x7d] = KC_NPLUS,
[0x7e] = 0,
[0x7f] = 0
};
 
/** @}
*/
/branches/arm/uspace/srv/kbd/ctl/gxe_fb.c
0,0 → 1,229
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_ctl
* @ingroup kbd
* @{
*/
/**
* @file
* @brief GXEmul framebuffer-mode keyboard controller driver.
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <kbd_ctl.h>
#include <gsp.h>
#include <stroke.h>
 
/** Scancode parser */
static gsp_t sp;
 
/** Current parser state */
static int ds;
 
#include <stdio.h>
 
int seq_defs[] = {
/* Not shifted */
 
0, KC_BACKTICK, 0x60, GSP_END,
 
0, KC_1, 0x31, GSP_END,
0, KC_2, 0x32, GSP_END,
0, KC_3, 0x33, GSP_END,
0, KC_4, 0x34, GSP_END,
0, KC_5, 0x35, GSP_END,
0, KC_6, 0x36, GSP_END,
0, KC_7, 0x37, GSP_END,
0, KC_8, 0x38, GSP_END,
0, KC_9, 0x39, GSP_END,
0, KC_0, 0x30, GSP_END,
 
0, KC_MINUS, 0x2d, GSP_END,
0, KC_EQUALS, 0x3d, GSP_END,
0, KC_BACKSPACE, 0x08, GSP_END,
 
0, KC_TAB, 0x09, GSP_END,
 
0, KC_Q, 0x71, GSP_END,
0, KC_W, 0x77, GSP_END,
0, KC_E, 0x65, GSP_END,
0, KC_R, 0x72, GSP_END,
0, KC_T, 0x74, GSP_END,
0, KC_Y, 0x79, GSP_END,
0, KC_U, 0x75, GSP_END,
0, KC_I, 0x69, GSP_END,
0, KC_O, 0x6f, GSP_END,
0, KC_P, 0x70, GSP_END,
 
0, KC_LBRACKET, 0x5b, GSP_END,
0, KC_RBRACKET, 0x5d, GSP_END,
 
0, KC_A, 0x61, GSP_END,
0, KC_S, 0x73, GSP_END,
0, KC_D, 0x64, GSP_END,
0, KC_F, 0x66, GSP_END,
0, KC_G, 0x67, GSP_END,
0, KC_H, 0x68, GSP_END,
0, KC_J, 0x6a, GSP_END,
0, KC_K, 0x6b, GSP_END,
0, KC_L, 0x6c, GSP_END,
 
0, KC_SEMICOLON, 0x3b, GSP_END,
0, KC_QUOTE, 0x27, GSP_END,
0, KC_BACKSLASH, 0x5c, GSP_END,
 
0, KC_Z, 0x7a, GSP_END,
0, KC_X, 0x78, GSP_END,
0, KC_C, 0x63, GSP_END,
0, KC_V, 0x76, GSP_END,
0, KC_B, 0x62, GSP_END,
0, KC_N, 0x6e, GSP_END,
0, KC_M, 0x6d, GSP_END,
 
0, KC_COMMA, 0x2c, GSP_END,
0, KC_PERIOD, 0x2e, GSP_END,
0, KC_SLASH, 0x2f, GSP_END,
 
/* Shifted */
 
KM_SHIFT, KC_BACKTICK, 0x7e, GSP_END,
 
KM_SHIFT, KC_1, 0x21, GSP_END,
KM_SHIFT, KC_2, 0x40, GSP_END,
KM_SHIFT, KC_3, 0x23, GSP_END,
KM_SHIFT, KC_4, 0x24, GSP_END,
KM_SHIFT, KC_5, 0x25, GSP_END,
KM_SHIFT, KC_6, 0x5e, GSP_END,
KM_SHIFT, KC_7, 0x26, GSP_END,
KM_SHIFT, KC_8, 0x2a, GSP_END,
KM_SHIFT, KC_9, 0x28, GSP_END,
KM_SHIFT, KC_0, 0x29, GSP_END,
 
KM_SHIFT, KC_MINUS, 0x5f, GSP_END,
KM_SHIFT, KC_EQUALS, 0x2b, GSP_END,
 
KM_SHIFT, KC_Q, 0x51, GSP_END,
KM_SHIFT, KC_W, 0x57, GSP_END,
KM_SHIFT, KC_E, 0x45, GSP_END,
KM_SHIFT, KC_R, 0x52, GSP_END,
KM_SHIFT, KC_T, 0x54, GSP_END,
KM_SHIFT, KC_Y, 0x59, GSP_END,
KM_SHIFT, KC_U, 0x55, GSP_END,
KM_SHIFT, KC_I, 0x49, GSP_END,
KM_SHIFT, KC_O, 0x4f, GSP_END,
KM_SHIFT, KC_P, 0x50, GSP_END,
 
KM_SHIFT, KC_LBRACKET, 0x7b, GSP_END,
KM_SHIFT, KC_RBRACKET, 0x7d, GSP_END,
 
KM_SHIFT, KC_A, 0x41, GSP_END,
KM_SHIFT, KC_S, 0x53, GSP_END,
KM_SHIFT, KC_D, 0x44, GSP_END,
KM_SHIFT, KC_F, 0x46, GSP_END,
KM_SHIFT, KC_G, 0x47, GSP_END,
KM_SHIFT, KC_H, 0x48, GSP_END,
KM_SHIFT, KC_J, 0x4a, GSP_END,
KM_SHIFT, KC_K, 0x4b, GSP_END,
KM_SHIFT, KC_L, 0x4c, GSP_END,
 
KM_SHIFT, KC_SEMICOLON, 0x3a, GSP_END,
KM_SHIFT, KC_QUOTE, 0x22, GSP_END,
KM_SHIFT, KC_BACKSLASH, 0x7c, GSP_END,
 
KM_SHIFT, KC_Z, 0x5a, GSP_END,
KM_SHIFT, KC_X, 0x58, GSP_END,
KM_SHIFT, KC_C, 0x43, GSP_END,
KM_SHIFT, KC_V, 0x56, GSP_END,
KM_SHIFT, KC_B, 0x42, GSP_END,
KM_SHIFT, KC_N, 0x4e, GSP_END,
KM_SHIFT, KC_M, 0x4d, GSP_END,
 
KM_SHIFT, KC_COMMA, 0x3c, GSP_END,
KM_SHIFT, KC_PERIOD, 0x3e, GSP_END,
KM_SHIFT, KC_SLASH, 0x3f, GSP_END,
 
/* ... */
 
0, KC_SPACE, 0x20, GSP_END,
0, KC_ENTER, 0x0a, GSP_END,
0, KC_ENTER, 0x0d, GSP_END,
 
0, KC_ESCAPE, 0x1b, 0x1b, GSP_END,
 
0, KC_F1, 0x1b, 0x5b, 0x4f, 0x50, GSP_END,
0, KC_F2, 0x1b, 0x5b, 0x4f, 0x51, GSP_END,
0, KC_F3, 0x1b, 0x5b, 0x4f, 0x52, GSP_END,
0, KC_F4, 0x1b, 0x5b, 0x4f, 0x53, GSP_END,
0, KC_F5, 0x1b, 0x5b, 0x31, 0x35, GSP_END,
0, KC_F6, 0x1b, 0x5b, 0x31, 0x37, GSP_END,
0, KC_F7, 0x1b, 0x5b, 0x31, 0x38, GSP_END,
0, KC_F8, 0x1b, 0x5b, 0x31, 0x39, GSP_END,
0, KC_F9, 0x1b, 0x5b, 0x32, 0x38, GSP_END,
0, KC_F10, 0x1b, 0x5b, 0x32, 0x39, GSP_END,
0, KC_F11, 0x1b, 0x5b, 0x32, 0x33, GSP_END,
0, KC_F12, 0x1b, 0x5b, 0x32, 0x34, GSP_END,
 
0, KC_INSERT, 0x1b, 0x5b, 0x32, 0x7e, GSP_END,
0, KC_HOME, 0x1b, 0x5b, 0x48, GSP_END,
0, KC_PAGE_UP, 0x1b, 0x5b, 0x35, 0x7e, GSP_END,
0, KC_DELETE, 0x1b, 0x5b, 0x33, 0x7e, GSP_END,
0, KC_END, 0x1b, 0x5b, 0x46, GSP_END,
0, KC_PAGE_DOWN, 0x1b, 0x5b, 0x36, 0x7e, GSP_END,
 
0, KC_UP, 0x1b, 0x5b, 0x41, GSP_END,
0, KC_LEFT, 0x1b, 0x5b, 0x44, GSP_END,
0, KC_DOWN, 0x1b, 0x5b, 0x42, GSP_END,
0, KC_RIGHT, 0x1b, 0x5b, 0x43, GSP_END,
 
0, 0
};
 
int kbd_ctl_init(void)
{
ds = 0;
 
gsp_init(&sp);
return gsp_insert_defs(&sp, seq_defs);
}
 
void kbd_ctl_parse_scancode(int scancode)
{
unsigned mods, key;
 
ds = gsp_step(&sp, ds, scancode, &mods, &key);
if (key != 0) {
stroke_sim(mods, key);
}
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/port/i8042.c
0,0 → 1,177
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief i8042 port driver.
*/
 
#include <ddi.h>
#include <libarch/ddi.h>
#include <ipc/ipc.h>
#include <async.h>
#include <unistd.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
#include "i8042.h"
 
/* Interesting bits for status register */
#define i8042_OUTPUT_FULL 0x1
#define i8042_INPUT_FULL 0x2
#define i8042_MOUSE_DATA 0x20
 
/* Command constants */
#define i8042_CMD_KBD 0x60
#define i8042_CMD_MOUSE 0xd4
 
/* Keyboard cmd byte */
#define i8042_KBD_IE 0x1
#define i8042_MOUSE_IE 0x2
#define i8042_KBD_DISABLE 0x10
#define i8042_MOUSE_DISABLE 0x20
#define i8042_KBD_TRANSLATE 0x40
 
/* Mouse constants */
#define MOUSE_OUT_INIT 0xf4
#define MOUSE_ACK 0xfa
 
static irq_cmd_t i8042_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = i8042_OUTPUT_FULL,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = NULL, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t i8042_kbd = {
sizeof(i8042_cmds) / sizeof(irq_cmd_t),
i8042_cmds
};
 
static uintptr_t i8042_physical;
static uintptr_t i8042_kernel;
static i8042_t * i8042;
 
static void wait_ready(void) {
while (pio_read_8(&i8042->status) & i8042_INPUT_FULL)
;
}
 
static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
int mouseenabled = 0;
void *vaddr;
 
i8042_physical = sysinfo_value("kbd.address.physical");
i8042_kernel = sysinfo_value("kbd.address.kernel");
if (pio_enable((void *) i8042_physical, sizeof(i8042_t), &vaddr) != 0)
return -1;
i8042 = vaddr;
 
async_set_interrupt_received(i8042_irq_handler);
 
/* Disable kbd, enable mouse */
pio_write_8(&i8042->status, i8042_CMD_KBD);
wait_ready();
pio_write_8(&i8042->status, i8042_CMD_KBD);
wait_ready();
pio_write_8(&i8042->data, i8042_KBD_DISABLE);
wait_ready();
 
/* Flush all current IO */
while (pio_read_8(&i8042->status) & i8042_OUTPUT_FULL)
(void) pio_read_8(&i8042->data);
/* Enable kbd */
i8042_kbd.cmds[0].addr = (void *) &((i8042_t *) i8042_kernel)->status;
i8042_kbd.cmds[3].addr = (void *) &((i8042_t *) i8042_kernel)->data;
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(), 0, &i8042_kbd);
 
int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
if (mouseenabled)
newcontrol |= i8042_MOUSE_IE;
pio_write_8(&i8042->status, i8042_CMD_KBD);
wait_ready();
pio_write_8(&i8042->data, newcontrol);
wait_ready();
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int status = IPC_GET_ARG1(*call);
 
if ((status & i8042_MOUSE_DATA))
return;
 
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
return;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/port/sgcn.c
0,0 → 1,176
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief SGCN (Serengeti Console) keyboard port driver.
*/
 
#include <as.h>
#include <ddi.h>
#include <async.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sysinfo.h>
#include <stdio.h>
#include <thread.h>
#include <bool.h>
 
#define POLL_INTERVAL 10000
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[4];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
/**
* Virtual address mapped to SRAM.
*/
static uintptr_t sram_virt_addr;
 
/**
* SGCN buffer offset within SGCN.
*/
static uintptr_t sram_buffer_offset;
 
/* polling thread */
static void *sgcn_thread_impl(void *arg);
 
static volatile bool polling_disabled = false;
 
/**
* Initializes the SGCN driver.
* Maps the physical memory (SRAM) and creates the polling thread.
*/
int kbd_port_init(void)
{
sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
if (physmem_map((void *) sysinfo_value("sram.address.physical"),
(void *) sram_virt_addr, sysinfo_value("sram.area.size") / PAGE_SIZE,
AS_AREA_READ | AS_AREA_WRITE) != 0) {
printf("SGCN: uspace driver could not map physical memory.");
return -1;
}
sram_buffer_offset = sysinfo_value("sram.buffer.offset");
 
thread_id_t tid;
int rc;
 
rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
if (rc != 0) {
return rc;
}
 
return 0;
}
 
void kbd_port_yield(void)
{
polling_disabled = true;
}
 
void kbd_port_reclaim(void)
{
polling_disabled = false;
}
 
/**
* Handler of the "key pressed" event. Reads codes of all the pressed keys from
* the buffer.
*/
static void sgcn_key_pressed(void)
{
char c;
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
while (*in_rdptr_ptr != *in_wrptr_ptr) {
c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
kbd_push_scancode(c);
}
}
 
/**
* Thread to poll SGCN for keypresses.
*/
static void *sgcn_thread_impl(void *arg)
{
(void) arg;
 
while (1) {
if (polling_disabled == false)
sgcn_key_pressed();
usleep(POLL_INTERVAL);
}
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/gxemul.c
0,0 → 1,95
/*
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @{
* @ingroup kbd
*/
/** @file
* @brief GXEmul keyboard port driver.
*/
 
#include <ipc/ipc.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
 
static irq_cmd_t gxemul_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2,
},
{
.cmd = CMD_ACCEPT
}
};
 
static irq_code_t gxemul_kbd = {
sizeof(gxemul_cmds) / sizeof(irq_cmd_t),
gxemul_cmds
};
 
static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
/** Initializes keyboard handler. */
int kbd_port_init(void)
{
async_set_interrupt_received(gxemul_irq_handler);
gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &gxemul_kbd);
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
/** Process data sent when a key is pressed.
*
* @param keybuffer Buffer of pressed keys.
* @param call IPC call.
*
* @return Always 1.
*/
static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
 
kbd_push_scancode(scan_code);
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/ns16550.c
0,0 → 1,129
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief NS16550 port driver.
*/
 
#include <ipc/ipc.h>
#include <ipc/bus.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <ddi.h>
 
/* NS16550 registers */
#define RBR_REG 0 /** Receiver Buffer Register. */
#define IER_REG 1 /** Interrupt Enable Register. */
#define IIR_REG 2 /** Interrupt Ident Register (read). */
#define FCR_REG 2 /** FIFO control register (write). */
#define LCR_REG 3 /** Line Control register. */
#define MCR_REG 4 /** Modem Control Register. */
#define LSR_REG 5 /** Line Status Register. */
 
#define LSR_DATA_READY 0x01
 
static irq_cmd_t ns16550_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = LSR_DATA_READY,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
irq_code_t ns16550_kbd = {
sizeof(ns16550_cmds) / sizeof(irq_cmd_t),
ns16550_cmds
};
 
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
static uintptr_t ns16550_physical;
static uintptr_t ns16550_kernel;
 
int ns16550_port_init(void)
{
void *vaddr;
 
async_set_interrupt_received(ns16550_irq_handler);
 
ns16550_physical = sysinfo_value("kbd.address.physical");
ns16550_kernel = sysinfo_value("kbd.address.kernel");
ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
sysinfo_value("kbd.inr"), &ns16550_kbd);
return pio_enable((void *) ns16550_physical, 8, &vaddr);
}
 
void ns16550_port_yield(void)
{
}
 
void ns16550_port_reclaim(void)
{
}
 
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
if (cir_service)
async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
IPC_GET_METHOD(*call));
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/port/msim.c
0,0 → 1,87
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Msim keyboard port driver.
*/
 
#include <ipc/ipc.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd_port.h>
#include <kbd.h>
#include <ddi.h>
 
irq_cmd_t msim_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
 
irq_code_t msim_kbd = {
sizeof(msim_cmds) / sizeof(irq_cmd_t),
msim_cmds
};
 
static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int kbd_port_init(void)
{
async_set_interrupt_received(msim_irq_handler);
msim_cmds[0].addr = sysinfo_value("kbd.address.virtual");
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
0, &msim_kbd);
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/sun.c
0,0 → 1,74
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Sun keyboard virtual port driver.
*/
 
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <sysinfo.h>
 
/** Sun keyboard virtual port driver.
*
* This is a virtual port driver which can use
* both ns16550_port_init and z8530_port_init
* according to the information passed from the
* kernel. This is just a temporal hack.
*
*/
int kbd_port_init(void)
{
if (sysinfo_value("kbd.type.z8530")) {
if (z8530_port_init() == 0)
return 0;
}
if (sysinfo_value("kbd.type.ns16550")) {
if (ns16550_port_init() == 0)
return 0;
}
return -1;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/ski.c
0,0 → 1,123
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Ski console keyboard port driver.
*/
 
 
#include <stdlib.h>
#include <unistd.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sys/types.h>
#include <thread.h>
#include <bool.h>
 
#define SKI_GETCHAR 21
 
#define POLL_INTERVAL 10000
 
static void *ski_thread_impl(void *arg);
static int32_t ski_getchar(void);
 
static volatile bool polling_disabled = false;
 
/** Initialize Ski port driver. */
int kbd_port_init(void)
{
thread_id_t tid;
int rc;
 
rc = thread_create(ski_thread_impl, NULL, "kbd_poll", &tid);
if (rc != 0) {
return rc;
}
 
return 0;
}
 
void kbd_port_yield(void)
{
polling_disabled = true;
}
 
void kbd_port_reclaim(void)
{
polling_disabled = false;
}
 
/** Thread to poll Ski for keypresses. */
static void *ski_thread_impl(void *arg)
{
int32_t c;
(void) arg;
 
while (1) {
while (polling_disabled == false) {
c = ski_getchar();
if (c == 0)
break;
kbd_push_scancode(c);
}
 
usleep(POLL_INTERVAL);
}
}
 
/** Ask Ski if a key was pressed.
*
* Use SSC (Simulator System Call) to get character from the debug console.
* This call is non-blocking.
*
* @return ASCII code of pressed key or 0 if no key pressed.
*/
static int32_t ski_getchar(void)
{
uint64_t ch;
asm volatile (
"mov r15 = %1\n"
"break 0x80000;;\n" /* modifies r8 */
"mov %0 = r8;;\n"
 
: "=r" (ch)
: "i" (SKI_GETCHAR)
: "r15", "r8"
);
 
return (int32_t) ch;
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/z8530.c
0,0 → 1,117
/*
* Copyright (c) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
/** @file
* @brief Z8530 keyboard port driver.
*/
 
#include <ipc/ipc.h>
#include <ipc/bus.h>
#include <async.h>
#include <sysinfo.h>
#include <kbd.h>
#include <kbd_port.h>
#include <sun.h>
#include <sys/types.h>
#include <ddi.h>
 
#define CHAN_A_STATUS 4
#define CHAN_A_DATA 6
 
#define RR0_RCA 1
 
static irq_cmd_t z8530_cmds[] = {
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 1
},
{
.cmd = CMD_BTEST,
.value = RR0_RCA,
.srcarg = 1,
.dstarg = 3
},
{
.cmd = CMD_PREDICATE,
.value = 2,
.srcarg = 3
},
{
.cmd = CMD_PIO_READ_8,
.addr = (void *) 0, /* will be patched in run-time */
.dstarg = 2
},
{
.cmd = CMD_ACCEPT
}
};
irq_code_t z8530_kbd = {
sizeof(z8530_cmds) / sizeof(irq_cmd_t),
z8530_cmds
};
 
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
int z8530_port_init(void)
{
async_set_interrupt_received(z8530_irq_handler);
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.kernel") +
CHAN_A_STATUS;
z8530_cmds[3].addr = (void *) sysinfo_value("kbd.address.kernel") +
CHAN_A_DATA;
ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
sysinfo_value("kbd.inr"), &z8530_kbd);
return 0;
}
 
void z8530_port_yield(void)
{
}
 
void z8530_port_reclaim(void)
{
}
 
static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
{
int scan_code = IPC_GET_ARG2(*call);
kbd_push_scancode(scan_code);
if (cir_service)
async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
IPC_GET_METHOD(*call));
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/dummy.c
0,0 → 1,54
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @brief Dummy keyboard port driver.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#include <kbd_port.h>
#include <kbd.h>
 
int kbd_port_init(void)
{
return 0;
}
 
void kbd_port_yield(void)
{
}
 
void kbd_port_reclaim(void)
{
}
 
/** @}
*/
/branches/arm/uspace/srv/kbd/port/i8042.h
0,0 → 1,55
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd_port
* @ingroup kbd
* @{
*/
 
/** @file
* @brief i8042 port driver.
*/
 
#ifndef KBD_PORT_i8042_H_
#define KBD_PORT_i8042_H_
 
#include <libarch/ddi.h>
#include <libarch/types.h>
 
struct i8042 {
ioport8_t data;
uint8_t pad[3];
ioport8_t status;
} __attribute__ ((packed));
typedef struct i8042 i8042_t;
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/genarch/include/kbd.h
File deleted
/branches/arm/uspace/srv/kbd/genarch/include/scanc.h
File deleted
/branches/arm/uspace/srv/kbd/genarch/src/kbd.c
File deleted
/branches/arm/uspace/srv/kbd/genarch/gsp.c
0,0 → 1,289
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/**
* @addtogroup kbdgen generic
* @ingroup kbd
* @{
*/
/** @file
* @brief Generic scancode parser.
*
* The scancode parser is a simple finite state machine. It is described
* using sequences of input symbols (scancodes) and the corresponding output
* value (mods, key pair). When the parser recognizes a sequence,
* it outputs the value and restarts. If a transition is undefined,
* the parser restarts, too.
*
* Apart from precise values, GSP_DEFAULT allows to catch general cases.
* I.e. if we knew that after 0x1b 0x4f there always follow two more
* scancodes, we can define (0x1b, 0x4f, GSP_DEFAULT, GSP_DEFAULT, GSP_END)
* with null output. This will force the parser to read the entire sequence,
* not leaving garbage on the input if it does not recognize the specific
* sequence.
*/
 
#include <gsp.h>
#include <adt/hash_table.h>
#include <stdlib.h>
#include <stdio.h>
 
#define TRANS_TABLE_CHAINS 256
 
/*
* Hash table operations for the transition function.
*/
 
static hash_index_t trans_op_hash(unsigned long key[]);
static int trans_op_compare(unsigned long key[], hash_count_t keys,
link_t *item);
static void trans_op_remove_callback(link_t *item);
 
static hash_table_operations_t trans_ops = {
.hash = trans_op_hash,
.compare = trans_op_compare,
.remove_callback = trans_op_remove_callback
};
 
static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input);
static void trans_insert(gsp_t *p, gsp_trans_t *t);
static gsp_trans_t *trans_new(void);
 
/** Initialise scancode parser. */
void gsp_init(gsp_t *p)
{
p->states = 1;
hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);
}
 
/** Insert a series of definitions into the parser.
*
* @param p The parser.
* @param defs Definition list. Each definition starts with two output values
* (mods, key) and continues with a sequence of input values
* terminated with GSP_END. The definition list is terminated
* with two zeroes (0, 0) for output values.
*/
int gsp_insert_defs(gsp_t *p, const int *defs)
{
unsigned mods, key;
const int *dp;
int rc;
 
dp = defs;
 
while (1) {
/* Read the output values. */
mods = *dp++;
key = *dp++;
if (key == 0) break;
 
/* Insert one sequence. */
rc = gsp_insert_seq(p, dp, mods, key);
if (rc != 0)
return rc;
 
/* Skip to the next definition. */
while (*dp != GSP_END)
++dp;
++dp;
}
 
return 0;
}
 
/** Insert one sequence into the parser.
*
* @param p The parser.
* @param seq Sequence of input values terminated with GSP_END.
* @param mods Corresponsing output value.
* @param key Corresponsing output value.
*/
int gsp_insert_seq(gsp_t *p, const int *seq, unsigned mods, unsigned key)
{
int state;
gsp_trans_t *t;
 
state = 0;
t = NULL;
 
/* Input sequence must be non-empty. */
if (*seq == GSP_END)
return -1;
 
while (*(seq + 1) != GSP_END) {
t = trans_lookup(p, state, *seq);
if (t == NULL) {
/* Create new state. */
t = trans_new();
t->old_state = state;
t->input = *seq;
t->new_state = p->states++;
 
t->out_mods = 0;
t->out_key = 0;
 
trans_insert(p, t);
}
state = t->new_state;
++seq;
}
 
/* Process the last transition. */
t = trans_lookup(p, state, *seq);
if (t != NULL) {
exit(1);
return -1; /* Conflicting definition. */
}
 
t = trans_new();
t->old_state = state;
t->input = *seq;
t->new_state = 0;
 
t->out_mods = mods;
t->out_key = key;
 
trans_insert(p, t);
 
return 0;
}
 
/** Compute one parser step.
*
* Computes the next state and output values for a given state and input.
* This handles everything including restarts and default branches.
*
* @param p The parser.
* @param state Old state.
* @param input Input symbol (scancode).
* @param mods Output value (modifier).
* @param key Output value (key).
* @return New state.
*/
int gsp_step(gsp_t *p, int state, int input, unsigned *mods, unsigned *key)
{
gsp_trans_t *t;
 
t = trans_lookup(p, state, input);
if (t == NULL) {
t = trans_lookup(p, state, GSP_DEFAULT);
}
 
if (t == NULL) {
printf("gsp_step: not found\n");
*mods = NULL;
*key = NULL;
return 0;
}
 
*mods = t->out_mods;
*key = t->out_key;
return t->new_state;
}
 
/** Transition function lookup.
*
* Returns the value of the transition function for the given state
* and input. Note that the transition must be specified precisely,
* to obtain the default branch use input = GSP_DEFAULT.
*
* @param p Parser.
* @param state Current state.
* @param input Input value.
* @return The transition or @c NULL if not defined.
*/
static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input)
{
link_t *item;
unsigned long key[2];
 
key[0] = state;
key[1] = input;
 
item = hash_table_find(&p->trans, key);
if (item == NULL) return NULL;
 
return hash_table_get_instance(item, gsp_trans_t, link);
}
 
/** Define a new transition.
*
* @param p The parser.
* @param t Transition with all fields defined.
*/
static void trans_insert(gsp_t *p, gsp_trans_t *t)
{
unsigned long key[2];
 
key[0] = t->old_state;
key[1] = t->input;
 
hash_table_insert(&p->trans, key, &t->link);
}
 
/** Allocate transition structure. */
static gsp_trans_t *trans_new(void)
{
gsp_trans_t *t;
 
t = malloc(sizeof(gsp_trans_t));
if (t == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
 
return t;
}
 
/*
* Transition function hash table operations.
*/
 
static hash_index_t trans_op_hash(unsigned long key[])
{
return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;
}
 
static int trans_op_compare(unsigned long key[], hash_count_t keys,
link_t *item)
{
gsp_trans_t *t;
 
t = hash_table_get_instance(item, gsp_trans_t, link);
return ((key[0] == (unsigned long) t->old_state)
&& (key[1] == (unsigned long) t->input));
}
 
static void trans_op_remove_callback(link_t *item)
{
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/genarch/stroke.c
0,0 → 1,85
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd
* @{
*/
/**
* @file
* @brief Stroke simulator.
*
* When simulating a keyboard using a serial TTY we need to convert the
* recognized strokes (such as Shift-A) to sequences of key presses and
* releases (such as 'press Shift, press A, release A, release Shift').
*
*/
 
#include <stroke.h>
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
 
/** Correspondence between modifers and the modifier keycodes. */
static unsigned int mods_keys[][2] = {
{ KM_LSHIFT, KC_LSHIFT },
{ 0, 0 }
};
 
/** Simulate keystroke using sequences of key presses and releases. */
void stroke_sim(unsigned mod, unsigned key)
{
int i;
 
/* Simulate modifier presses. */
i = 0;
while (mods_keys[i][0] != 0) {
if (mod & mods_keys[i][0]) {
kbd_push_ev(KEY_PRESS, mods_keys[i][1]);
}
++i;
}
 
/* Simulate key press and release. */
if (key != 0) {
kbd_push_ev(KEY_PRESS, key);
kbd_push_ev(KEY_RELEASE, key);
}
 
/* Simulate modifier releases. */
i = 0;
while (mods_keys[i][0] != 0) {
if (mod & mods_keys[i][0]) {
kbd_push_ev(KEY_RELEASE, mods_keys[i][1]);
}
++i;
}
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/layout/cz.c
0,0 → 1,408
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @{
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <bool.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(console_event_t *ev);
 
enum m_state {
ms_start,
ms_hacek,
ms_carka
};
 
static enum m_state mstate;
 
layout_op_t cz_op = {
layout_reset,
layout_parse_ev
};
 
static wchar_t map_lcase[] = {
[KC_Q] = 'q',
[KC_W] = 'w',
[KC_E] = 'e',
[KC_R] = 'r',
[KC_T] = 't',
[KC_Y] = 'z',
[KC_U] = 'u',
[KC_I] = 'i',
[KC_O] = 'o',
[KC_P] = 'p',
 
[KC_A] = 'a',
[KC_S] = 's',
[KC_D] = 'd',
[KC_F] = 'f',
[KC_G] = 'g',
[KC_H] = 'h',
[KC_J] = 'j',
[KC_K] = 'k',
[KC_L] = 'l',
 
[KC_Z] = 'y',
[KC_X] = 'x',
[KC_C] = 'c',
[KC_V] = 'v',
[KC_B] = 'b',
[KC_N] = 'n',
[KC_M] = 'm',
};
 
static wchar_t map_ucase[] = {
[KC_Q] = 'Q',
[KC_W] = 'W',
[KC_E] = 'E',
[KC_R] = 'R',
[KC_T] = 'T',
[KC_Y] = 'Z',
[KC_U] = 'U',
[KC_I] = 'I',
[KC_O] = 'O',
[KC_P] = 'P',
 
[KC_A] = 'A',
[KC_S] = 'S',
[KC_D] = 'D',
[KC_F] = 'F',
[KC_G] = 'G',
[KC_H] = 'H',
[KC_J] = 'J',
[KC_K] = 'K',
[KC_L] = 'L',
 
[KC_Z] = 'Y',
[KC_X] = 'X',
[KC_C] = 'C',
[KC_V] = 'V',
[KC_B] = 'B',
[KC_N] = 'N',
[KC_M] = 'M',
};
 
static wchar_t map_not_shifted[] = {
[KC_BACKTICK] = ';',
 
[KC_1] = '+',
 
[KC_MINUS] = '=',
 
[KC_RBRACKET] = ')',
 
[KC_QUOTE] = L'§',
 
[KC_COMMA] = ',',
[KC_PERIOD] = '.',
[KC_SLASH] = '-',
};
 
static wchar_t map_shifted[] = {
[KC_1] = '1',
[KC_2] = '2',
[KC_3] = '3',
[KC_4] = '4',
[KC_5] = '5',
[KC_6] = '6',
[KC_7] = '7',
[KC_8] = '8',
[KC_9] = '9',
[KC_0] = '0',
 
[KC_MINUS] = '%',
 
[KC_LBRACKET] = '/',
[KC_RBRACKET] = '(',
 
[KC_SEMICOLON] = '"',
[KC_QUOTE] = '!',
[KC_BACKSLASH] = '\'',
 
[KC_COMMA] = '?',
[KC_PERIOD] = ':',
[KC_SLASH] = '_',
};
 
static wchar_t map_ns_nocaps[] = {
[KC_2] = L'ě',
[KC_3] = L'š',
[KC_4] = L'č',
[KC_5] = L'ř',
[KC_6] = L'ž',
[KC_7] = L'ý',
[KC_8] = L'á',
[KC_9] = L'í',
[KC_0] = L'é',
 
[KC_LBRACKET] = L'ú',
[KC_SEMICOLON] = L'ů'
};
 
static wchar_t map_ns_caps[] = {
[KC_2] = L'Ě',
[KC_3] = L'Š',
[KC_4] = L'Č',
[KC_5] = L'Ř',
[KC_6] = L'Ž',
[KC_7] = L'Ý',
[KC_8] = L'Á',
[KC_9] = L'Í',
[KC_0] = L'É',
 
[KC_LBRACKET] = L'Ú',
[KC_SEMICOLON] = L'Ů'
};
 
static wchar_t map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
[KC_ENTER] = '\n',
[KC_SPACE] = ' ',
 
[KC_NSLASH] = '/',
[KC_NTIMES] = '*',
[KC_NMINUS] = '-',
[KC_NPLUS] = '+',
[KC_NENTER] = '\n'
};
 
static wchar_t map_numeric[] = {
[KC_N7] = '7',
[KC_N8] = '8',
[KC_N9] = '9',
[KC_N4] = '4',
[KC_N5] = '5',
[KC_N6] = '6',
[KC_N1] = '1',
[KC_N2] = '2',
[KC_N3] = '3',
 
[KC_N0] = '0',
[KC_NPERIOD] = '.'
};
 
static wchar_t map_hacek_lcase[] = {
[KC_E] = L'ě',
[KC_R] = L'ř',
[KC_T] = L'ť',
[KC_Y] = L'ž',
[KC_U] = L'ů',
 
[KC_S] = L'š',
[KC_D] = L'ď',
 
[KC_C] = L'č',
[KC_N] = L'ň'
};
 
static wchar_t map_hacek_ucase[] = {
[KC_E] = L'Ě',
[KC_R] = L'Ř',
[KC_T] = L'Ť',
[KC_Y] = L'Ž',
[KC_U] = L'Ů',
 
[KC_S] = L'Š',
[KC_D] = L'Ď',
 
[KC_C] = L'Č',
[KC_N] = L'Ň'
};
 
static wchar_t map_carka_lcase[] = {
[KC_E] = L'é',
[KC_U] = L'ú',
[KC_I] = L'í',
[KC_O] = L'ó',
 
[KC_A] = L'á',
 
[KC_Z] = L'ý',
};
 
static wchar_t map_carka_ucase[] = {
[KC_E] = L'É',
[KC_U] = L'Ú',
[KC_I] = L'Í',
[KC_O] = L'Ó',
 
[KC_A] = L'Á',
 
[KC_Z] = L'Ý',
};
 
static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
{
if (key >= map_length)
return 0;
return map[key];
}
 
static wchar_t parse_ms_hacek(console_event_t *ev)
{
wchar_t c;
 
mstate = ms_start;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
 
return c;
}
 
static wchar_t parse_ms_carka(console_event_t *ev)
{
wchar_t c;
 
mstate = ms_start;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
 
return c;
}
 
static wchar_t parse_ms_start(console_event_t *ev)
{
wchar_t c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
if (ev->key == KC_EQUALS) {
if ((ev->mods & KM_SHIFT) != 0)
mstate = ms_hacek;
else
mstate = ms_carka;
 
return 0;
}
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) == 0) {
if ((ev->mods & KM_CAPS_LOCK) != 0)
c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
else
c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
 
if (c != 0)
return c;
}
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) != 0)
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
else
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_NUM_LOCK) != 0)
c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
else
c = 0;
 
return c;
}
 
static bool key_is_mod(unsigned key)
{
switch (key) {
case KC_LSHIFT:
case KC_RSHIFT:
case KC_LALT:
case KC_RALT:
case KC_LCTRL:
case KC_RCTRL:
return true;
default:
return false;
}
}
 
static void layout_reset(void)
{
mstate = ms_start;
}
 
static wchar_t layout_parse_ev(console_event_t *ev)
{
if (ev->type != KEY_PRESS)
return 0;
if (key_is_mod(ev->key))
return 0;
switch (mstate) {
case ms_start:
return parse_ms_start(ev);
case ms_hacek:
return parse_ms_hacek(ev);
case ms_carka:
return parse_ms_carka(ev);
}
return 0;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/layout/us_qwerty.c
0,0 → 1,244
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd
* @brief US QWERTY leyout.
* @{
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(console_event_t *ev);
 
layout_op_t us_qwerty_op = {
layout_reset,
layout_parse_ev
};
 
static wchar_t map_lcase[] = {
[KC_Q] = 'q',
[KC_W] = 'w',
[KC_E] = 'e',
[KC_R] = 'r',
[KC_T] = 't',
[KC_Y] = 'y',
[KC_U] = 'u',
[KC_I] = 'i',
[KC_O] = 'o',
[KC_P] = 'p',
 
[KC_A] = 'a',
[KC_S] = 's',
[KC_D] = 'd',
[KC_F] = 'f',
[KC_G] = 'g',
[KC_H] = 'h',
[KC_J] = 'j',
[KC_K] = 'k',
[KC_L] = 'l',
 
[KC_Z] = 'z',
[KC_X] = 'x',
[KC_C] = 'c',
[KC_V] = 'v',
[KC_B] = 'b',
[KC_N] = 'n',
[KC_M] = 'm',
};
 
static wchar_t map_ucase[] = {
[KC_Q] = 'Q',
[KC_W] = 'W',
[KC_E] = 'E',
[KC_R] = 'R',
[KC_T] = 'T',
[KC_Y] = 'Y',
[KC_U] = 'U',
[KC_I] = 'I',
[KC_O] = 'O',
[KC_P] = 'P',
 
[KC_A] = 'A',
[KC_S] = 'S',
[KC_D] = 'D',
[KC_F] = 'F',
[KC_G] = 'G',
[KC_H] = 'H',
[KC_J] = 'J',
[KC_K] = 'K',
[KC_L] = 'L',
 
[KC_Z] = 'Z',
[KC_X] = 'X',
[KC_C] = 'C',
[KC_V] = 'V',
[KC_B] = 'B',
[KC_N] = 'N',
[KC_M] = 'M',
};
 
static wchar_t map_not_shifted[] = {
[KC_BACKTICK] = '`',
 
[KC_1] = '1',
[KC_2] = '2',
[KC_3] = '3',
[KC_4] = '4',
[KC_5] = '5',
[KC_6] = '6',
[KC_7] = '7',
[KC_8] = '8',
[KC_9] = '9',
[KC_0] = '0',
 
[KC_MINUS] = '-',
[KC_EQUALS] = '=',
 
[KC_LBRACKET] = '[',
[KC_RBRACKET] = ']',
 
[KC_SEMICOLON] = ';',
[KC_QUOTE] = '\'',
[KC_BACKSLASH] = '\\',
 
[KC_COMMA] = ',',
[KC_PERIOD] = '.',
[KC_SLASH] = '/',
};
 
static wchar_t map_shifted[] = {
[KC_BACKTICK] = '~',
 
[KC_1] = '!',
[KC_2] = '@',
[KC_3] = '#',
[KC_4] = '$',
[KC_5] = '%',
[KC_6] = '^',
[KC_7] = '&',
[KC_8] = '*',
[KC_9] = '(',
[KC_0] = ')',
 
[KC_MINUS] = '_',
[KC_EQUALS] = '+',
 
[KC_LBRACKET] = '{',
[KC_RBRACKET] = '}',
 
[KC_SEMICOLON] = ':',
[KC_QUOTE] = '"',
[KC_BACKSLASH] = '|',
 
[KC_COMMA] = '<',
[KC_PERIOD] = '>',
[KC_SLASH] = '?',
};
 
static wchar_t map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
[KC_ENTER] = '\n',
[KC_SPACE] = ' ',
 
[KC_NSLASH] = '/',
[KC_NTIMES] = '*',
[KC_NMINUS] = '-',
[KC_NPLUS] = '+',
[KC_NENTER] = '\n'
};
 
static wchar_t map_numeric[] = {
[KC_N7] = '7',
[KC_N8] = '8',
[KC_N9] = '9',
[KC_N4] = '4',
[KC_N5] = '5',
[KC_N6] = '6',
[KC_N1] = '1',
[KC_N2] = '2',
[KC_N3] = '3',
 
[KC_N0] = '0',
[KC_NPERIOD] = '.'
};
 
static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
{
if (key >= map_length)
return 0;
return map[key];
}
 
static void layout_reset(void)
{
}
 
static wchar_t layout_parse_ev(console_event_t *ev)
{
wchar_t c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
if (c != 0)
return c;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) != 0)
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
else
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_NUM_LOCK) != 0)
c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
else
c = 0;
 
return c;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/layout/us_dvorak.c
0,0 → 1,250
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbd
* @brief US Dvorak Simplified Keyboard layout.
* @{
*/
 
#include <kbd.h>
#include <io/console.h>
#include <io/keycode.h>
#include <layout.h>
 
static void layout_reset(void);
static wchar_t layout_parse_ev(console_event_t *ev);
 
layout_op_t us_dvorak_op = {
layout_reset,
layout_parse_ev
};
 
static wchar_t map_lcase[] = {
[KC_R] = 'p',
[KC_T] = 'y',
[KC_Y] = 'f',
[KC_U] = 'g',
[KC_I] = 'c',
[KC_O] = 'r',
[KC_P] = 'l',
 
[KC_A] = 'a',
[KC_S] = 'o',
[KC_D] = 'e',
[KC_F] = 'u',
[KC_G] = 'i',
[KC_H] = 'd',
[KC_J] = 'h',
[KC_K] = 't',
[KC_L] = 'n',
 
[KC_SEMICOLON] = 's',
 
[KC_X] = 'q',
[KC_C] = 'j',
[KC_V] = 'k',
[KC_B] = 'x',
[KC_N] = 'b',
[KC_M] = 'm',
 
[KC_COMMA] = 'w',
[KC_PERIOD] = 'v',
[KC_SLASH] = 'z',
};
 
static wchar_t map_ucase[] = {
[KC_R] = 'P',
[KC_T] = 'Y',
[KC_Y] = 'F',
[KC_U] = 'G',
[KC_I] = 'C',
[KC_O] = 'R',
[KC_P] = 'L',
 
[KC_A] = 'A',
[KC_S] = 'O',
[KC_D] = 'E',
[KC_F] = 'U',
[KC_G] = 'I',
[KC_H] = 'D',
[KC_J] = 'H',
[KC_K] = 'T',
[KC_L] = 'N',
 
[KC_SEMICOLON] = 'S',
 
[KC_X] = 'Q',
[KC_C] = 'J',
[KC_V] = 'K',
[KC_B] = 'X',
[KC_N] = 'B',
[KC_M] = 'M',
 
[KC_COMMA] = 'W',
[KC_PERIOD] = 'V',
[KC_SLASH] = 'Z',
};
 
static wchar_t map_not_shifted[] = {
[KC_BACKTICK] = '`',
 
[KC_1] = '1',
[KC_2] = '2',
[KC_3] = '3',
[KC_4] = '4',
[KC_5] = '5',
[KC_6] = '6',
[KC_7] = '7',
[KC_8] = '8',
[KC_9] = '9',
[KC_0] = '0',
 
[KC_MINUS] = '[',
[KC_EQUALS] = ']',
 
[KC_Q] = '\'',
[KC_W] = ',',
[KC_E] = '.',
 
[KC_LBRACKET] = '/',
[KC_RBRACKET] = '=',
 
[KC_QUOTE] = '-',
[KC_BACKSLASH] = '\\',
 
[KC_Z] = ';',
};
 
static wchar_t map_shifted[] = {
[KC_BACKTICK] = '~',
 
[KC_1] = '!',
[KC_2] = '@',
[KC_3] = '#',
[KC_4] = '$',
[KC_5] = '%',
[KC_6] = '^',
[KC_7] = '&',
[KC_8] = '*',
[KC_9] = '(',
[KC_0] = ')',
 
[KC_MINUS] = '{',
[KC_EQUALS] = '}',
 
[KC_Q] = '"',
[KC_W] = '<',
[KC_E] = '>',
 
[KC_LBRACKET] = '?',
[KC_RBRACKET] = '+',
 
[KC_QUOTE] = '_',
[KC_BACKSLASH] = '|',
 
[KC_Z] = ':',
};
 
static wchar_t map_neutral[] = {
[KC_BACKSPACE] = '\b',
[KC_TAB] = '\t',
[KC_ENTER] = '\n',
[KC_SPACE] = ' ',
 
[KC_NSLASH] = '/',
[KC_NTIMES] = '*',
[KC_NMINUS] = '-',
[KC_NPLUS] = '+',
[KC_NENTER] = '\n'
};
 
static wchar_t map_numeric[] = {
[KC_N7] = '7',
[KC_N8] = '8',
[KC_N9] = '9',
[KC_N4] = '4',
[KC_N5] = '5',
[KC_N6] = '6',
[KC_N1] = '1',
[KC_N2] = '2',
[KC_N3] = '3',
 
[KC_N0] = '0',
[KC_NPERIOD] = '.'
};
 
static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
{
if (key >= map_length)
return 0;
return map[key];
}
 
static void layout_reset(void)
{
}
 
static wchar_t layout_parse_ev(console_event_t *ev)
{
wchar_t c;
 
/* Produce no characters when Ctrl or Alt is pressed. */
if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
return 0;
 
c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
if (c != 0)
return c;
 
if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
else
c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_SHIFT) != 0)
c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
else
c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
 
if (c != 0)
return c;
 
if ((ev->mods & KM_NUM_LOCK) != 0)
c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
else
c = 0;
 
return c;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/include/key_buffer.h
File deleted
/branches/arm/uspace/srv/kbd/include/keys.h
File deleted
/branches/arm/uspace/srv/kbd/include/gsp.h
0,0 → 1,84
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen generic
* @brief Generic scancode parser.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_GSP_H_
#define KBD_GSP_H_
 
#include <adt/hash_table.h>
 
enum {
GSP_END = -1, /**< Terminates a sequence. */
GSP_DEFAULT = -2 /**< Wildcard, catches unhandled cases. */
};
 
/** Scancode parser description */
typedef struct {
/** Transition table, (state, input) -> (state, output) */
hash_table_t trans;
 
/** Number of states */
int states;
} gsp_t;
 
/** Scancode parser transition. */
typedef struct {
link_t link; /**< Link to hash table in @c gsp_t */
 
/* Preconditions */
 
int old_state; /**< State before transition */
int input; /**< Input symbol (scancode) */
 
/* Effects */
 
int new_state; /**< State after transition */
 
/* Output emitted during transition */
 
unsigned out_mods; /**< Modifier to emit */
unsigned out_key; /**< Keycode to emit */
} gsp_trans_t;
 
extern void gsp_init(gsp_t *);
extern int gsp_insert_defs(gsp_t *, const int *);
extern int gsp_insert_seq(gsp_t *, const int *, unsigned, unsigned);
extern int gsp_step(gsp_t *, int, int, unsigned *, unsigned *);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/include/layout.h
0,0 → 1,56
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_LAYOUT_H_
#define KBD_LAYOUT_H_
 
#include <sys/types.h>
#include <io/console.h>
 
typedef struct {
void (*reset)(void);
wchar_t (*parse_ev)(console_event_t *);
} layout_op_t;
 
extern layout_op_t us_qwerty_op;
extern layout_op_t us_dvorak_op;
extern layout_op_t cz_op;
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/include/kbd.h
27,10 → 27,10
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
*/
/** @file
*/
 
37,15 → 37,28
#ifndef KBD_KBD_H_
#define KBD_KBD_H_
 
#include <key_buffer.h>
#include <keybuffer.h>
#include <ipc/ipc.h>
 
extern int kbd_arch_init(void);
extern int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call);
extern int mouse_arch_process(int phoneid, ipc_call_t *call);
#define KBD_EVENT 1024
#define KBD_MS_LEFT 1025
#define KBD_MS_RIGHT 1026
#define KBD_MS_MIDDLE 1027
#define KBD_MS_MOVE 1028
 
typedef enum {
KBD_YIELD = IPC_FIRST_USER_METHOD,
KBD_RECLAIM
} kbd_request_t;
 
extern int cir_service;
extern int cir_phone;
 
extern void kbd_push_scancode(int);
extern void kbd_push_ev(int, unsigned int);
 
#endif
 
/**
* @}
*/
 
*/
/branches/arm/uspace/srv/kbd/include/keybuffer.h
0,0 → 1,65
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef __KEYBUFFER_H__
#define __KEYBUFFER_H__
 
#include <sys/types.h>
#include <io/console.h>
#include <bool.h>
 
/** Size of buffer for pressed keys */
#define KEYBUFFER_SIZE 128
 
typedef struct {
console_event_t fifo[KEYBUFFER_SIZE];
unsigned long head;
unsigned long tail;
unsigned long items;
} keybuffer_t;
 
extern void keybuffer_free(keybuffer_t *);
extern void keybuffer_init(keybuffer_t *);
extern size_t keybuffer_available(keybuffer_t *);
extern bool keybuffer_empty(keybuffer_t *);
extern void keybuffer_push(keybuffer_t *, const console_event_t *);
extern bool keybuffer_pop(keybuffer_t *, console_event_t *);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/include/kbd_port.h
0,0 → 1,49
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_PORT_H_
#define KBD_PORT_H_
 
extern int kbd_port_init(void);
extern void kbd_port_yield(void);
extern void kbd_port_reclaim(void);
 
#endif
 
/**
* @}
*/
 
/branches/arm/uspace/srv/kbd/include/sun.h
0,0 → 1,47
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen generic
* @brief Sun keyboard virtual port driver.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_SUN_H_
#define KBD_SUN_H_
 
extern int ns16550_port_init(void);
extern int z8530_port_init(void);
 
#endif
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/include/kbd_ctl.h
0,0 → 1,49
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_CTL_H_
#define KBD_CTL_H_
 
extern void kbd_ctl_parse_scancode(int);
extern int kbd_ctl_init(void);
 
 
#endif
 
/**
* @}
*/
 
/branches/arm/uspace/srv/kbd/include/stroke.h
0,0 → 1,47
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen generic
* @brief Generic scancode parser.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#ifndef KBD_STROKE_H_
#define KBD_STROKE_H_
 
extern void stroke_sim(unsigned, unsigned);
 
#endif
 
/**
* @}
*/
 
/branches/arm/uspace/srv/kbd/generic/key_buffer.c
File deleted
/branches/arm/uspace/srv/kbd/generic/kbd.c
28,57 → 28,139
 
/**
* @addtogroup kbdgen generic
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
*/
/** @file
*/
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <sysinfo.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ipc/ns.h>
#include <async.h>
#include <errno.h>
#include <arch/kbd.h>
#include <adt/fifo.h>
#include <io/console.h>
#include <io/keycode.h>
 
#include <kbd.h>
#include <libadt/fifo.h>
#include <key_buffer.h>
#include <async.h>
#include <keys.h>
#include <keybuffer.h>
#include <kbd_port.h>
#include <kbd_ctl.h>
#include <layout.h>
 
#define NAME "kbd"
 
int cons_connected = 0;
int phone2cons = -1;
keybuffer_t keybuffer;
keybuffer_t keybuffer;
 
static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
/** Currently active modifiers. */
static unsigned mods = KM_NUM_LOCK;
 
/** Currently pressed lock keys. We track these to tackle autorepeat. */
static unsigned lock_keys;
 
int cir_service = 0;
int cir_phone = -1;
 
#define NUM_LAYOUTS 3
 
static layout_op_t *layout[NUM_LAYOUTS] = {
&us_qwerty_op,
&us_dvorak_op,
&cz_op
};
 
static int active_layout = 0;
 
void kbd_push_scancode(int scancode)
{
int chr;
/* printf("scancode: 0x%x\n", scancode);*/
kbd_ctl_parse_scancode(scancode);
}
 
#ifdef MOUSE_ENABLED
if (mouse_arch_process(phone2cons, call))
return;
#endif
kbd_arch_process(&keybuffer, call);
void kbd_push_ev(int type, unsigned int key)
{
console_event_t ev;
unsigned mod_mask;
 
if (cons_connected && phone2cons != -1) {
/*
* recode to ASCII - one interrupt can produce more than one
* code so result is stored in fifo
*/
while (!keybuffer_empty(&keybuffer)) {
if (!keybuffer_pop(&keybuffer, (int *)&chr))
break;
switch (key) {
case KC_LCTRL: mod_mask = KM_LCTRL; break;
case KC_RCTRL: mod_mask = KM_RCTRL; break;
case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
case KC_LALT: mod_mask = KM_LALT; break;
case KC_RALT: mod_mask = KM_RALT; break;
default: mod_mask = 0; break;
}
 
async_msg_1(phone2cons, KBD_PUSHCHAR, chr);
if (mod_mask != 0) {
if (type == KEY_PRESS)
mods = mods | mod_mask;
else
mods = mods & ~mod_mask;
}
 
switch (key) {
case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
default: mod_mask = 0; break;
}
 
if (mod_mask != 0) {
if (type == KEY_PRESS) {
/*
* Only change lock state on transition from released
* to pressed. This prevents autorepeat from messing
* up the lock state.
*/
mods = mods ^ (mod_mask & ~lock_keys);
lock_keys = lock_keys | mod_mask;
} else {
lock_keys = lock_keys & ~mod_mask;
}
}
/*
printf("type: %d\n", type);
printf("mods: 0x%x\n", mods);
printf("keycode: %u\n", key);
*/
if (type == KEY_PRESS && (mods & KM_LCTRL) &&
key == KC_F1) {
active_layout = 0;
layout[active_layout]->reset();
return;
}
 
if (type == KEY_PRESS && (mods & KM_LCTRL) &&
key == KC_F2) {
active_layout = 1;
layout[active_layout]->reset();
return;
}
 
if (type == KEY_PRESS && (mods & KM_LCTRL) &&
key == KC_F3) {
active_layout = 2;
layout[active_layout]->reset();
return;
}
 
ev.type = type;
ev.key = key;
ev.mods = mods;
 
ev.c = layout[active_layout]->parse_ev(&ev);
 
async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
}
 
static void console_connection(ipc_callid_t iid, ipc_call_t *icall)
111,6 → 193,14
phone2cons = IPC_GET_ARG5(call);
retval = 0;
break;
case KBD_YIELD:
kbd_port_yield();
retval = 0;
break;
case KBD_RECLAIM:
kbd_port_reclaim();
retval = 0;
break;
default:
retval = EINVAL;
}
125,16 → 215,35
ipcarg_t phonead;
/* Initialize arch dependent parts */
if (kbd_arch_init())
if (sysinfo_value("kbd.cir.fhc") == 1)
cir_service = SERVICE_FHC;
else if (sysinfo_value("kbd.cir.obio") == 1)
cir_service = SERVICE_OBIO;
if (cir_service) {
while (cir_phone < 0) {
cir_phone = ipc_connect_me_to_blocking(PHONE_NS, cir_service,
0, 0);
}
}
/* Initialize port driver. */
if (kbd_port_init() != 0)
return -1;
 
/* Initialize controller driver. */
if (kbd_ctl_init() != 0)
return -1;
 
/* Initialize (reset) layout. */
layout[active_layout]->reset();
/* Initialize key buffer */
keybuffer_init(&keybuffer);
async_set_client_connection(console_connection);
async_set_interrupt_received(irq_handler);
/* Register service at nameserver */
 
/* Register service at nameserver. */
if (ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, 0, &phonead) != 0)
return -1;
141,7 → 250,7
printf(NAME ": Accepting connections\n");
async_manager();
 
/* Never reached */
/* Not reached. */
return 0;
}
 
/branches/arm/uspace/srv/kbd/generic/keybuffer.c
0,0 → 1,132
/*
* Copyright (c) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup kbdgen
* @brief HelenOS generic uspace keyboard handler.
* @ingroup kbd
* @{
*/
/** @file
*/
 
#include <keybuffer.h>
#include <futex.h>
 
atomic_t keybuffer_futex = FUTEX_INITIALIZER;
 
/** Clear key buffer.
*/
void keybuffer_free(keybuffer_t *keybuffer)
{
futex_down(&keybuffer_futex);
keybuffer->head = 0;
keybuffer->tail = 0;
keybuffer->items = 0;
futex_up(&keybuffer_futex);
}
 
/** Key buffer initialization.
*
*/
void keybuffer_init(keybuffer_t *keybuffer)
{
keybuffer_free(keybuffer);
}
 
/** Get free space in buffer.
*
* This function is useful for processing some scancodes that are translated
* to more than one character.
*
* @return empty buffer space
*
*/
size_t keybuffer_available(keybuffer_t *keybuffer)
{
return KEYBUFFER_SIZE - keybuffer->items;
}
 
/**
*
* @return nonzero, if buffer is not empty.
*
*/
bool keybuffer_empty(keybuffer_t *keybuffer)
{
return (keybuffer->items == 0);
}
 
/** Push key event to key buffer.
*
* If the buffer is full, the event is ignored.
*
* @param keybuffer The keybuffer.
* @param ev The event to push.
*
*/
void keybuffer_push(keybuffer_t *keybuffer, const console_event_t *ev)
{
futex_down(&keybuffer_futex);
if (keybuffer->items < KEYBUFFER_SIZE) {
keybuffer->fifo[keybuffer->tail] = *ev;
keybuffer->tail = (keybuffer->tail + 1) % KEYBUFFER_SIZE;
keybuffer->items++;
}
futex_up(&keybuffer_futex);
}
 
/** Pop event from buffer.
*
* @param edst Pointer to where the event should be saved.
*
* @return True if an event was popped.
*
*/
bool keybuffer_pop(keybuffer_t *keybuffer, console_event_t *edst)
{
futex_down(&keybuffer_futex);
if (keybuffer->items > 0) {
keybuffer->items--;
*edst = (keybuffer->fifo[keybuffer->head]);
keybuffer->head = (keybuffer->head + 1) % KEYBUFFER_SIZE;
futex_up(&keybuffer_futex);
return true;
}
futex_up(&keybuffer_futex);
return false;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/kbd/Makefile
31,11 → 31,11
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
include ../../../Makefile.config
 
CFLAGS += -Iinclude -I../libadt/include
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -Iinclude
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
44,75 → 44,130
OUTPUT = kbd
GENERIC_SOURCES = \
generic/kbd.c \
generic/key_buffer.c
genarch/gsp.c \
genarch/stroke.c \
generic/keybuffer.c
 
ARCH_SOURCES = \
arch/$(ARCH)/src/kbd.c
ARCH_SOURCES =
GENARCH_SOURCES = \
layout/cz.c \
layout/us_qwerty.c \
layout/us_dvorak.c
 
ifeq ($(ARCH), ia32)
ARCH_SOURCES += \
arch/$(ARCH)/src/mouse.c \
arch/$(ARCH)/src/scanc.c
GENARCH_SOURCES = \
genarch/src/kbd.c
CFLAGS += -DMOUSE_ENABLED
ifeq ($(UARCH), amd64)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
ifeq ($(ARCH), amd64)
ARCH_SOURCES += \
arch/$(ARCH)/src/mouse.c \
arch/$(ARCH)/src/scanc.c
GENARCH_SOURCES = \
genarch/src/kbd.c
CFLAGS += -DMOUSE_ENABLED
 
ifeq ($(UARCH), arm32)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
else
GENARCH_SOURCES += \
ctl/stty.c
endif
endif
ifeq ($(ARCH), sparc64)
ARCH_SOURCES += \
arch/$(ARCH)/src/scanc.c
GENARCH_SOURCES = \
genarch/src/kbd.c
 
ifeq ($(UARCH), ia32)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
ifeq ($(ARCH), arm32)
ifeq ($(MACHINE), gxemul_testarm)
ARCH_SOURCES += \
arch/$(ARCH)/src/kbd_gxemul.c
 
ifeq ($(MACHINE), i460GX)
GENARCH_SOURCES += \
port/i8042.c \
ctl/pc.c
endif
ifeq ($(MACHINE), qemu_icp)
GENARCH_SOURCES = \
genarch/src/kbd.c
ARCH_SOURCES += \
arch/$(ARCH)/src/kbd_icp.c \
arch/$(ARCH)/src/scanc.c
 
ifeq ($(MACHINE), ski)
GENARCH_SOURCES += \
port/ski.c \
ctl/stty.c
endif
 
ifeq ($(MACHINE), msim)
GENARCH_SOURCES += \
port/msim.c \
ctl/stty.c
endif
 
ifeq ($(MACHINE), lgxemul)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
else
GENARCH_SOURCES += \
ctl/stty.c
endif
endif
 
ifeq ($(MACHINE), bgxemul)
GENARCH_SOURCES += \
port/gxemul.c
ifeq ($(CONFIG_FB), y)
GENARCH_SOURCES += \
ctl/gxe_fb.c
else
GENARCH_SOURCES += \
ctl/stty.c
endif
endif
 
ifeq ($(UARCH), ppc32)
GENARCH_SOURCES += \
port/dummy.c \
ctl/stty.c
endif
 
ifeq ($(UARCH), sparc64)
ifeq ($(MACHINE),serengeti)
GENARCH_SOURCES += \
port/sgcn.c \
ctl/stty.c
else
GENARCH_SOURCES += \
port/sun.c \
port/z8530.c \
port/ns16550.c \
ctl/sun.c
endif
endif
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
OBJECTS := $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS)
 
.PHONY: all clean depend disasm links
 
all: links $(OUTPUT) $(OUTPUT).disasm
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
links:
ln -sfn ../arch/$(ARCH)/include include/arch
ln -sfn ../genarch/include include/genarch
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend include/arch include/genarch
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(GENERIC_OBJECTS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/vfs/vfs_ops.c
28,11 → 28,11
 
/** @addtogroup fs
* @{
*/
*/
 
/**
* @file vfs_ops.c
* @brief Operations that VFS offers to its clients.
* @file vfs_ops.c
* @brief Operations that VFS offers to its clients.
*/
 
#include "vfs.h"
43,9 → 43,8
#include <stdlib.h>
#include <string.h>
#include <bool.h>
#include <futex.h>
#include <rwlock.h>
#include <libadt/list.h>
#include <fibril_sync.h>
#include <adt/list.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
59,190 → 58,109
* This rwlock prevents the race between a triplet-to-VFS-node resolution and a
* concurrent VFS operation which modifies the file system namespace.
*/
RWLOCK_INITIALIZE(namespace_rwlock);
FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock);
 
futex_t rootfs_futex = FUTEX_INITIALIZER;
vfs_pair_t rootfs = {
.fs_handle = 0,
.dev_handle = 0
};
 
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle,
fs_handle_t fs_handle, char *mp, char *opts)
{
dev_handle_t dev_handle;
vfs_lookup_res_t mp_res;
vfs_lookup_res_t mr_res;
vfs_node_t *mp_node = NULL;
ipc_callid_t callid;
ipc_call_t data;
int rc;
vfs_node_t *mr_node;
fs_index_t rindex;
size_t rsize;
unsigned rlnkcnt;
ipcarg_t rc;
int phone;
size_t size;
 
/*
* We expect the library to do the device-name to device-handle
* translation for us, thus the device handle will arrive as ARG1
* in the request.
*/
dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
 
/*
* For now, don't make use of ARG2 and ARG3, but they can be used to
* carry mount options in the future.
*/
 
/*
* Now, we expect the client to send us data with the name of the file
* system.
*/
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
/*
* Don't receive more than is necessary for storing a full file system
* name.
*/
if (size < 1 || size > FS_NAME_MAXLEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
/* Deliver the file system name. */
char fs_name[FS_NAME_MAXLEN + 1];
(void) ipc_data_write_finalize(callid, fs_name, size);
fs_name[size] = '\0';
aid_t msg;
ipc_call_t answer;
/*
* Wait for IPC_M_PING so that we can return an error if we don't know
* fs_name.
*/
callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_PING) {
ipc_answer_0(callid, ENOTSUP);
ipc_answer_0(rid, ENOTSUP);
return;
}
 
/*
* Check if we know a file system with the same name as is in fs_name.
* This will also give us its file system handle.
*/
fs_handle_t fs_handle = fs_name_to_handle(fs_name, true);
if (!fs_handle) {
ipc_answer_0(callid, ENOENT);
ipc_answer_0(rid, ENOENT);
return;
}
 
/* Acknowledge that we know fs_name. */
ipc_answer_0(callid, EOK);
 
/* Now, we want the client to send us the mount point. */
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
/* Check whether size is reasonable wrt. the mount point. */
if (size < 1 || size > MAX_PATH_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
/* Allocate buffer for the mount point data being received. */
uint8_t *buf;
buf = malloc(size + 1);
if (!buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
/* Deliver the mount point. */
(void) ipc_data_write_finalize(callid, buf, size);
buf[size] = '\0';
 
/* Resolve the path to the mountpoint. */
vfs_lookup_res_t mp_res;
futex_down(&rootfs_futex);
fibril_rwlock_write_lock(&namespace_rwlock);
if (rootfs.fs_handle) {
/* We already have the root FS. */
rwlock_write_lock(&namespace_rwlock);
if ((size == 1) && (buf[0] == '/')) {
if (str_cmp(mp, "/") == 0) {
/* Trying to mount root FS over root FS */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
free(buf);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, EBUSY);
return;
}
rc = vfs_lookup_internal(buf, L_DIRECTORY, &mp_res, NULL);
rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL);
if (rc != EOK) {
/* The lookup failed for some reason. */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
free(buf);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
}
mp_node = vfs_node_get(&mp_res);
if (!mp_node) {
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
free(buf);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, ENOMEM);
return;
}
/*
* Now we hold a reference to mp_node.
* It will be dropped upon the corresponding VFS_UNMOUNT.
* It will be dropped upon the corresponding VFS_IN_UNMOUNT.
* This prevents the mount point from being deleted.
*/
rwlock_write_unlock(&namespace_rwlock);
} else {
/* We still don't have the root file system mounted. */
if ((size == 1) && (buf[0] == '/')) {
vfs_lookup_res_t mr_res;
vfs_node_t *mr_node;
ipcarg_t rindex;
ipcarg_t rsize;
ipcarg_t rlnkcnt;
if (str_cmp(mp, "/") == 0) {
/*
* For this simple, but important case,
* we are almost done.
*/
free(buf);
/* Tell the mountee that it is being mounted. */
phone = vfs_grab_phone(fs_handle);
rc = async_req_1_3(phone, VFS_MOUNTED,
(ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt);
msg = async_send_1(phone, VFS_OUT_MOUNTED,
(ipcarg_t) dev_handle, &answer);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts,
str_size(opts));
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(phone);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
}
async_wait_for(msg, &rc);
vfs_release_phone(phone);
if (rc != EOK) {
futex_up(&rootfs_futex);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
}
 
rindex = (fs_index_t) IPC_GET_ARG1(answer);
rsize = (size_t) IPC_GET_ARG2(answer);
rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
mr_res.triplet.fs_handle = fs_handle;
mr_res.triplet.dev_handle = dev_handle;
mr_res.triplet.index = (fs_index_t) rindex;
mr_res.size = (size_t) rsize;
mr_res.lnkcnt = (unsigned) rlnkcnt;
 
mr_res.triplet.index = rindex;
mr_res.size = rsize;
mr_res.lnkcnt = rlnkcnt;
mr_res.type = VFS_NODE_DIRECTORY;
rootfs.fs_handle = fs_handle;
rootfs.dev_handle = dev_handle;
futex_up(&rootfs_futex);
 
/* Add reference to the mounted root. */
mr_node = vfs_node_get(&mr_res);
assert(mr_node);
 
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
} else {
250,38 → 168,266
* We can't resolve this without the root filesystem
* being mounted first.
*/
futex_up(&rootfs_futex);
free(buf);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, ENOENT);
return;
}
}
futex_up(&rootfs_futex);
free(buf); /* The buffer is not needed anymore. */
/*
* At this point, we have all necessary pieces: file system and device
* handles, and we know the mount point VFS node.
*/
int mountee_phone = vfs_grab_phone(fs_handle);
assert(mountee_phone >= 0);
 
phone = vfs_grab_phone(mp_res.triplet.fs_handle);
rc = async_req_4_0(phone, VFS_MOUNT,
msg = async_send_4(phone, VFS_OUT_MOUNT,
(ipcarg_t) mp_res.triplet.dev_handle,
(ipcarg_t) mp_res.triplet.index,
(ipcarg_t) fs_handle,
(ipcarg_t) dev_handle);
vfs_release_phone(phone);
(ipcarg_t) dev_handle, &answer);
/* send connection */
rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone);
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(mountee_phone);
vfs_release_phone(phone);
/* Mount failed, drop reference to mp_node. */
if (mp_node)
vfs_node_put(mp_node);
ipc_answer_0(rid, rc);
fibril_rwlock_write_unlock(&namespace_rwlock);
return;
}
 
vfs_release_phone(mountee_phone);
/* send the mount options */
rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
if (rc != EOK) {
async_wait_for(msg, NULL);
vfs_release_phone(phone);
/* Mount failed, drop reference to mp_node. */
if (mp_node)
vfs_node_put(mp_node);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
}
async_wait_for(msg, &rc);
vfs_release_phone(phone);
if (rc == EOK) {
rindex = (fs_index_t) IPC_GET_ARG1(answer);
rsize = (size_t) IPC_GET_ARG2(answer);
rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
mr_res.triplet.fs_handle = fs_handle;
mr_res.triplet.dev_handle = dev_handle;
mr_res.triplet.index = rindex;
mr_res.size = rsize;
mr_res.lnkcnt = rlnkcnt;
mr_res.type = VFS_NODE_DIRECTORY;
/* Add reference to the mounted root. */
mr_node = vfs_node_get(&mr_res);
assert(mr_node);
} else {
/* Mount failed, drop reference to mp_node. */
if (mp_node)
vfs_node_put(mp_node);
}
 
ipc_answer_0(rid, rc);
fibril_rwlock_write_unlock(&namespace_rwlock);
}
 
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
{
/*
* We expect the library to do the device-name to device-handle
* translation for us, thus the device handle will arrive as ARG1
* in the request.
*/
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
/*
* Mount flags are passed as ARG2.
*/
unsigned int flags = (unsigned int) IPC_GET_ARG2(*request);
/*
* For now, don't make use of ARG3, but it can be used to
* carry mount options in the future.
*/
/* We want the client to send us the mount point. */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
/* Check whether size is reasonable wrt. the mount point. */
if ((size < 1) || (size > MAX_PATH_LEN)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
/* Allocate buffer for the mount point data being received. */
char *mp = malloc(size + 1);
if (!mp) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
/* Deliver the mount point. */
ipcarg_t retval = ipc_data_write_finalize(callid, mp, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(mp);
return;
}
mp[size] = '\0';
/* Now we expect to receive the mount options. */
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
return;
}
 
/* Check the offered options size. */
if (size < 0 || size > MAX_MNTOPTS_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
return;
}
 
/* Allocate buffer for the mount options. */
char *opts = (char *) malloc(size + 1);
if (!opts) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(mp);
return;
}
 
/* Deliver the mount options. */
retval = ipc_data_write_finalize(callid, opts, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(mp);
free(opts);
return;
}
opts[size] = '\0';
/*
* Now, we expect the client to send us data with the name of the file
* system.
*/
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
free(opts);
return;
}
/*
* Don't receive more than is necessary for storing a full file system
* name.
*/
if ((size < 1) || (size > FS_NAME_MAXLEN)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(mp);
free(opts);
return;
}
/*
* Allocate buffer for file system name.
*/
char *fs_name = (char *) malloc(size + 1);
if (fs_name == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
free(mp);
free(opts);
return;
}
/* Deliver the file system name. */
retval = ipc_data_write_finalize(callid, fs_name, size);
if (retval != EOK) {
ipc_answer_0(rid, retval);
free(mp);
free(opts);
free(fs_name);
return;
}
fs_name[size] = '\0';
 
/*
* Wait for IPC_M_PING so that we can return an error if we don't know
* fs_name.
*/
ipc_call_t data;
callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_PING) {
ipc_answer_0(callid, ENOTSUP);
ipc_answer_0(rid, ENOTSUP);
free(mp);
free(opts);
free(fs_name);
return;
}
 
/*
* Check if we know a file system with the same name as is in fs_name.
* This will also give us its file system handle.
*/
fibril_mutex_lock(&fs_head_lock);
fs_handle_t fs_handle;
recheck:
fs_handle = fs_name_to_handle(fs_name, false);
if (!fs_handle) {
if (flags & IPC_FLAG_BLOCKING) {
fibril_condvar_wait(&fs_head_cv, &fs_head_lock);
goto recheck;
}
fibril_mutex_unlock(&fs_head_lock);
ipc_answer_0(callid, ENOENT);
ipc_answer_0(rid, ENOENT);
free(mp);
free(fs_name);
free(opts);
return;
}
fibril_mutex_unlock(&fs_head_lock);
/* Acknowledge that we know fs_name. */
ipc_answer_0(callid, EOK);
/* Do the mount */
vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts);
free(mp);
free(fs_name);
free(opts);
}
 
void vfs_open(ipc_callid_t rid, ipc_call_t *request)
{
if (!vfs_files_init()) {
288,11 → 434,11
ipc_answer_0(rid, ENOMEM);
return;
}
 
/*
* The POSIX interface is open(path, oflag, mode).
* We can receive oflags and mode along with the VFS_OPEN call; the path
* will need to arrive in another call.
* We can receive oflags and mode along with the VFS_IN_OPEN call;
* the path will need to arrive in another call.
*
* We also receive one private, non-POSIX set of flags called lflag
* used to pass information to vfs_lookup_internal().
301,19 → 447,30
int oflag = IPC_GET_ARG2(*request);
int mode = IPC_GET_ARG3(*request);
size_t len;
 
/*
* Make sure that we are called with exactly one of L_FILE and
* L_DIRECTORY. Make sure that the user does not pass L_OPEN.
*/
if (((lflag & (L_FILE | L_DIRECTORY)) == 0) ||
((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) ||
((lflag & L_OPEN) != 0)) {
ipc_answer_0(rid, EINVAL);
return;
}
if (oflag & O_CREAT)
lflag |= L_CREATE;
if (oflag & O_EXCL)
lflag |= L_EXCLUSIVE;
 
ipc_callid_t callid;
 
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *path = malloc(len + 1);
if (!path) {
ipc_answer_0(callid, ENOMEM);
320,6 → 477,7
ipc_answer_0(rid, ENOMEM);
return;
}
int rc;
if ((rc = ipc_data_write_finalize(callid, path, len))) {
ipc_answer_0(rid, rc);
334,40 → 492,40
* triplet.
*/
if (lflag & L_CREATE)
rwlock_write_lock(&namespace_rwlock);
fibril_rwlock_write_lock(&namespace_rwlock);
else
rwlock_read_lock(&namespace_rwlock);
 
fibril_rwlock_read_lock(&namespace_rwlock);
/* The path is now populated and we can call vfs_lookup_internal(). */
vfs_lookup_res_t lr;
rc = vfs_lookup_internal(path, lflag, &lr, NULL);
if (rc) {
rc = vfs_lookup_internal(path, lflag | L_OPEN, &lr, NULL);
if (rc != EOK) {
if (lflag & L_CREATE)
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
else
rwlock_read_unlock(&namespace_rwlock);
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
free(path);
return;
}
 
/* Path is no longer needed. */
free(path);
 
vfs_node_t *node = vfs_node_get(&lr);
if (lflag & L_CREATE)
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
else
rwlock_read_unlock(&namespace_rwlock);
 
fibril_rwlock_read_unlock(&namespace_rwlock);
/* Truncate the file if requested and if necessary. */
if (oflag & O_TRUNC) {
rwlock_write_lock(&node->contents_rwlock);
fibril_rwlock_write_lock(&node->contents_rwlock);
if (node->size) {
rc = vfs_truncate_internal(node->fs_handle,
node->dev_handle, node->index, 0);
if (rc) {
rwlock_write_unlock(&node->contents_rwlock);
fibril_rwlock_write_unlock(&node->contents_rwlock);
vfs_node_put(node);
ipc_answer_0(rid, rc);
return;
374,9 → 532,9
}
node->size = 0;
}
rwlock_write_unlock(&node->contents_rwlock);
fibril_rwlock_write_unlock(&node->contents_rwlock);
}
 
/*
* Get ourselves a file descriptor and the corresponding vfs_file_t
* structure.
389,30 → 547,173
}
vfs_file_t *file = vfs_file_get(fd);
file->node = node;
if (oflag & O_APPEND)
if (oflag & O_APPEND)
file->append = true;
/*
* The following increase in reference count is for the fact that the
* file is being opened and that a file structure is pointing to it.
* It is necessary so that the file will not disappear when
* vfs_node_put() is called. The reference will be dropped by the
* respective VFS_IN_CLOSE.
*/
vfs_node_addref(node);
vfs_node_put(node);
/* Success! Return the new file descriptor to the client. */
ipc_answer_1(rid, EOK, fd);
}
 
void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
{
// FIXME: check for sanity of the supplied fs, dev and index
if (!vfs_files_init()) {
ipc_answer_0(rid, ENOMEM);
return;
}
/*
* The interface is open_node(fs, dev, index, oflag).
*/
vfs_lookup_res_t lr;
lr.triplet.fs_handle = IPC_GET_ARG1(*request);
lr.triplet.dev_handle = IPC_GET_ARG2(*request);
lr.triplet.index = IPC_GET_ARG3(*request);
int oflag = IPC_GET_ARG4(*request);
fibril_rwlock_read_lock(&namespace_rwlock);
int rc = vfs_open_node_internal(&lr);
if (rc != EOK) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
}
vfs_node_t *node = vfs_node_get(&lr);
fibril_rwlock_read_unlock(&namespace_rwlock);
/* Truncate the file if requested and if necessary. */
if (oflag & O_TRUNC) {
fibril_rwlock_write_lock(&node->contents_rwlock);
if (node->size) {
rc = vfs_truncate_internal(node->fs_handle,
node->dev_handle, node->index, 0);
if (rc) {
fibril_rwlock_write_unlock(&node->contents_rwlock);
vfs_node_put(node);
ipc_answer_0(rid, rc);
return;
}
node->size = 0;
}
fibril_rwlock_write_unlock(&node->contents_rwlock);
}
/*
* Get ourselves a file descriptor and the corresponding vfs_file_t
* structure.
*/
int fd = vfs_fd_alloc();
if (fd < 0) {
vfs_node_put(node);
ipc_answer_0(rid, fd);
return;
}
vfs_file_t *file = vfs_file_get(fd);
file->node = node;
if (oflag & O_APPEND)
file->append = true;
/*
* The following increase in reference count is for the fact that the
* file is being opened and that a file structure is pointing to it.
* It is necessary so that the file will not disappear when
* vfs_node_put() is called. The reference will be dropped by the
* respective VFS_CLOSE.
* respective VFS_IN_CLOSE.
*/
vfs_node_addref(node);
vfs_node_put(node);
 
/* Success! Return the new file descriptor to the client. */
ipc_answer_1(rid, EOK, fd);
}
 
void vfs_close(ipc_callid_t rid, ipc_call_t *request)
void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
int rc = vfs_fd_free(fd);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
/*
* Lock the open file structure so that no other thread can manipulate
* the same open file at a time.
*/
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_OUT_SYMC request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, VFS_OUT_SYNC, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
vfs_release_phone(fs_phone);
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, rc);
}
 
void vfs_close(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
/*
* Lock the open file structure so that no other thread can manipulate
* the same open file at a time.
*/
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_OUT_CLOSE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
 
vfs_release_phone(fs_phone);
fibril_mutex_unlock(&file->lock);
int retval = IPC_GET_ARG1(answer);
if (retval != EOK)
ipc_answer_0(rid, retval);
retval = vfs_fd_free(fd);
ipc_answer_0(rid, retval);
}
 
static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
{
 
455,16 → 756,25
* Lock the open file structure so that no other thread can manipulate
* the same open file at a time.
*/
futex_down(&file->lock);
fibril_mutex_lock(&file->lock);
 
/*
* Lock the file's node so that no other client can read/write to it at
* the same time.
*/
if (read)
rwlock_read_lock(&file->node->contents_rwlock);
fibril_rwlock_read_lock(&file->node->contents_rwlock);
else
rwlock_write_lock(&file->node->contents_rwlock);
fibril_rwlock_write_lock(&file->node->contents_rwlock);
 
if (file->node->type == VFS_NODE_DIRECTORY) {
/*
* Make sure that no one is modifying the namespace
* while we are in readdir().
*/
assert(read);
fibril_rwlock_read_lock(&namespace_rwlock);
}
int fs_phone = vfs_grab_phone(file->node->fs_handle);
473,7 → 783,7
ipc_call_t answer;
if (!read && file->append)
file->pos = file->node->size;
msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE,
file->node->dev_handle, file->node->index, file->pos, &answer);
/*
483,28 → 793,32
* don't have to bother.
*/
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
vfs_release_phone(fs_phone);
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
size_t bytes = IPC_GET_ARG1(answer);
 
if (file->node->type == VFS_NODE_DIRECTORY)
fibril_rwlock_read_unlock(&namespace_rwlock);
/* Unlock the VFS node. */
if (read)
rwlock_read_unlock(&file->node->contents_rwlock);
fibril_rwlock_read_unlock(&file->node->contents_rwlock);
else {
/* Update the cached version of node's size. */
if (rc == EOK)
file->node->size = IPC_GET_ARG2(answer);
rwlock_write_unlock(&file->node->contents_rwlock);
fibril_rwlock_write_unlock(&file->node->contents_rwlock);
}
/* Update the position pointer and unlock the open file. */
if (rc == EOK)
file->pos += bytes;
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
/*
* FS server's reply is the final result of the whole operation we
538,40 → 852,40
}
 
off_t newpos;
futex_down(&file->lock);
fibril_mutex_lock(&file->lock);
if (whence == SEEK_SET) {
file->pos = off;
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_1(rid, EOK, off);
return;
}
if (whence == SEEK_CUR) {
if (file->pos + off < file->pos) {
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, EOVERFLOW);
return;
}
file->pos += off;
newpos = file->pos;
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_1(rid, EOK, newpos);
return;
}
if (whence == SEEK_END) {
rwlock_read_lock(&file->node->contents_rwlock);
fibril_rwlock_read_lock(&file->node->contents_rwlock);
size_t size = file->node->size;
rwlock_read_unlock(&file->node->contents_rwlock);
fibril_rwlock_read_unlock(&file->node->contents_rwlock);
if (size + off < size) {
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, EOVERFLOW);
return;
}
newpos = size + off;
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_1(rid, EOK, newpos);
return;
}
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, EINVAL);
}
 
583,7 → 897,7
int fs_phone;
fs_phone = vfs_grab_phone(fs_handle);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle,
rc = async_req_3_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t)dev_handle,
(ipcarg_t)index, (ipcarg_t)size);
vfs_release_phone(fs_phone);
return (int)rc;
600,19 → 914,119
ipc_answer_0(rid, ENOENT);
return;
}
futex_down(&file->lock);
fibril_mutex_lock(&file->lock);
 
rwlock_write_lock(&file->node->contents_rwlock);
fibril_rwlock_write_lock(&file->node->contents_rwlock);
rc = vfs_truncate_internal(file->node->fs_handle,
file->node->dev_handle, file->node->index, size);
if (rc == EOK)
file->node->size = size;
rwlock_write_unlock(&file->node->contents_rwlock);
fibril_rwlock_write_unlock(&file->node->contents_rwlock);
 
futex_up(&file->lock);
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, (ipcarg_t)rc);
}
 
void vfs_fstat(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
size_t size = IPC_GET_ARG2(*request);
ipcarg_t rc;
 
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
 
ipc_callid_t callid;
if (!ipc_data_read_receive(&callid, NULL)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
fibril_mutex_lock(&file->lock);
 
int fs_phone = vfs_grab_phone(file->node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle,
file->node->index, true, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
vfs_release_phone(fs_phone);
 
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, rc);
}
 
void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
size_t len;
ipc_callid_t callid;
 
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *path = malloc(len + 1);
if (!path) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
int rc;
if ((rc = ipc_data_write_finalize(callid, path, len))) {
ipc_answer_0(rid, rc);
free(path);
return;
}
path[len] = '\0';
 
if (!ipc_data_read_receive(&callid, NULL)) {
free(path);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
vfs_lookup_res_t lr;
fibril_rwlock_read_lock(&namespace_rwlock);
rc = vfs_lookup_internal(path, L_NONE, &lr, NULL);
free(path);
if (rc != EOK) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(callid, rc);
ipc_answer_0(rid, rc);
return;
}
vfs_node_t *node = vfs_node_get(&lr);
if (!node) {
fibril_rwlock_read_unlock(&namespace_rwlock);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
fibril_rwlock_read_unlock(&namespace_rwlock);
 
int fs_phone = vfs_grab_phone(node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, node->dev_handle,
node->index, false, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
ipcarg_t rv;
async_wait_for(msg, &rv);
vfs_release_phone(fs_phone);
 
ipc_answer_0(rid, rv);
 
vfs_node_put(node);
}
 
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
{
int mode = IPC_GET_ARG1(*request);
639,10 → 1053,10
}
path[len] = '\0';
rwlock_write_lock(&namespace_rwlock);
fibril_rwlock_write_lock(&namespace_rwlock);
int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
rc = vfs_lookup_internal(path, lflag, NULL, NULL);
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
free(path);
ipc_answer_0(rid, rc);
}
673,13 → 1087,13
}
path[len] = '\0';
rwlock_write_lock(&namespace_rwlock);
fibril_rwlock_write_lock(&namespace_rwlock);
lflag &= L_DIRECTORY; /* sanitize lflag */
vfs_lookup_res_t lr;
rc = vfs_lookup_internal(path, lflag | L_UNLINK, &lr, NULL);
free(path);
if (rc != EOK) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
return;
}
687,13 → 1101,13
/*
* The name has already been unlinked by vfs_lookup_internal().
* We have to get and put the VFS node to ensure that it is
* VFS_DESTROY'ed after the last reference to it is dropped.
* VFS_OUT_DESTROY'ed after the last reference to it is dropped.
*/
vfs_node_t *node = vfs_node_get(&lr);
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
node->lnkcnt--;
futex_up(&nodes_futex);
rwlock_write_unlock(&namespace_rwlock);
fibril_mutex_unlock(&nodes_mutex);
fibril_rwlock_write_unlock(&namespace_rwlock);
vfs_node_put(node);
ipc_answer_0(rid, EOK);
}
700,37 → 1114,37
 
void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
{
size_t len;
size_t olen, nlen;
ipc_callid_t callid;
int rc;
 
/* Retrieve the old path. */
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &olen)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
char *old = malloc(len + 1);
char *old = malloc(olen + 1);
if (!old) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
if ((rc = ipc_data_write_finalize(callid, old, len))) {
if ((rc = ipc_data_write_finalize(callid, old, olen))) {
ipc_answer_0(rid, rc);
free(old);
return;
}
old[len] = '\0';
old[olen] = '\0';
/* Retrieve the new path. */
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &nlen)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
free(old);
return;
}
char *new = malloc(len + 1);
char *new = malloc(nlen + 1);
if (!new) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
737,16 → 1151,16
free(old);
return;
}
if ((rc = ipc_data_write_finalize(callid, new, len))) {
if ((rc = ipc_data_write_finalize(callid, new, nlen))) {
ipc_answer_0(rid, rc);
free(old);
free(new);
return;
}
new[len] = '\0';
new[nlen] = '\0';
 
char *oldc = canonify(old, &len);
char *newc = canonify(new, NULL);
char *oldc = canonify(old, &olen);
char *newc = canonify(new, &nlen);
if (!oldc || !newc) {
ipc_answer_0(rid, EINVAL);
free(old);
753,8 → 1167,18
free(new);
return;
}
if (!strncmp(newc, oldc, len)) {
/* oldc is a prefix of newc */
oldc[olen] = '\0';
newc[nlen] = '\0';
if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
((newc[str_length(oldc)] == '/') ||
(str_length(oldc) == 1) ||
(str_length(oldc) == str_length(newc)))) {
/*
* oldc is a prefix of newc and either
* - newc continues with a / where oldc ends, or
* - oldc was / itself, or
* - oldc and newc are equal.
*/
ipc_answer_0(rid, EINVAL);
free(old);
free(new);
764,11 → 1188,11
vfs_lookup_res_t old_lr;
vfs_lookup_res_t new_lr;
vfs_lookup_res_t new_par_lr;
rwlock_write_lock(&namespace_rwlock);
fibril_rwlock_write_lock(&namespace_rwlock);
/* Lookup the node belonging to the old file name. */
rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
if (rc != EOK) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
free(old);
free(new);
776,16 → 1200,31
}
vfs_node_t *old_node = vfs_node_get(&old_lr);
if (!old_node) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, ENOMEM);
free(old);
free(new);
return;
}
/* Determine the path to the parent of the node with the new name. */
char *parentc = str_dup(newc);
if (!parentc) {
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
free(old);
free(new);
return;
}
char *lastsl = str_rchr(parentc + 1, '/');
if (lastsl)
*lastsl = '\0';
else
parentc[1] = '\0';
/* Lookup parent of the new file name. */
rc = vfs_lookup_internal(newc, L_PARENT, &new_par_lr, NULL);
rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
free(parentc); /* not needed anymore */
if (rc != EOK) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, rc);
free(old);
free(new);
794,7 → 1233,7
/* Check whether linking to the same file system instance. */
if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
(old_node->dev_handle != new_par_lr.triplet.dev_handle)) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, EXDEV); /* different file systems */
free(old);
free(new);
810,18 → 1249,18
case EOK:
new_node = vfs_node_get(&new_lr);
if (!new_node) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, ENOMEM);
free(old);
free(new);
return;
}
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
new_node->lnkcnt--;
futex_up(&nodes_futex);
fibril_mutex_unlock(&nodes_mutex);
break;
default:
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
ipc_answer_0(rid, ENOTEMPTY);
free(old);
free(new);
830,7 → 1269,7
/* Create the new link for the new name. */
rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
if (rc != EOK) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
if (new_node)
vfs_node_put(new_node);
ipc_answer_0(rid, rc);
838,13 → 1277,13
free(new);
return;
}
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
old_node->lnkcnt++;
futex_up(&nodes_futex);
fibril_mutex_unlock(&nodes_mutex);
/* Destroy the link for the old name. */
rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
if (rc != EOK) {
rwlock_write_unlock(&namespace_rwlock);
fibril_rwlock_write_unlock(&namespace_rwlock);
vfs_node_put(old_node);
if (new_node)
vfs_node_put(new_node);
853,10 → 1292,10
free(new);
return;
}
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
old_node->lnkcnt--;
futex_up(&nodes_futex);
rwlock_write_unlock(&namespace_rwlock);
fibril_mutex_unlock(&nodes_mutex);
fibril_rwlock_write_unlock(&namespace_rwlock);
vfs_node_put(old_node);
if (new_node)
vfs_node_put(new_node);
867,4 → 1306,4
 
/**
* @}
*/
*/
/branches/arm/uspace/srv/vfs/vfs.c
28,11 → 28,11
 
/** @addtogroup fs
* @{
*/
*/
 
/**
* @file vfs.c
* @brief VFS service for HelenOS.
* @file vfs.c
* @brief VFS service for HelenOS.
*/
 
#include <ipc/ipc.h>
43,17 → 43,14
#include <bool.h>
#include <string.h>
#include <as.h>
#include <libadt/list.h>
#include <atomic.h>
#include "vfs.h"
 
#define NAME "vfs"
 
#define dprintf(...) printf(__VA_ARGS__)
 
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall)
{
bool keep_on_going = 1;
bool keep_on_going = true;
 
/*
* The connection was opened via the IPC_CONNECT_ME_TO call.
60,7 → 57,7
* This call needs to be answered.
*/
ipc_answer_0(iid, EOK);
 
/*
* Here we enter the main connection fibril loop.
* The logic behind this loop and the protocol is that we'd like to keep
72,71 → 69,76
* connection later.
*/
while (keep_on_going) {
ipc_callid_t callid;
ipc_call_t call;
 
callid = async_get_call(&call);
 
ipc_callid_t callid = async_get_call(&call);
fs_handle_t fs_handle;
int phone;
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
keep_on_going = false;
break;
case VFS_REGISTER:
case VFS_IN_REGISTER:
vfs_register(callid, &call);
keep_on_going = false;
break;
case VFS_MOUNT:
case VFS_IN_MOUNT:
vfs_mount(callid, &call);
break;
case VFS_OPEN:
case VFS_IN_OPEN:
vfs_open(callid, &call);
break;
case VFS_CLOSE:
case VFS_IN_OPEN_NODE:
vfs_open_node(callid, &call);
break;
case VFS_IN_CLOSE:
vfs_close(callid, &call);
break;
case VFS_READ:
case VFS_IN_READ:
vfs_read(callid, &call);
break;
case VFS_WRITE:
case VFS_IN_WRITE:
vfs_write(callid, &call);
break;
case VFS_SEEK:
case VFS_IN_SEEK:
vfs_seek(callid, &call);
break;
case VFS_TRUNCATE:
case VFS_IN_TRUNCATE:
vfs_truncate(callid, &call);
break;
case VFS_MKDIR:
case VFS_IN_FSTAT:
vfs_fstat(callid, &call);
break;
case VFS_IN_STAT:
vfs_stat(callid, &call);
break;
case VFS_IN_MKDIR:
vfs_mkdir(callid, &call);
break;
case VFS_UNLINK:
case VFS_IN_UNLINK:
vfs_unlink(callid, &call);
break;
case VFS_RENAME:
case VFS_IN_RENAME:
vfs_rename(callid, &call);
break;
case VFS_IN_SYNC:
vfs_sync(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
}
}
 
/* TODO: cleanup after the client */
}
 
int main(int argc, char **argv)
{
ipcarg_t phonead;
 
printf(NAME ": HelenOS VFS server\n");
 
/*
* Initialize the list of registered file systems.
*/
list_initialize(&fs_head);
 
/*
* Initialize VFS node hash table.
*/
if (!vfs_nodes_init()) {
143,16 → 145,16
printf(NAME ": Failed to initialize VFS node hash table\n");
return ENOMEM;
}
 
/*
* Allocate and initialize the Path Lookup Buffer.
*/
list_initialize(&plb_head);
plb = as_get_mappable_page(PLB_SIZE);
if (!plb) {
printf(NAME ": Cannot allocate a mappable piece of address space\n");
return ENOMEM;
}
if (as_area_create(plb, PLB_SIZE, AS_AREA_READ | AS_AREA_WRITE |
AS_AREA_CACHEABLE) != plb) {
printf(NAME ": Cannot create address space area\n");
161,7 → 163,7
memset(plb, 0, PLB_SIZE);
/*
* Set a connectio handling function/fibril.
* Set a connection handling function/fibril.
*/
async_set_client_connection(vfs_connection);
 
168,8 → 170,9
/*
* Register at the naming service.
*/
ipcarg_t phonead;
ipc_connect_to_me(PHONE_NS, SERVICE_VFS, 0, 0, &phonead);
 
/*
* Start accepting connections.
*/
180,4 → 183,4
 
/**
* @}
*/
*/
/branches/arm/uspace/srv/vfs/vfs.h
28,88 → 28,25
 
/** @addtogroup fs
* @{
*/
*/
 
#ifndef VFS_VFS_H_
#define VFS_VFS_H_
 
#include <ipc/ipc.h>
#include <libadt/list.h>
#include <futex.h>
#include <rwlock.h>
#include <adt/list.h>
#include <fibril_sync.h>
#include <sys/types.h>
#include <devmap.h>
#include <bool.h>
#include <ipc/vfs.h>
 
// FIXME: according to CONFIG_DEBUG
// #define dprintf(...) printf(__VA_ARGS__)
// #define dprintf(...) printf(__VA_ARGS__)
 
#define dprintf(...)
 
#define VFS_FIRST IPC_FIRST_USER_METHOD
 
#define IPC_METHOD_TO_VFS_OP(m) ((m) - VFS_FIRST)
 
/* Basic types. */
typedef int16_t fs_handle_t;
typedef int16_t dev_handle_t;
typedef uint32_t fs_index_t;
 
typedef enum {
VFS_READ = VFS_FIRST,
VFS_WRITE,
VFS_TRUNCATE,
VFS_MOUNT,
VFS_UNMOUNT,
VFS_LAST_CMN, /* keep this the last member of this enum */
} vfs_request_cmn_t;
 
typedef enum {
VFS_LOOKUP = VFS_LAST_CMN,
VFS_MOUNTED,
VFS_DESTROY,
VFS_LAST_CLNT, /* keep this the last member of this enum */
} vfs_request_clnt_t;
 
typedef enum {
VFS_REGISTER = VFS_LAST_CMN,
VFS_OPEN,
VFS_CLOSE,
VFS_SEEK,
VFS_MKDIR,
VFS_UNLINK,
VFS_RENAME,
VFS_LAST_SRV, /* keep this the last member of this enum */
} vfs_request_srv_t;
 
 
/**
* An instance of this structure is associated with a particular FS operation.
* It tells VFS if the FS supports the operation or maybe if a default one
* should be used.
*/
typedef enum {
VFS_OP_NULL = 0,
VFS_OP_DEFAULT,
VFS_OP_DEFINED
} vfs_op_t;
 
#define FS_NAME_MAXLEN 20
 
/**
* A structure like this is passed to VFS by each individual FS upon its
* registration. It assosiates a human-readable identifier with each
* registered FS. More importantly, through this structure, the FS announces
* what operations it supports.
*/
typedef struct {
/** Unique identifier of the fs. */
char name[FS_NAME_MAXLEN + 1];
/** Operations. */
vfs_op_t ops[VFS_LAST_CLNT - VFS_FIRST];
} vfs_info_t;
 
/**
* A structure like this will be allocated for each registered file system.
*/
typedef struct {
116,7 → 53,7
link_t fs_link;
vfs_info_t vfs_info;
fs_handle_t fs_handle;
futex_t phone_futex; /**< Phone serializing futex. */
fibril_mutex_t phone_lock;
ipcarg_t phone;
} fs_info_t;
 
123,8 → 60,8
/**
* VFS_PAIR uniquely represents a file system instance.
*/
#define VFS_PAIR \
fs_handle_t fs_handle; \
#define VFS_PAIR \
fs_handle_t fs_handle; \
dev_handle_t dev_handle;
 
/**
134,8 → 71,8
* @note fs_handle, dev_handle and index are meant to be returned in one
* IPC reply.
*/
#define VFS_TRIPLET \
VFS_PAIR; \
#define VFS_TRIPLET \
VFS_PAIR; \
fs_index_t index;
 
typedef struct {
146,52 → 83,15
VFS_TRIPLET;
} vfs_triplet_t;
 
/*
* Lookup flags.
*/
/**
* No lookup flags used.
*/
#define L_NONE 0
/**
* Lookup will succeed only if the object is a regular file. If L_CREATE is
* specified, an empty file will be created. This flag is mutually exclusive
* with L_DIRECTORY.
*/
#define L_FILE 1
/**
* Lookup wil succeed only if the object is a directory. If L_CREATE is
* specified, an empty directory will be created. This flag is mutually
* exclusive with L_FILE.
*/
#define L_DIRECTORY 2
/**
* When used with L_CREATE, L_EXCLUSIVE will cause the lookup to fail if the
* object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
*/
#define L_EXCLUSIVE 4
/**
* L_CREATE is used for creating both regular files and directories.
*/
#define L_CREATE 8
/**
* L_LINK is used for linking to an already existing nodes.
*/
#define L_LINK 16
/**
* L_UNLINK is used to remove leaves from the file system namespace. This flag
* cannot be passed directly by the client, but will be set by VFS during
* VFS_UNLINK.
*/
#define L_UNLINK 32
/**
* L_PARENT performs a lookup but returns the triplet of the parent node.
* This flag may not be combined with any other lookup flag.
*/
#define L_PARENT 64
typedef enum vfs_node_type {
VFS_NODE_UNKNOWN,
VFS_NODE_FILE,
VFS_NODE_DIRECTORY,
} vfs_node_type_t;
 
typedef struct {
vfs_triplet_t triplet;
vfs_node_type_t type;
size_t size;
unsigned lnkcnt;
} vfs_lookup_res_t;
213,12 → 113,15
unsigned lnkcnt;
 
link_t nh_link; /**< Node hash-table link. */
 
vfs_node_type_t type; /**< Partial info about the node type. */
 
size_t size; /**< Cached size if the node is a file. */
 
/**
* Holding this rwlock prevents modifications of the node's contents.
*/
rwlock_t contents_rwlock;
fibril_rwlock_t contents_rwlock;
} vfs_node_t;
 
/**
227,7 → 130,7
*/
typedef struct {
/** Serializes access to this open file. */
futex_t lock;
fibril_mutex_t lock;
 
vfs_node_t *node;
241,16 → 144,14
off_t pos;
} vfs_file_t;
 
extern futex_t nodes_futex;
extern fibril_mutex_t nodes_mutex;
 
extern fibril_condvar_t fs_head_cv;
extern fibril_mutex_t fs_head_lock;
extern link_t fs_head; /**< List of registered file systems. */
 
extern vfs_pair_t rootfs; /**< Root file system. */
 
#define MAX_PATH_LEN (64 * 1024)
 
#define PLB_SIZE (2 * MAX_PATH_LEN)
 
/** Each instance of this type describes one path lookup in progress. */
typedef struct {
link_t plb_link; /**< Active PLB entries list link. */
258,12 → 159,14
size_t len; /**< Number of characters in this PLB entry. */
} plb_entry_t;
 
extern futex_t plb_futex; /**< Futex protecting plb and plb_head. */
extern fibril_mutex_t plb_mutex;/**< Mutex protecting plb and plb_head. */
extern uint8_t *plb; /**< Path Lookup Buffer */
extern link_t plb_head; /**< List of active PLB entries. */
 
#define MAX_MNTOPTS_LEN 256
 
/** Holding this rwlock prevents changes in file system namespace. */
extern rwlock_t namespace_rwlock;
extern fibril_rwlock_t namespace_rwlock;
 
extern int vfs_grab_phone(fs_handle_t);
extern void vfs_release_phone(int);
270,8 → 173,9
 
extern fs_handle_t fs_name_to_handle(char *, bool);
 
extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, vfs_pair_t *,
...);
extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
vfs_pair_t *, ...);
extern int vfs_open_node_internal(vfs_lookup_res_t *);
 
extern bool vfs_nodes_init(void);
extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *);
293,11 → 197,16
extern void vfs_register(ipc_callid_t, ipc_call_t *);
extern void vfs_mount(ipc_callid_t, ipc_call_t *);
extern void vfs_open(ipc_callid_t, ipc_call_t *);
extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
extern void vfs_sync(ipc_callid_t, ipc_call_t *);
extern void vfs_close(ipc_callid_t, ipc_call_t *);
extern void vfs_read(ipc_callid_t, ipc_call_t *);
extern void vfs_write(ipc_callid_t, ipc_call_t *);
extern void vfs_seek(ipc_callid_t, ipc_call_t *);
extern void vfs_truncate(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_stat(ipc_callid_t, ipc_call_t *);
extern void vfs_mkdir(ipc_callid_t, ipc_call_t *);
extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
extern void vfs_rename(ipc_callid_t, ipc_call_t *);
/branches/arm/uspace/srv/vfs/vfs_node.c
38,15 → 38,14
#include "vfs.h"
#include <stdlib.h>
#include <string.h>
#include <futex.h>
#include <rwlock.h>
#include <libadt/hash_table.h>
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <assert.h>
#include <async.h>
#include <errno.h>
 
/** Futex protecting the VFS node hash table. */
futex_t nodes_futex = FUTEX_INITIALIZER;
/** Mutex protecting the VFS node hash table. */
FIBRIL_MUTEX_INITIALIZE(nodes_mutex);
 
#define NODES_BUCKETS_LOG 8
#define NODES_BUCKETS (1 << NODES_BUCKETS_LOG)
89,9 → 88,9
*/
void vfs_node_addref(vfs_node_t *node)
{
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
_vfs_node_addref(node);
futex_up(&nodes_futex);
fibril_mutex_unlock(&nodes_mutex);
}
 
/** Decrement reference count of a VFS node.
105,7 → 104,7
bool free_vfs_node = false;
bool free_fs_node = false;
 
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
if (node->refcnt-- == 1) {
/*
* We are dropping the last reference to this node.
121,7 → 120,7
if (!node->lnkcnt)
free_fs_node = true;
}
futex_up(&nodes_futex);
fibril_mutex_unlock(&nodes_mutex);
 
if (free_fs_node) {
/*
130,7 → 129,7
*/
int phone = vfs_grab_phone(node->fs_handle);
ipcarg_t rc;
rc = async_req_2_0(phone, VFS_DESTROY,
rc = async_req_2_0(phone, VFS_OUT_DESTROY,
(ipcarg_t)node->dev_handle, (ipcarg_t)node->index);
assert(rc == EOK);
vfs_release_phone(phone);
161,12 → 160,12
link_t *tmp;
vfs_node_t *node;
 
futex_down(&nodes_futex);
fibril_mutex_lock(&nodes_mutex);
tmp = hash_table_find(&nodes, key);
if (!tmp) {
node = (vfs_node_t *) malloc(sizeof(vfs_node_t));
if (!node) {
futex_up(&nodes_futex);
fibril_mutex_unlock(&nodes_mutex);
return NULL;
}
memset(node, 0, sizeof(vfs_node_t));
175,18 → 174,25
node->index = result->triplet.index;
node->size = result->size;
node->lnkcnt = result->lnkcnt;
node->type = result->type;
link_initialize(&node->nh_link);
rwlock_initialize(&node->contents_rwlock);
fibril_rwlock_initialize(&node->contents_rwlock);
hash_table_insert(&nodes, key, &node->nh_link);
} else {
node = hash_table_get_instance(tmp, vfs_node_t, nh_link);
node = hash_table_get_instance(tmp, vfs_node_t, nh_link);
if (node->type == VFS_NODE_UNKNOWN &&
result->type != VFS_NODE_UNKNOWN) {
/* Upgrade the node type. */
node->type = result->type;
}
}
 
assert(node->size == result->size);
assert(node->lnkcnt == result->lnkcnt);
assert(node->type == result->type || result->type == VFS_NODE_UNKNOWN);
 
_vfs_node_addref(node);
futex_up(&nodes_futex);
fibril_mutex_unlock(&nodes_mutex);
 
return node;
}
226,4 → 232,4
 
/**
* @}
*/
*/
/branches/arm/uspace/srv/vfs/vfs_lookup.c
28,10 → 28,10
 
/** @addtogroup fs
* @{
*/
*/
 
/**
* @file vfs_lookup.c
* @file vfs_lookup.c
* @brief
*/
 
42,27 → 42,28
#include <string.h>
#include <stdarg.h>
#include <bool.h>
#include <futex.h>
#include <libadt/list.h>
#include <fibril_sync.h>
#include <adt/list.h>
#include <vfs/canonify.h>
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
 
futex_t plb_futex = FUTEX_INITIALIZER;
link_t plb_head; /**< PLB entry ring buffer. */
FIBRIL_MUTEX_INITIALIZE(plb_mutex);
LIST_INITIALIZE(plb_head); /**< PLB entry ring buffer. */
uint8_t *plb = NULL;
 
/** Perform a path lookup.
*
* @param path Path to be resolved; it must be a NULL-terminated
* string.
* @param lflag Flags to be used during lookup.
* @param result Empty structure where the lookup result will be stored.
* Can be NULL.
* @param altroot If non-empty, will be used instead of rootfs as the root
* of the whole VFS tree.
* @param path Path to be resolved; it must be a NULL-terminated
* string.
* @param lflag Flags to be used during lookup.
* @param result Empty structure where the lookup result will be stored.
* Can be NULL.
* @param altroot If non-empty, will be used instead of rootfs as the root
* of the whole VFS tree.
*
* @return EOK on success or an error code from errno.h.
* @return EOK on success or an error code from errno.h.
*
*/
int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result,
vfs_pair_t *altroot, ...)
91,7 → 92,7
va_end(ap);
}
futex_down(&plb_futex);
fibril_mutex_lock(&plb_mutex);
 
plb_entry_t entry;
link_initialize(&entry.plb_link);
118,7 → 119,7
/*
* The buffer cannot absorb the path.
*/
futex_up(&plb_futex);
fibril_mutex_unlock(&plb_mutex);
return ELIMIT;
}
} else {
126,7 → 127,7
/*
* The buffer cannot absorb the path.
*/
futex_up(&plb_futex);
fibril_mutex_unlock(&plb_mutex);
return ELIMIT;
}
}
145,7 → 146,7
*/
list_append(&entry.plb_link, &plb_head);
futex_up(&plb_futex);
fibril_mutex_unlock(&plb_mutex);
 
/*
* Copy the path into PLB.
158,16 → 159,16
 
ipc_call_t answer;
int phone = vfs_grab_phone(root->fs_handle);
aid_t req = async_send_5(phone, VFS_LOOKUP, (ipcarg_t) first,
aid_t req = async_send_5(phone, VFS_OUT_LOOKUP, (ipcarg_t) first,
(ipcarg_t) (first + len - 1) % PLB_SIZE,
(ipcarg_t) root->dev_handle, (ipcarg_t) lflag, (ipcarg_t) index,
&answer);
vfs_release_phone(phone);
 
ipcarg_t rc;
async_wait_for(req, &rc);
 
futex_down(&plb_futex);
vfs_release_phone(phone);
fibril_mutex_lock(&plb_mutex);
list_remove(&entry.plb_link);
/*
* Erasing the path from PLB will come handy for debugging purposes.
174,19 → 175,58
*/
memset(&plb[first], 0, cnt1);
memset(plb, 0, cnt2);
futex_up(&plb_futex);
fibril_mutex_unlock(&plb_mutex);
 
if ((rc == EOK) && result) {
if ((rc == EOK) && (result)) {
result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer);
result->triplet.dev_handle = (dev_handle_t) IPC_GET_ARG2(answer);
result->triplet.index = (fs_index_t) IPC_GET_ARG3(answer);
result->size = (size_t) IPC_GET_ARG4(answer);
result->lnkcnt = (unsigned) IPC_GET_ARG5(answer);
if (lflag & L_FILE)
result->type = VFS_NODE_FILE;
else if (lflag & L_DIRECTORY)
result->type = VFS_NODE_DIRECTORY;
else
result->type = VFS_NODE_UNKNOWN;
}
 
return rc;
}
 
/** Perform a node open operation.
*
* @return EOK on success or an error code from errno.h.
*
*/
int vfs_open_node_internal(vfs_lookup_res_t *result)
{
int phone = vfs_grab_phone(result->triplet.fs_handle);
ipc_call_t answer;
aid_t req = async_send_2(phone, VFS_OUT_OPEN_NODE,
(ipcarg_t) result->triplet.dev_handle,
(ipcarg_t) result->triplet.index, &answer);
ipcarg_t rc;
async_wait_for(req, &rc);
vfs_release_phone(phone);
if (rc == EOK) {
result->size = (size_t) IPC_GET_ARG1(answer);
result->lnkcnt = (unsigned) IPC_GET_ARG2(answer);
if (IPC_GET_ARG3(answer) & L_FILE)
result->type = VFS_NODE_FILE;
else if (IPC_GET_ARG3(answer) & L_DIRECTORY)
result->type = VFS_NODE_DIRECTORY;
else
result->type = VFS_NODE_UNKNOWN;
}
return rc;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/vfs/vfs_register.c
28,10 → 28,10
 
/** @addtogroup fs
* @{
*/
*/
 
/**
* @file vfs_register.c
* @file vfs_register.c
* @brief
*/
 
45,15 → 45,16
#include <string.h>
#include <ctype.h>
#include <bool.h>
#include <futex.h>
#include <libadt/list.h>
#include <fibril_sync.h>
#include <adt/list.h>
#include <as.h>
#include <assert.h>
#include <atomic.h>
#include "vfs.h"
 
atomic_t fs_head_futex = FUTEX_INITIALIZER;
link_t fs_head;
FIBRIL_CONDVAR_INITIALIZE(fs_head_cv);
FIBRIL_MUTEX_INITIALIZE(fs_head_lock);
LIST_INITIALIZE(fs_head);
 
atomic_t fs_handle_next = {
.count = 1
98,30 → 99,6
return false;
}
 
/*
* Check if the FS implements mandatory VFS operations.
*/
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] != VFS_OP_DEFINED) {
dprintf("Operation VFS_LOOKUP not defined by the client.\n");
return false;
}
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_READ)] != VFS_OP_DEFINED) {
dprintf("Operation VFS_READ not defined by the client.\n");
return false;
}
/*
* Check if each operation is either not defined, defined or default.
*/
for (i = VFS_FIRST; i < VFS_LAST_CLNT; i++) {
if ((info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_NULL) &&
(info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_DEFAULT) &&
(info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_DEFINED)) {
dprintf("Operation info not understood.\n");
return false;
}
}
return true;
}
 
183,7 → 160,7
return;
}
link_initialize(&fs_info->fs_link);
futex_initialize(&fs_info->phone_futex, 1);
fibril_mutex_initialize(&fs_info->phone_lock);
rc = ipc_data_write_finalize(callid, &fs_info->vfs_info, size);
if (rc != EOK) {
204,8 → 181,7
return;
}
futex_down(&fs_head_futex);
fibril_inc_sercount();
fibril_mutex_lock(&fs_head_lock);
 
/*
* Check for duplicit registrations.
215,8 → 191,7
* We already register a fs like this.
*/
dprintf("FS is already registered.\n");
fibril_dec_sercount();
futex_up(&fs_head_futex);
fibril_mutex_unlock(&fs_head_lock);
free(fs_info);
ipc_answer_0(callid, EEXISTS);
ipc_answer_0(rid, EEXISTS);
238,8 → 213,7
if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
list_remove(&fs_info->fs_link);
fibril_dec_sercount();
futex_up(&fs_head_futex);
fibril_mutex_unlock(&fs_head_lock);
free(fs_info);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
257,8 → 231,7
if (!ipc_share_in_receive(&callid, &size)) {
dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
list_remove(&fs_info->fs_link);
fibril_dec_sercount();
futex_up(&fs_head_futex);
fibril_mutex_unlock(&fs_head_lock);
ipc_hangup(fs_info->phone);
free(fs_info);
ipc_answer_0(callid, EINVAL);
272,8 → 245,7
if (size != PLB_SIZE) {
dprintf("Client suggests wrong size of PFB, size = %d\n", size);
list_remove(&fs_info->fs_link);
fibril_dec_sercount();
futex_up(&fs_head_futex);
fibril_mutex_unlock(&fs_head_lock);
ipc_hangup(fs_info->phone);
free(fs_info);
ipc_answer_0(callid, EINVAL);
297,8 → 269,8
fs_info->fs_handle = (fs_handle_t) atomic_postinc(&fs_handle_next);
ipc_answer_1(rid, EOK, (ipcarg_t) fs_info->fs_handle);
fibril_dec_sercount();
futex_up(&fs_head_futex);
fibril_condvar_broadcast(&fs_head_cv);
fibril_mutex_unlock(&fs_head_lock);
dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n",
FS_NAME_MAXLEN, fs_info->vfs_info.name, fs_info->fs_handle);
313,76 → 285,49
*/
int vfs_grab_phone(fs_handle_t handle)
{
int phone;
 
/*
* For now, we don't try to be very clever and very fast.
* We simply lookup the phone in the fs_head list. We currently don't
* open any additional phones (even though that itself would be pretty
* straightforward; housekeeping multiple open phones to a FS task would
* be more demanding). Instead, we simply take the respective
* phone_futex and keep it until vfs_release_phone().
* For now, we don't try to be very clever and very fast. We simply
* lookup the phone in the fs_head list and duplicate it. The duplicate
* phone will be returned to the client and the client will use it for
* communication. In the future, we should cache the connections so
* that they do not have to be reestablished over and over again.
*/
futex_down(&fs_head_futex);
fibril_mutex_lock(&fs_head_lock);
link_t *cur;
fs_info_t *fs;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs = list_get_instance(cur, fs_info_t, fs_link);
if (fs->fs_handle == handle) {
futex_up(&fs_head_futex);
/*
* For now, take the futex unconditionally.
* Oh yeah, serialization rocks.
* It will be up'ed in vfs_release_phone().
*/
futex_down(&fs->phone_futex);
/*
* Avoid deadlock with other fibrils in the same thread
* by disabling fibril preemption.
*/
fibril_inc_sercount();
return fs->phone;
fibril_mutex_unlock(&fs_head_lock);
fibril_mutex_lock(&fs->phone_lock);
phone = ipc_connect_me_to(fs->phone, 0, 0, 0);
fibril_mutex_unlock(&fs->phone_lock);
 
assert(phone > 0);
return phone;
}
}
futex_up(&fs_head_futex);
fibril_mutex_unlock(&fs_head_lock);
return 0;
}
 
/** Tell VFS that the phone is in use for any request.
/** Tell VFS that the phone is not needed anymore.
*
* @param phone Phone to FS task.
*/
void vfs_release_phone(int phone)
{
bool found = false;
 
/*
* Undo the fibril_inc_sercount() done in vfs_grab_phone().
*/
fibril_dec_sercount();
futex_down(&fs_head_futex);
link_t *cur;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
if (fs->phone == phone) {
found = true;
futex_up(&fs_head_futex);
futex_up(&fs->phone_futex);
return;
}
}
futex_up(&fs_head_futex);
 
/*
* Not good to get here.
*/
assert(found == true);
/* TODO: implement connection caching */
ipc_hangup(phone);
}
 
/** Convert file system name to its handle.
*
* @param name File system name.
* @param lock If true, the function will down and up the
* fs_head_futex.
* @param lock If true, the function will lock and unlock the
* fs_head_lock.
*
* @return File system handle or zero if file system not found.
*/
391,18 → 336,17
int handle = 0;
if (lock)
futex_down(&fs_head_futex);
fibril_mutex_lock(&fs_head_lock);
link_t *cur;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
if (strncmp(fs->vfs_info.name, name,
sizeof(fs->vfs_info.name)) == 0) {
if (str_cmp(fs->vfs_info.name, name) == 0) {
handle = fs->fs_handle;
break;
}
}
if (lock)
futex_up(&fs_head_futex);
fibril_mutex_unlock(&fs_head_lock);
return handle;
}
 
/branches/arm/uspace/srv/vfs/vfs_file.c
40,6 → 40,8
#include <string.h>
#include <assert.h>
#include <bool.h>
#include <fibril.h>
#include <fibril_sync.h>
#include "vfs.h"
 
/**
55,9 → 57,9
* first VFS_OPEN operation.
*
* This resource being per-connection and, in the first place, per-fibril, we
* don't need to protect it by a futex.
* don't need to protect it by a mutex.
*/
__thread vfs_file_t **files = NULL;
fibril_local vfs_file_t **files = NULL;
 
/** Initialize the table of open files. */
bool vfs_files_init(void)
78,19 → 80,23
*/
int vfs_fd_alloc(void)
{
int i;
 
if (!vfs_files_init())
return ENOMEM;
unsigned int i;
for (i = 0; i < MAX_OPEN_FILES; i++) {
if (!files[i]) {
files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
if (!files[i])
return ENOMEM;
memset(files[i], 0, sizeof(vfs_file_t));
futex_initialize(&files[i]->lock, 1);
fibril_mutex_initialize(&files[i]->lock);
vfs_file_addref(files[i]);
return i;
return (int) i;
}
}
return EMFILE;
}
 
103,10 → 109,15
*/
int vfs_fd_free(int fd)
{
if ((fd >= MAX_OPEN_FILES) || (files[fd] == NULL))
if (!vfs_files_init())
return ENOMEM;
if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] == NULL))
return EBADF;
vfs_file_delref(files[fd]);
files[fd] = NULL;
return EOK;
}
 
150,11 → 161,15
*/
vfs_file_t *vfs_file_get(int fd)
{
if (fd < MAX_OPEN_FILES)
if (!vfs_files_init())
return NULL;
if ((fd >= 0) && (fd < MAX_OPEN_FILES))
return files[fd];
return NULL;
}
 
/**
* @}
*/
*/
/branches/arm/uspace/srv/vfs/Makefile
32,6 → 32,7
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
57,18 → 58,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/devmap/devmap.c
28,9 → 28,9
 
/**
* @defgroup devmap Device mapper.
* @brief HelenOS device mapper.
* @brief HelenOS device mapper.
* @{
*/
*/
 
/** @file
*/
41,115 → 41,131
#include <stdio.h>
#include <errno.h>
#include <bool.h>
#include <futex.h>
#include <fibril_sync.h>
#include <stdlib.h>
#include <string.h>
#include <ipc/devmap.h>
 
#define NAME "devmap"
#define NAME "devmap"
#define NULL_DEVICES 256
 
/** Representation of device driver.
*
* Each driver is responsible for a set of devices.
*
*/
typedef struct {
/** Pointers to previous and next drivers in linked list */
link_t drivers;
/** Pointer to the linked list of devices controlled by this driver */
link_t devices;
/** Phone asociated with this driver */
ipcarg_t phone;
/** Device driver name */
char *name;
/** Fibril mutex for list of devices owned by this driver */
fibril_mutex_t devices_mutex;
} devmap_driver_t;
 
/** Info about registered device
*
*/
typedef struct {
/** Pointer to the previous and next device in the list of all devices */
link_t devices;
/** Pointer to the previous and next device in the list of devices
owned by one driver */
link_t driver_devices;
/** Unique device identifier */
dev_handle_t handle;
/** Device name */
char *name;
/** Device driver handling this device */
devmap_driver_t *driver;
} devmap_device_t;
 
LIST_INITIALIZE(devices_list);
LIST_INITIALIZE(drivers_list);
 
/* order of locking:
* drivers_list_futex
* devices_list_futex
* (devmap_driver_t *)->devices_futex
* create_handle_futex
/* Locking order:
* drivers_list_mutex
* devices_list_mutex
* (devmap_driver_t *)->devices_mutex
* create_handle_mutex
**/
 
static atomic_t devices_list_futex = FUTEX_INITIALIZER;
static atomic_t drivers_list_futex = FUTEX_INITIALIZER;
static atomic_t create_handle_futex = FUTEX_INITIALIZER;
static FIBRIL_MUTEX_INITIALIZE(devices_list_mutex);
static FIBRIL_CONDVAR_INITIALIZE(devices_list_cv);
static FIBRIL_MUTEX_INITIALIZE(drivers_list_mutex);
static FIBRIL_MUTEX_INITIALIZE(create_handle_mutex);
static FIBRIL_MUTEX_INITIALIZE(null_devices_mutex);
 
static dev_handle_t last_handle = 0;
static devmap_device_t *null_devices[NULL_DEVICES];
 
static int devmap_create_handle(void)
static dev_handle_t devmap_create_handle(void)
{
static int last_handle = 0;
int handle;
 
/* TODO: allow reusing old handles after their unregistration
and implement some version of LRU algorithm */
/* FIXME: overflow */
futex_down(&create_handle_futex);
 
last_handle += 1;
handle = last_handle;
 
futex_up(&create_handle_futex);
 
return handle;
* and implement some version of LRU algorithm, avoid overflow
*/
fibril_mutex_lock(&create_handle_mutex);
last_handle++;
fibril_mutex_unlock(&create_handle_mutex);
return last_handle;
}
 
 
/** Initialize device mapper.
*
*
*/
static int devmap_init()
{
/* TODO: */
 
return EOK;
}
 
/** Find device with given name.
*
*/
static devmap_device_t *devmap_device_find_name(const char *name)
{
link_t *item;
link_t *item = devices_list.next;
devmap_device_t *device = NULL;
 
item = devices_list.next;
 
while (item != &devices_list) {
 
device = list_get_instance(item, devmap_device_t, devices);
if (0 == strcmp(device->name, name)) {
if (str_cmp(device->name, name) == 0)
break;
}
item = item->next;
}
 
if (item == &devices_list)
return NULL;
 
device = list_get_instance(item, devmap_device_t, devices);
return device;
}
 
/** Find device with given handle.
*
* @todo: use hash table
*
*/
static devmap_device_t *devmap_device_find_handle(int handle)
static devmap_device_t *devmap_device_find_handle(dev_handle_t handle)
{
link_t *item;
fibril_mutex_lock(&devices_list_mutex);
link_t *item = (&devices_list)->next;
devmap_device_t *device = NULL;
futex_down(&devices_list_futex);
 
item = (&devices_list)->next;
 
while (item != &devices_list) {
 
device = list_get_instance(item, devmap_device_t, devices);
if (device->handle == handle) {
if (device->handle == handle)
break;
}
item = item->next;
}
 
if (item == &devices_list) {
futex_up(&devices_list_futex);
fibril_mutex_unlock(&devices_list_mutex);
return NULL;
}
 
device = list_get_instance(item, devmap_device_t, devices);
futex_up(&devices_list_futex);
 
fibril_mutex_unlock(&devices_list_mutex);
return device;
}
 
159,14 → 175,12
*/
static int devmap_device_unregister_core(devmap_device_t *device)
{
 
list_remove(&(device->devices));
list_remove(&(device->driver_devices));
 
free(device->name);
free(device->name);
free(device);
 
 
return EOK;
}
 
176,31 → 190,28
*/
static void devmap_driver_register(devmap_driver_t **odriver)
{
size_t name_size;
ipc_callid_t callid;
ipc_call_t call;
devmap_driver_t *driver;
ipc_callid_t iid;
ipc_call_t icall;
 
*odriver = NULL;
iid = async_get_call(&icall);
 
ipc_call_t icall;
ipc_callid_t iid = async_get_call(&icall);
if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) {
ipc_answer_0(iid, EREFUSED);
return;
}
 
if (NULL ==
(driver = (devmap_driver_t *)malloc(sizeof(devmap_driver_t)))) {
}
devmap_driver_t *driver = (devmap_driver_t *) malloc(sizeof(devmap_driver_t));
if (driver == NULL) {
ipc_answer_0(iid, ENOMEM);
return;
}
 
/*
/*
* Get driver name
*/
ipc_callid_t callid;
size_t name_size;
if (!ipc_data_write_receive(&callid, &name_size)) {
free(driver);
ipc_answer_0(callid, EREFUSED);
207,7 → 218,7
ipc_answer_0(iid, EREFUSED);
return;
}
 
if (name_size > DEVMAP_NAME_MAXLEN) {
free(driver);
ipc_answer_0(callid, EINVAL);
214,43 → 225,45
ipc_answer_0(iid, EREFUSED);
return;
}
 
/*
* Allocate buffer for device name.
*/
if (NULL == (driver->name = (char *)malloc(name_size + 1))) {
driver->name = (char *) malloc(name_size + 1);
if (driver->name == NULL) {
free(driver);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(iid, EREFUSED);
return;
}
 
}
/*
* Send confirmation to sender and get data into buffer.
*/
if (EOK != ipc_data_write_finalize(callid, driver->name, name_size)) {
if (ipc_data_write_finalize(callid, driver->name, name_size) != EOK) {
free(driver->name);
free(driver);
ipc_answer_0(iid, EREFUSED);
return;
}
 
driver->name[name_size] = 0;
 
/* Initialize futex for list of devices owned by this driver */
futex_initialize(&(driver->devices_futex), 1);
 
/*
/* Initialize mutex for list of devices owned by this driver */
fibril_mutex_initialize(&driver->devices_mutex);
/*
* Initialize list of asociated devices
*/
list_initialize(&(driver->devices));
 
/*
* Create connection to the driver
list_initialize(&driver->devices);
/*
* Create connection to the driver
*/
ipc_call_t call;
callid = async_get_call(&call);
 
if (IPC_M_CONNECT_TO_ME != IPC_GET_METHOD(call)) {
if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
ipc_answer_0(callid, ENOTSUP);
free(driver->name);
258,73 → 271,71
ipc_answer_0(iid, ENOTSUP);
return;
}
 
driver->phone = IPC_GET_ARG5(call);
ipc_answer_0(callid, EOK);
list_initialize(&(driver->drivers));
 
futex_down(&drivers_list_futex);
fibril_mutex_lock(&drivers_list_mutex);
/* TODO:
* check that no driver with name equal to driver->name is registered
*/
 
/*
/*
* Insert new driver into list of registered drivers
*/
list_append(&(driver->drivers), &drivers_list);
futex_up(&drivers_list_futex);
fibril_mutex_unlock(&drivers_list_mutex);
ipc_answer_0(iid, EOK);
 
*odriver = driver;
}
 
/** Unregister device driver, unregister all its devices and free driver
/**
* Unregister device driver, unregister all its devices and free driver
* structure.
*
*/
static int devmap_driver_unregister(devmap_driver_t *driver)
{
devmap_device_t *device;
 
if (NULL == driver)
if (driver == NULL)
return EEXISTS;
futex_down(&drivers_list_futex);
 
ipc_hangup(driver->phone);
fibril_mutex_lock(&drivers_list_mutex);
/* remove it from list of drivers */
if (driver->phone != 0)
ipc_hangup(driver->phone);
/* Remove it from list of drivers */
list_remove(&(driver->drivers));
 
/* unregister all its devices */
futex_down(&devices_list_futex);
futex_down(&(driver->devices_futex));
 
/* Unregister all its devices */
fibril_mutex_lock(&devices_list_mutex);
fibril_mutex_lock(&driver->devices_mutex);
while (!list_empty(&(driver->devices))) {
device = list_get_instance(driver->devices.next,
devmap_device_t *device = list_get_instance(driver->devices.next,
devmap_device_t, driver_devices);
devmap_device_unregister_core(device);
}
futex_up(&(driver->devices_futex));
futex_up(&devices_list_futex);
futex_up(&drivers_list_futex);
 
fibril_mutex_unlock(&driver->devices_mutex);
fibril_mutex_unlock(&devices_list_mutex);
fibril_mutex_unlock(&drivers_list_mutex);
/* free name and driver */
if (NULL != driver->name) {
if (driver->name != NULL)
free(driver->name);
}
 
free(driver);
 
return EOK;
}
 
 
/** Register instance of device
*
*/
331,29 → 342,27
static void devmap_device_register(ipc_callid_t iid, ipc_call_t *icall,
devmap_driver_t *driver)
{
ipc_callid_t callid;
size_t size;
devmap_device_t *device;
 
if (NULL == driver) {
if (driver == NULL) {
ipc_answer_0(iid, EREFUSED);
return;
}
/* Create new device entry */
if (NULL ==
(device = (devmap_device_t *) malloc(sizeof(devmap_device_t)))) {
devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
if (device == NULL) {
ipc_answer_0(iid, ENOMEM);
return;
}
/* Get device name */
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
free(device);
ipc_answer_0(iid, EREFUSED);
return;
}
 
if (size > DEVMAP_NAME_MAXLEN) {
free(device);
ipc_answer_0(callid, EINVAL);
363,8 → 372,8
/* +1 for terminating \0 */
device->name = (char *) malloc(size + 1);
 
if (NULL == device->name) {
if (device->name == NULL) {
free(device);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(iid, EREFUSED);
373,38 → 382,39
ipc_data_write_finalize(callid, device->name, size);
device->name[size] = 0;
 
list_initialize(&(device->devices));
list_initialize(&(device->driver_devices));
 
futex_down(&devices_list_futex);
 
fibril_mutex_lock(&devices_list_mutex);
/* Check that device with such name is not already registered */
if (NULL != devmap_device_find_name(device->name)) {
printf(NAME ": Device '%s' already registered\n", device->name);
futex_up(&devices_list_futex);
fibril_mutex_unlock(&devices_list_mutex);
free(device->name);
free(device);
ipc_answer_0(iid, EEXISTS);
return;
}
 
/* Get unique device handle */
device->handle = devmap_create_handle();
 
device->handle = devmap_create_handle();
device->driver = driver;
/* Insert device into list of all devices */
list_append(&device->devices, &devices_list);
 
/* Insert device into list of devices that belog to one driver */
futex_down(&device->driver->devices_futex);
fibril_mutex_lock(&device->driver->devices_mutex);
list_append(&device->driver_devices, &device->driver->devices);
futex_up(&device->driver->devices_futex);
futex_up(&devices_list_futex);
 
fibril_mutex_unlock(&device->driver->devices_mutex);
fibril_condvar_broadcast(&devices_list_cv);
fibril_mutex_unlock(&devices_list_mutex);
ipc_answer_1(iid, EOK, device->handle);
}
 
415,162 → 425,325
devmap_driver_t *driver)
{
/* TODO */
 
return EOK;
}
 
/** Connect client to the device.
*
* Find device driver owning requested device and forward
* the message to it.
*
*/
static void devmap_forward(ipc_callid_t callid, ipc_call_t *call)
{
devmap_device_t *dev;
int handle;
 
/*
* Get handle from request
*/
handle = IPC_GET_ARG2(*call);
dev = devmap_device_find_handle(handle);
 
if (NULL == dev) {
dev_handle_t handle = IPC_GET_ARG2(*call);
devmap_device_t *dev = devmap_device_find_handle(handle);
if ((dev == NULL) || (dev->driver == NULL) || (dev->driver->phone == 0)) {
ipc_answer_0(callid, ENOENT);
return;
}
 
ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle),
}
ipc_forward_fast(callid, dev->driver->phone, dev->handle,
IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
}
 
/** Find handle for device instance identified by name.
*
* In answer will be send EOK and device handle in arg1 or a error
* code from errno.h.
* code from errno.h.
*
*/
static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall)
{
char *name = NULL;
size_t name_size;
const devmap_device_t *dev;
ipc_callid_t callid;
ipcarg_t retval;
/*
/*
* Wait for incoming message with device name (but do not
* read the name itself until the buffer is allocated).
*/
if (!ipc_data_write_receive(&callid, &name_size)) {
ipc_callid_t callid;
size_t size;
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EREFUSED);
ipc_answer_0(iid, EREFUSED);
return;
}
 
if (name_size > DEVMAP_NAME_MAXLEN) {
if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(iid, EREFUSED);
return;
}
 
/*
* Allocate buffer for device name.
*/
if (NULL == (name = (char *)malloc(name_size))) {
char *name = (char *) malloc(size + 1);
if (name == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(iid, EREFUSED);
return;
}
 
}
/*
* Send confirmation to sender and get data into buffer.
*/
if (EOK != (retval = ipc_data_write_finalize(callid, name,
name_size))) {
ipcarg_t retval = ipc_data_write_finalize(callid, name, size);
if (retval != EOK) {
ipc_answer_0(iid, EREFUSED);
free(name);
return;
}
name[size] = '\0';
fibril_mutex_lock(&devices_list_mutex);
const devmap_device_t *dev;
recheck:
 
/*
* Find device name in linked list of known devices.
* Find device name in the list of known devices.
*/
dev = devmap_device_find_name(name);
 
/*
* Device was not found.
*/
if (NULL == dev) {
if (dev == NULL) {
if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
/* Blocking lookup */
fibril_condvar_wait(&devices_list_cv,
&devices_list_mutex);
goto recheck;
}
ipc_answer_0(iid, ENOENT);
free(name);
fibril_mutex_unlock(&devices_list_mutex);
return;
}
 
fibril_mutex_unlock(&devices_list_mutex);
ipc_answer_1(iid, EOK, dev->handle);
free(name);
}
 
/** Find name of device identified by id and send it to caller.
/** Find name of device identified by id and send it to caller.
*
*/
static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall)
static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall)
{
const devmap_device_t *device;
size_t name_size;
 
device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
 
const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall));
/*
* Device not found.
*/
if (NULL == device) {
if (device == NULL) {
ipc_answer_0(iid, ENOENT);
return;
}
 
}
ipc_answer_0(iid, EOK);
size_t name_size = str_size(device->name);
/* FIXME:
* We have no channel from DEVMAP to client, therefore
* sending must be initiated by client.
*
* int rc = ipc_data_write_send(phone, device->name, name_size);
* if (rc != EOK) {
* async_wait_for(req, NULL);
* return rc;
* }
*/
/* TODO: send name in response */
}
 
name_size = strlen(device->name);
static void devmap_get_count(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&devices_list_mutex);
ipc_answer_1(iid, EOK, list_count(&devices_list));
fibril_mutex_unlock(&devices_list_mutex);
}
 
static void devmap_get_devices(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&devices_list_mutex);
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size)) {
ipc_answer_0(callid, EREFUSED);
ipc_answer_0(iid, EREFUSED);
return;
}
if ((size % sizeof(dev_desc_t)) != 0) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(iid, EREFUSED);
return;
}
size_t count = size / sizeof(dev_desc_t);
dev_desc_t *desc = (dev_desc_t *) malloc(size);
if (desc == NULL) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(iid, EREFUSED);
return;
}
size_t pos = 0;
link_t *item = devices_list.next;
while ((item != &devices_list) && (pos < count)) {
devmap_device_t *device = list_get_instance(item, devmap_device_t, devices);
desc[pos].handle = device->handle;
str_cpy(desc[pos].name, DEVMAP_NAME_MAXLEN, device->name);
pos++;
item = item->next;
}
ipcarg_t retval = ipc_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t));
if (retval != EOK) {
ipc_answer_0(iid, EREFUSED);
free(desc);
return;
}
free(desc);
fibril_mutex_unlock(&devices_list_mutex);
ipc_answer_1(iid, EOK, pos);
}
 
/* FIXME:
we have no channel from DEVMAP to client ->
sending must be initiated by client
static void devmap_null_create(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&null_devices_mutex);
unsigned int i;
bool fnd = false;
for (i = 0; i < NULL_DEVICES; i++) {
if (null_devices[i] == NULL) {
fnd = true;
break;
}
}
if (!fnd) {
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, ENOMEM);
return;
}
/* Create NULL device entry */
devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t));
if (device == NULL) {
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, ENOMEM);
return;
}
char null[DEVMAP_NAME_MAXLEN];
snprintf(null, DEVMAP_NAME_MAXLEN, "null%u", i);
device->name = str_dup(null);
if (device->name == NULL) {
fibril_mutex_unlock(&null_devices_mutex);
free(device);
ipc_answer_0(iid, ENOMEM);
return;
}
list_initialize(&(device->devices));
list_initialize(&(device->driver_devices));
fibril_mutex_lock(&devices_list_mutex);
/* Get unique device handle */
device->handle = devmap_create_handle();
device->driver = NULL;
/* Insert device into list of all devices
and into null devices array */
list_append(&device->devices, &devices_list);
null_devices[i] = device;
fibril_mutex_unlock(&devices_list_mutex);
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_1(iid, EOK, (ipcarg_t) i);
}
 
int rc = ipc_data_write_send(phone, device->name, name_size);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
static void devmap_null_destroy(ipc_callid_t iid, ipc_call_t *icall)
{
fibril_mutex_lock(&null_devices_mutex);
ipcarg_t i = IPC_GET_ARG1(*icall);
if (null_devices[i] == NULL) {
ipc_answer_0(iid, ENOENT);
return;
}
*/
/* TODO: send name in response */
devmap_device_unregister_core(null_devices[i]);
null_devices[i] = NULL;
fibril_mutex_unlock(&null_devices_mutex);
ipc_answer_0(iid, EOK);
}
 
/** Initialize device mapper.
*
*
*/
static bool devmap_init(void)
{
fibril_mutex_lock(&null_devices_mutex);
unsigned int i;
for (i = 0; i < NULL_DEVICES; i++)
null_devices[i] = NULL;
fibril_mutex_unlock(&null_devices_mutex);
return true;
}
 
/** Handle connection with device driver.
*
*/
static void devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
bool cont = true;
devmap_driver_t *driver = NULL;
 
ipc_answer_0(iid, EOK);
 
/* Accept connection */
ipc_answer_0(iid, EOK);
devmap_driver_t *driver = NULL;
devmap_driver_register(&driver);
 
if (NULL == driver)
return;
bool cont = true;
while (cont) {
callid = async_get_call(&call);
 
switch (IPC_GET_METHOD(call)) {
ipc_call_t call;
ipc_callid_t callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
cont = false;
continue; /* Exit thread */
continue;
case DEVMAP_DRIVER_UNREGISTER:
if (NULL == driver) {
if (NULL == driver)
ipc_answer_0(callid, ENOENT);
} else {
else
ipc_answer_0(callid, EOK);
}
break;
case DEVMAP_DEVICE_REGISTER:
/* Register one instance of device */
584,23 → 757,21
devmap_get_handle(callid, &call);
break;
case DEVMAP_DEVICE_GET_NAME:
devmap_get_handle(callid, &call);
devmap_get_name(callid, &call);
break;
default:
if (!(callid & IPC_CALLID_NOTIFICATION)) {
if (!(callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(callid, ENOENT);
}
}
}
if (NULL != driver) {
/*
if (driver != NULL) {
/*
* Unregister the device driver and all its devices.
*/
devmap_driver_unregister(driver);
driver = NULL;
}
}
 
/** Handle connection with device client.
608,37 → 779,44
*/
static void devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
/* Accept connection */
ipc_answer_0(iid, EOK);
bool cont = true;
 
ipc_answer_0(iid, EOK); /* Accept connection */
 
while (cont) {
callid = async_get_call(&call);
 
switch (IPC_GET_METHOD(call)) {
ipc_call_t call;
ipc_callid_t callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
cont = false;
continue; /* Exit thread */
 
continue;
case DEVMAP_DEVICE_GET_HANDLE:
devmap_get_handle(callid, &call);
 
devmap_get_handle(callid, &call);
break;
case DEVMAP_DEVICE_GET_NAME:
/* TODO */
devmap_get_name(callid, &call);
break;
case DEVMAP_DEVICE_NULL_CREATE:
devmap_null_create(callid, &call);
break;
case DEVMAP_DEVICE_NULL_DESTROY:
devmap_null_destroy(callid, &call);
break;
case DEVMAP_DEVICE_GET_COUNT:
devmap_get_count(callid, &call);
break;
case DEVMAP_DEVICE_GET_DEVICES:
devmap_get_devices(callid, &call);
break;
default:
if (!(callid & IPC_CALLID_NOTIFICATION)) {
if (!(callid & IPC_CALLID_NOTIFICATION))
ipc_answer_0(callid, ENOENT);
}
}
}
}
 
/** Function for handling connections to devmap
/** Function for handling connections to devmap
*
*/
static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
656,10 → 834,9
devmap_forward(iid, icall);
break;
default:
ipc_answer_0(iid, ENOENT); /* No such interface */
/* No such interface */
ipc_answer_0(iid, ENOENT);
}
 
/* Cleanup */
}
 
/**
669,9 → 846,7
{
printf(NAME ": HelenOS Device Mapper\n");
ipcarg_t phonead;
 
if (devmap_init() != 0) {
if (!devmap_init()) {
printf(NAME ": Error while initializing service\n");
return -1;
}
678,13 → 853,15
/* Set a handler of incomming connections */
async_set_client_connection(devmap_connection);
 
/* Register device mapper at naming service */
ipcarg_t phonead;
if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0)
return -1;
printf(NAME ": Accepting connections\n");
async_manager();
/* Never reached */
return 0;
}
/branches/arm/uspace/srv/devmap/Makefile
31,12 → 31,11
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../libipc/include
LIBS = $(LIBC_PREFIX)/libc.a
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
44,7 → 43,7
SOURCES = \
devmap.c
 
CFLAGS += -D$(ARCH)
CFLAGS += -D$(UARCH)
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
55,18 → 54,18
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< >$@
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/uspace/srv/cir/fhc/Makefile
0,0 → 1,76
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
 
LIBC_PREFIX = ../../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = fhc
SOURCES = \
fhc.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/cir/fhc/fhc.c
0,0 → 1,157
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup fhc
* @{
*/
 
/**
* @file fhc.c
* @brief FHC bus controller driver.
*/
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/bus.h>
#include <ipc/ns.h>
#include <sysinfo.h>
#include <as.h>
#include <ddi.h>
#include <align.h>
#include <bool.h>
#include <errno.h>
#include <async.h>
#include <align.h>
#include <async.h>
#include <stdio.h>
#include <ipc/devmap.h>
 
#define NAME "fhc"
 
#define FHC_UART_INR 0x39
 
#define FHC_UART_IMAP 0x0
#define FHC_UART_ICLR 0x4
 
static void *fhc_uart_phys;
static volatile uint32_t *fhc_uart_virt;
static size_t fhc_uart_size;
 
/** Handle one connection to fhc.
*
* @param iid Hash of the request that opened the connection.
* @param icall Call data of the request that opened the connection.
*/
static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
 
/*
* Answer the first IPC_M_CONNECT_ME_TO call.
*/
ipc_answer_0(iid, EOK);
 
while (1) {
int inr;
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case BUS_CLEAR_INTERRUPT:
inr = IPC_GET_ARG1(call);
switch (inr) {
case FHC_UART_INR:
fhc_uart_virt[FHC_UART_ICLR] = 0;
ipc_answer_0(callid, EOK);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
}
break;
default:
ipc_answer_0(callid, EINVAL);
break;
}
}
}
 
/** Initialize the FHC driver.
*
* So far, the driver heavily depends on information provided by the kernel via
* sysinfo. In the future, there should be a standalone FHC driver.
*/
static bool fhc_init(void)
{
ipcarg_t phonead;
 
fhc_uart_size = sysinfo_value("fhc.uart.size");
fhc_uart_phys = (void *) sysinfo_value("fhc.uart.physical");
if (!fhc_uart_size) {
printf(NAME ": no FHC UART registers found\n");
return false;
}
 
fhc_uart_virt = as_get_mappable_page(fhc_uart_size);
int flags = AS_AREA_READ | AS_AREA_WRITE;
int retval = physmem_map(fhc_uart_phys, (void *) fhc_uart_virt,
ALIGN_UP(fhc_uart_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
if (retval < 0) {
printf(NAME ": Error mapping FHC UART registers\n");
return false;
}
printf(NAME ": FHC UART registers at %p, %d bytes\n", fhc_uart_phys,
fhc_uart_size);
 
async_set_client_connection(fhc_connection);
ipc_connect_to_me(PHONE_NS, SERVICE_FHC, 0, 0, &phonead);
return true;
}
 
int main(int argc, char **argv)
{
printf(NAME ": HelenOS FHC bus controller driver\n");
if (!fhc_init())
return -1;
printf(NAME ": Accepting connections\n");
async_manager();
 
/* Never reached */
return 0;
}
 
/**
* @}
*/
/branches/arm/uspace/srv/cir/obio/Makefile
0,0 → 1,76
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## Setup toolchain
#
 
 
LIBC_PREFIX = ../../../lib/libc
SOFTINT_PREFIX = ../../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
LIBS = $(LIBC_PREFIX)/libc.a
 
## Sources
#
 
OUTPUT = obio
SOURCES = \
obio.c
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
.PHONY: all clean depend disasm
 
all: $(OUTPUT) $(OUTPUT).disasm
 
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
 
depend:
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm: $(OUTPUT).disasm
 
$(OUTPUT).disasm: $(OUTPUT)
$(OBJDUMP) -d $< > $@
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/uspace/srv/cir/obio/obio.c
0,0 → 1,158
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup obio
* @{
*/
 
/**
* @file obio.c
* @brief OBIO driver.
*
* OBIO is a short for on-board I/O. On UltraSPARC IIi and systems with U2P,
* there is a piece of the root PCI bus controller address space, which
* contains interrupt mapping and clear registers for all on-board devices.
* Although UltraSPARC IIi and U2P are different in general, these registers can
* be found at the same addresses.
*/
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/bus.h>
#include <ipc/ns.h>
#include <sysinfo.h>
#include <as.h>
#include <ddi.h>
#include <align.h>
#include <bool.h>
#include <errno.h>
#include <async.h>
#include <align.h>
#include <async.h>
#include <stdio.h>
#include <ipc/devmap.h>
 
#define NAME "obio"
 
#define OBIO_SIZE 0x1898
 
#define OBIO_IMR_BASE 0x200
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK))
 
#define OBIO_CIR_BASE 0x300
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK))
 
#define INO_MASK 0x1f
 
static void *base_phys;
static volatile uint64_t *base_virt;
 
/** Handle one connection to obio.
*
* @param iid Hash of the request that opened the connection.
* @param icall Call data of the request that opened the connection.
*/
static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
{
ipc_callid_t callid;
ipc_call_t call;
 
/*
* Answer the first IPC_M_CONNECT_ME_TO call.
*/
ipc_answer_0(iid, EOK);
 
while (1) {
int inr;
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case BUS_CLEAR_INTERRUPT:
inr = IPC_GET_ARG1(call);
base_virt[OBIO_CIR(inr & INO_MASK)] = 0;
ipc_answer_0(callid, EOK);
break;
default:
ipc_answer_0(callid, EINVAL);
break;
}
}
}
 
/** Initialize the OBIO driver.
*
* So far, the driver heavily depends on information provided by the kernel via
* sysinfo. In the future, there should be a standalone OBIO driver.
*/
static bool obio_init(void)
{
ipcarg_t phonead;
 
base_phys = (void *) sysinfo_value("obio.base.physical");
if (!base_phys) {
printf(NAME ": no OBIO registers found\n");
return false;
}
 
base_virt = as_get_mappable_page(OBIO_SIZE);
int flags = AS_AREA_READ | AS_AREA_WRITE;
int retval = physmem_map(base_phys, (void *) base_virt,
ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
if (retval < 0) {
printf(NAME ": Error mapping OBIO registers\n");
return false;
}
printf(NAME ": OBIO registers with base at %p\n", base_phys);
 
async_set_client_connection(obio_connection);
ipc_connect_to_me(PHONE_NS, SERVICE_OBIO, 0, 0, &phonead);
return true;
}
 
int main(int argc, char **argv)
{
printf(NAME ": HelenOS OBIO driver\n");
if (!obio_init())
return -1;
printf(NAME ": Accepting connections\n");
async_manager();
 
/* Never reached */
return 0;
}
 
/**
* @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/srv/cir/obio
Property changes:
Added: svn:mergeinfo
/branches/arm/uspace/srv/pci/libpci/names.c
103,7 → 103,7
u32 id34 = id_pair(id3, id4);
unsigned int h = id_hash(cat, id12, id34);
struct id_entry *n = a->id_hash[h];
int len = strlen((char *) text);
int len = str_size((char *) text);
 
while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat))
n = n->next;
/branches/arm/uspace/srv/pci/Makefile
31,6 → 31,7
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
 
52,7 → 53,7
-include Makefile.depend
 
clean:
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS)
$(MAKE) -C libpci clean
 
depend:
60,7 → 61,7
 
$(OUTPUT): $(OBJECTS) $(LIBS)
$(MAKE) -C libpci
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
/branches/arm/uspace/dist/readme
0,0 → 1,10
Multilingual text test
----------------------
 
English: Quick brown fox jumps over the lazy dog
Czech: Příliš žluťoučký kůň úpěl ďábelské ódy
Greek: Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε
Hebrew: משוואת ברנולי היא משוואה בהידרודינמיקה
Arabic: التوزيع الجغرافي للحمل العنقودي
Russian: Леннон познакомился с художницей-авангардисткой
Armenian: Սկսեց հրատարակվել Երուսաղեմի հայկական
/branches/arm/uspace/Makefile
29,21 → 29,26
## Include configuration
#
 
-include Makefile.config
-include ../Makefile.config
 
DIRS = \
lib/libc \
lib/libfs \
lib/libblock \
lib/softint \
lib/softfloat \
srv/bd/ata_bd \
srv/bd/file_bd \
srv/bd/gxe_bd \
srv/bd/rd \
srv/ns \
srv/loader \
srv/fb \
srv/kbd \
srv/console \
srv/rd \
srv/fs/fat \
srv/fs/tmpfs \
srv/fs/devfs \
srv/vfs \
srv/devmap \
app/tetris \
51,47 → 56,34
app/trace \
app/klog \
app/init \
app/getvc \
app/bdsh
 
ifeq ($(ARCH), amd64)
ifeq ($(UARCH),amd64)
DIRS += srv/pci
endif
 
ifeq ($(ARCH), ia32)
ifeq ($(UARCH),ia32)
DIRS += srv/pci
endif
 
ifeq ($(ARCH), mips32)
CFLAGS += -DCONFIG_MIPS_FPU
ifeq ($(UARCH),sparc64)
DIRS += \
srv/cir/fhc \
srv/cir/obio
endif
 
ifeq ($(ARCH), mips32eb)
CFLAGS += -DCONFIG_MIPS_FPU
endif
 
BUILDS := $(addsuffix .build,$(DIRS))
CLEANS := $(addsuffix .clean,$(DIRS))
 
.PHONY: all config build $(BUILDS) $(CLEANS) clean distclean
.PHONY: all $(BUILDS) $(CLEANS) clean
 
all:
../tools/config.py uspace.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG)
$(MAKE) -C . build
all: ../Makefile.config ../config.h ../config.defs $(BUILDS)
 
config:
../tools/config.py uspace.config
 
build: $(BUILDS)
 
clean: $(CLEANS)
find $(DIRS) -name '*.o' -follow -exec rm \{\} \;
find lib/libc -name "_link.ld" -exec rm \{\} \;
 
distclean: clean
-rm Makefile.config
 
$(CLEANS):
-$(MAKE) -C $(basename $@) clean ARCH=$(ARCH)
-$(MAKE) -C $(basename $@) clean
 
$(BUILDS):
$(MAKE) -C $(basename $@) all ARCH=$(ARCH) COMPILER=$(COMPILER)
$(MAKE) -C $(basename $@) all
/branches/arm/kernel/kernel.config
File deleted
/branches/arm/kernel/arch/ppc64/_link.ld.in
File deleted
/branches/arm/kernel/arch/ppc64/include/cpuid.h
File deleted
/branches/arm/kernel/arch/ppc64/include/types.h
File deleted
/branches/arm/kernel/arch/ppc64/include/elf.h
File deleted
/branches/arm/kernel/arch/ppc64/include/memstr.h
File deleted
/branches/arm/kernel/arch/ppc64/include/arg.h
File deleted
/branches/arm/kernel/arch/ppc64/include/atomic.h
File deleted
/branches/arm/kernel/arch/ppc64/include/arch.h
File deleted
/branches/arm/kernel/arch/ppc64/include/proc/task.h
File deleted
/branches/arm/kernel/arch/ppc64/include/proc/thread.h
File deleted
/branches/arm/kernel/arch/ppc64/include/boot/boot.h
File deleted
/branches/arm/kernel/arch/ppc64/include/faddr.h
File deleted
/branches/arm/kernel/arch/ppc64/include/asm.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/frame.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/page.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/asid.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/tlb.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/as.h
File deleted
/branches/arm/kernel/arch/ppc64/include/context.h
File deleted
/branches/arm/kernel/arch/ppc64/include/debug.h
File deleted
/branches/arm/kernel/arch/ppc64/include/barrier.h
File deleted
/branches/arm/kernel/arch/ppc64/include/cpu.h
File deleted
/branches/arm/kernel/arch/ppc64/include/drivers/pic.h
File deleted
/branches/arm/kernel/arch/ppc64/include/asm/regname.h
File deleted
/branches/arm/kernel/arch/ppc64/include/context_offset.h
File deleted
/branches/arm/kernel/arch/ppc64/include/interrupt.h
File deleted
/branches/arm/kernel/arch/ppc64/include/fpu_context.h
File deleted
/branches/arm/kernel/arch/ppc64/include/exception.h
File deleted
/branches/arm/kernel/arch/ppc64/include/cycle.h
File deleted
/branches/arm/kernel/arch/ppc64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ppc64/Makefile.inc
File deleted
/branches/arm/kernel/arch/ppc64/src/dummy.s
File deleted
/branches/arm/kernel/arch/ppc64/src/interrupt.c
File deleted
/branches/arm/kernel/arch/ppc64/src/ppc64.c
File deleted
/branches/arm/kernel/arch/ppc64/src/drivers/pic.c
File deleted
/branches/arm/kernel/arch/ppc64/src/exception.S
File deleted
/branches/arm/kernel/arch/ppc64/src/fpu_context.S
File deleted
/branches/arm/kernel/arch/ppc64/src/ddi/ddi.c
File deleted
/branches/arm/kernel/arch/ppc64/src/asm.S
File deleted
/branches/arm/kernel/arch/ppc64/src/proc/scheduler.c
File deleted
/branches/arm/kernel/arch/ppc64/src/boot/boot.S
File deleted
/branches/arm/kernel/arch/ppc64/src/context.S
File deleted
/branches/arm/kernel/arch/ppc64/src/debug/panic.s
File deleted
/branches/arm/kernel/arch/ppc64/src/cpu/cpu.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/frame.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/page.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/tlb.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/as.c
File deleted
/branches/arm/kernel/arch/ia32xen/Makefile.inc
File deleted
/branches/arm/kernel/arch/ia32xen/src/debugger.c
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/mm/frame.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/mm/page.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/mm/tlb.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/mm/as.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/userspace.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/atomic.S
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/interrupt.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/drivers/xconsole.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/fpu_context.c
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/asm.S
File deleted
/branches/arm/kernel/arch/ia32xen/src/context.S
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/debug
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/cpu
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/ia32xen.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/bios
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/pm.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/delay.s
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/smp/mps.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/smp/smp.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/smp/ipi.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/smp/apic.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/ddi
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/boot/boot.S
File deleted
/branches/arm/kernel/arch/ia32xen/src/proc/thread.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/proc/scheduler.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/proc/task.c
File deleted
/branches/arm/kernel/arch/ia32xen/_link.ld.in
File deleted
/branches/arm/kernel/arch/ia32xen/include/pm.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/atomic.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/arch.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/proc
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/faddr.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/asm.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/hypercall.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/asid.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/tlb.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/as.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/frame.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/page.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/debugger.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/context.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/barrier.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/debug.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/cpu.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/drivers/xconsole.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/context_offset.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/interrupt.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/fpu_context.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/cycle.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/byteorder.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/types.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/cpuid.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/elf.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/bios
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/memstr.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/smp
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/arg.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/ddi
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/sparc64/src/asm.S
225,10 → 225,15
 
.global memsetb
memsetb:
b _memsetb
ba %xcc, _memsetb
nop
 
.global memsetw
memsetw:
ba %xcc, _memsetw
nop
 
 
.macro WRITE_ALTERNATE_REGISTER reg, bit
rdpr %pstate, %g1 ! save PSTATE.PEF
wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
272,7 → 277,7
*/
.global switch_to_userspace
switch_to_userspace:
save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
flushw
wrpr %g0, 0, %cleanwin ! avoid information leak
 
/branches/arm/kernel/arch/sparc64/src/smp/smp.c
35,6 → 35,7
#include <smp/smp.h>
#include <genarch/ofw/ofw_tree.h>
#include <cpu.h>
#include <arch/cpu_family.h>
#include <arch/cpu.h>
#include <arch.h>
#include <config.h>
43,6 → 44,7
#include <synch/synch.h>
#include <synch/waitq.h>
#include <print.h>
#include <arch/cpu_node.h>
 
/**
* This global variable is used to pick-up application processors
59,17 → 61,57
void smp_init(void)
{
ofw_tree_node_t *node;
count_t cnt = 0;
size_t cnt = 0;
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
while (node) {
cnt++;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
cnt++;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
}
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
cnt += 2;
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
config.cpu_count = max(1, cnt);
}
 
/**
* Wakes up the CPU which is represented by the "node" OFW tree node.
* If "node" represents the current CPU, calling the function has
* no effect.
*/
static void wakeup_cpu(ofw_tree_node_t *node)
{
uint32_t mid;
ofw_tree_property_t *prop;
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
prop = ofw_tree_getprop(node, "upa-portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "cpuid");
if (!prop || prop->value == NULL)
return;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid)
return;
 
waking_up_mid = mid;
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) ==
ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %" PRIu32
") timed out\n", __func__, mid);
}
 
/** Wake application processors up. */
void kmp(void *arg)
{
76,31 → 118,18
ofw_tree_node_t *node;
int i;
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) {
uint32_t mid;
ofw_tree_property_t *prop;
prop = ofw_tree_getprop(node, "upa-portid");
if (!prop || !prop->value)
continue;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid) {
/*
* Skip the current CPU.
*/
continue;
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
for (i = 0; node;
node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++)
wakeup_cpu(node);
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
wakeup_cpu(ofw_tree_find_child(node, "cpu@0"));
wakeup_cpu(ofw_tree_find_child(node, "cpu@1"));
node = ofw_tree_find_peer_by_name(node, "cmp");
}
 
/*
* Processor with ID == mid can proceed with its initialization.
*/
waking_up_mid = mid;
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n",
__func__, mid);
}
}
 
/branches/arm/kernel/arch/sparc64/src/smp/ipi.c
46,6 → 46,33
#include <time/delay.h>
#include <panic.h>
 
/** Set the contents of the outgoing interrupt vector data.
*
* The first data item (data 0) will be set to the value of func, the
* rest of the vector will contain zeros.
*
* This is a helper function used from within the cross_call function.
*
* @param func value the first data item of the vector will be set to
*/
static inline void set_intr_w_data(void (* func)(void))
{
#if defined (US)
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func);
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
#elif defined (US3)
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0);
#endif
}
 
/** Invoke function on another processor.
*
* Currently, only functions without arguments are supported.
71,16 → 98,15
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
if (status & INTR_DISPATCH_STATUS_BUSY)
panic("Interrupt Dispatch Status busy bit set\n");
panic("Interrupt Dispatch Status busy bit set.");
ASSERT(!(pstate_read() & PSTATE_IE_BIT));
do {
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0,
(uintptr_t) func);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
asi_u64_write(ASI_UDB_INTR_W,
set_intr_w_data(func);
asi_u64_write(ASI_INTR_W,
(mid << INTR_VEC_DISPATCH_MID_SHIFT) |
ASI_UDB_INTR_W_DISPATCH, 0);
VA_INTR_W_DISPATCH, 0);
membar();
125,7 → 151,7
func = tlb_shootdown_ipi_recv;
break;
default:
panic("Unknown IPI (%d).\n", ipi);
panic("Unknown IPI (%d).", ipi);
break;
}
/branches/arm/kernel/arch/sparc64/src/mm/tlb.c
54,14 → 54,13
#include <arch/mm/tsb.h>
#endif
 
static void dtlb_pte_copy(pte_t *t, index_t index, bool ro);
static void itlb_pte_copy(pte_t *t, index_t index);
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
const char *str);
static void do_fast_data_access_mmu_miss_fault(istate_t *istate,
tlb_tag_access_reg_t tag, const char *str);
static void do_fast_data_access_protection_fault(istate_t *istate,
tlb_tag_access_reg_t tag, const char *str);
static void dtlb_pte_copy(pte_t *, size_t, bool);
static void itlb_pte_copy(pte_t *, size_t);
static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
const char *);
static void do_fast_data_access_protection_fault(istate_t *,
tlb_tag_access_reg_t, const char *);
 
char *context_encoding[] = {
"Primary",
86,11 → 85,11
 
/** Insert privileged mapping into DMMU TLB.
*
* @param page Virtual page address.
* @param frame Physical frame address.
* @param pagesize Page size.
* @param locked True for permanent mappings, false otherwise.
* @param cacheable True if the mapping is cacheable, false otherwise.
* @param page Virtual page address.
* @param frame Physical frame address.
* @param pagesize Page size.
* @param locked True for permanent mappings, false otherwise.
* @param cacheable True if the mapping is cacheable, false otherwise.
*/
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
bool locked, bool cacheable)
103,7 → 102,7
pg.address = page;
fr.address = frame;
 
tag.value = ASID_KERNEL;
tag.context = ASID_KERNEL;
tag.vpn = pg.vpn;
 
dtlb_tag_access_write(tag.value);
126,12 → 125,12
 
/** Copy PTE to TLB.
*
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the entry will be created read-only, regardless of its
* w field.
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the entry will be created read-only, regardless
* of its w field.
*/
void dtlb_pte_copy(pte_t *t, index_t index, bool ro)
void dtlb_pte_copy(pte_t *t, size_t index, bool ro)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
165,10 → 164,10
 
/** Copy PTE to ITLB.
*
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
*/
void itlb_pte_copy(pte_t *t, index_t index)
void itlb_pte_copy(pte_t *t, size_t index)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
200,12 → 199,12
/** ITLB miss handler. */
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
{
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
pte_t *t;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
t = page_mapping_find(AS, page_16k);
if (t && PTE_EXECUTABLE(t)) {
/*
* The mapping was found in the software page hash table.
223,7 → 222,8
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
AS_PF_FAULT) {
do_fast_instruction_access_mmu_miss_fault(istate,
__func__);
}
235,18 → 235,21
* Note that some faults (e.g. kernel faults) were already resolved by the
* low-level, assembly language part of the fast_data_access_mmu_miss handler.
*
* @param tag Content of the TLB Tag Access register as it existed when the
* trap happened. This is to prevent confusion created by clobbered
* Tag Access register during a nested DTLB miss.
* @param istate Interrupted state saved on the stack.
* @param tag Content of the TLB Tag Access register as it existed
* when the trap happened. This is to prevent confusion
* created by clobbered Tag Access register during a nested
* DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
{
uintptr_t va;
index_t index;
uintptr_t page_8k;
uintptr_t page_16k;
size_t index;
pte_t *t;
 
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE;
 
if (tag.context == ASID_KERNEL) {
254,6 → 257,15
/* NULL access in kernel */
do_fast_data_access_mmu_miss_fault(istate, tag,
__func__);
} else if (page_8k >= end_of_identity) {
/*
* The kernel is accessing the I/O space.
* We still do identity mapping for I/O,
* but without caching.
*/
dtlb_insert_mapping(page_8k, KA2PA(page_8k),
PAGESIZE_8K, false, false);
return;
}
do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
"kernel page fault.");
260,7 → 272,7
}
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
t = page_mapping_find(AS, page_16k);
if (t) {
/*
* The mapping was found in the software page hash table.
278,7 → 290,8
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
AS_PF_FAULT) {
do_fast_data_access_mmu_miss_fault(istate, tag,
__func__);
}
287,22 → 300,23
 
/** DTLB protection fault handler.
*
* @param tag Content of the TLB Tag Access register as it existed when the
* trap happened. This is to prevent confusion created by clobbered
* Tag Access register during a nested DTLB miss.
* @param istate Interrupted state saved on the stack.
* @param tag Content of the TLB Tag Access register as it existed
* when the trap happened. This is to prevent confusion
* created by clobbered Tag Access register during a nested
* DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
{
uintptr_t va;
index_t index;
uintptr_t page_16k;
size_t index;
pte_t *t;
 
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
t = page_mapping_find(AS, page_16k);
if (t && PTE_WRITABLE(t)) {
/*
* The mapping was found in the software page hash table and is
312,7 → 326,7
t->a = true;
t->d = true;
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
va + index * MMU_PAGE_SIZE);
page_16k + index * MMU_PAGE_SIZE);
dtlb_pte_copy(t, index, false);
#ifdef CONFIG_TSB
dtsb_pte_copy(t, index, false);
324,7 → 338,8
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
AS_PF_FAULT) {
do_fast_data_access_protection_fault(istate, tag,
__func__);
}
331,6 → 346,26
}
}
 
/** Print TLB entry (for debugging purposes).
*
* The diag field has been left out in order to make this function more generic
* (there is no diag field in US3 architeture).
*
* @param i TLB entry number
* @param t TLB entry tag
* @param d TLB entry data
*/
static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
{
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
}
 
#if defined (US)
 
/** Print contents of both TLBs. */
void tlb_print(void)
{
342,12 → 377,7
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
t.value = itlb_tag_read_read(i);
 
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
print_tlb_entry(i, t, d);
}
 
printf("D-TLB contents:\n");
354,22 → 384,63
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
t.value = dtlb_tag_read_read(i);
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
print_tlb_entry(i, t, d);
}
}
 
#elif defined (US3)
 
/** Print contents of all TLBs. */
void tlb_print(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
printf("TLB_ISMALL contents:\n");
for (i = 0; i < tlb_ismall_size(); i++) {
d.value = dtlb_data_access_read(TLB_ISMALL, i);
t.value = dtlb_tag_read_read(TLB_ISMALL, i);
print_tlb_entry(i, t, d);
}
printf("TLB_IBIG contents:\n");
for (i = 0; i < tlb_ibig_size(); i++) {
d.value = dtlb_data_access_read(TLB_IBIG, i);
t.value = dtlb_tag_read_read(TLB_IBIG, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DSMALL contents:\n");
for (i = 0; i < tlb_dsmall_size(); i++) {
d.value = dtlb_data_access_read(TLB_DSMALL, i);
t.value = dtlb_tag_read_read(TLB_DSMALL, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DBIG_1 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_0, i);
t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DBIG_2 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_1, i);
t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
print_tlb_entry(i, t, d);
}
}
 
#endif
 
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
const char *str)
{
fault_if_from_uspace(istate, "%s\n", str);
fault_if_from_uspace(istate, "%s.", str);
dump_istate(istate);
panic("%s\n", str);
panic("%s.", str);
}
 
void do_fast_data_access_mmu_miss_fault(istate_t *istate,
379,12 → 450,12
 
va = tag.vpn << MMU_PAGE_WIDTH;
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
tag.context);
}
dump_istate(istate);
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
panic("%s\n", str);
printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
panic("%s.", str);
}
 
void do_fast_data_access_protection_fault(istate_t *istate,
395,12 → 466,12
va = tag.vpn << MMU_PAGE_WIDTH;
 
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
tag.context);
}
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
dump_istate(istate);
panic("%s\n", str);
panic("%s.", str);
}
 
void dump_sfsr_and_sfar(void)
411,30 → 482,39
sfsr.value = dtlb_sfsr_read();
sfar = dtlb_sfar_read();
#if defined (US)
printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
"fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
sfsr.ow, sfsr.fv);
#elif defined (US3)
printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
"w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
#endif
printf("DTLB SFAR: address=%p\n", sfar);
dtlb_sfsr_write(0);
}
 
#if defined (US)
/** Invalidate all unlocked ITLB and DTLB entries. */
void tlb_invalidate_all(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
 
/*
* Walk all ITLB and DTLB entries and remove all unlocked mappings.
*
* The kernel doesn't use global mappings so any locked global mappings
* found must have been created by someone else. Their only purpose now
* found must have been created by someone else. Their only purpose now
* is to collide with proper mappings. Invalidate immediately. It should
* be safe to invalidate them as late as now.
*/
 
tlb_data_t d;
tlb_tag_read_reg_t t;
 
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
if (!d.l || d.g) {
444,7 → 524,7
itlb_data_access_write(i, d.value);
}
}
 
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
if (!d.l || d.g) {
454,9 → 534,20
dtlb_data_access_write(i, d.value);
}
}
 
}
 
#elif defined (US3)
 
/** Invalidate all unlocked ITLB and DTLB entries. */
void tlb_invalidate_all(void)
{
itlb_demap(TLB_DEMAP_ALL, 0, 0);
dtlb_demap(TLB_DEMAP_ALL, 0, 0);
}
 
#endif
 
/** Invalidate all ITLB and DTLB entries that belong to specified ASID
* (Context).
*
484,11 → 575,11
/** Invalidate all ITLB and DTLB entries for specified page range in specified
* address space.
*
* @param asid Address Space ID.
* @param page First page which to sweep out from ITLB and DTLB.
* @param cnt Number of ITLB and DTLB entries to invalidate.
* @param asid Address Space ID.
* @param page First page which to sweep out from ITLB and DTLB.
* @param cnt Number of ITLB and DTLB entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
unsigned int i;
tlb_context_reg_t pc_save, ctx;
/branches/arm/kernel/arch/sparc64/src/mm/as.c
89,7 → 89,7
* The count must be calculated with respect to the emualted 16K page
* size.
*/
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
size_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
sizeof(tsb_entry_t)) >> FRAME_WIDTH;
frame_free(KA2PA((uintptr_t) as->arch.itsb));
return cnt;
101,7 → 101,7
int as_create_arch(as_t *as, int flags)
{
#ifdef CONFIG_TSB
tsb_invalidate(as, 0, (count_t) -1);
tsb_invalidate(as, 0, (size_t) -1);
#endif
return 0;
}
164,7 → 164,25
itsb_base_write(tsb_base.value);
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH;
dtsb_base_write(tsb_base.value);
#if defined (US3)
/*
* Clear the extension registers.
* In HelenOS, primary and secondary context registers contain
* equal values and kernel misses (context 0, ie. the nucleus context)
* are excluded from the TSB miss handler, so it makes no sense
* to have separate TSBs for primary, secondary and nucleus contexts.
* Clearing the extension registers will ensure that the value of the
* TSB Base register will be used as an address of TSB, making the code
* compatible with the US port.
*/
itsb_primary_extension_write(0);
itsb_nucleus_extension_write(0);
dtsb_primary_extension_write(0);
dtsb_secondary_extension_write(0);
dtsb_nucleus_extension_write(0);
#endif
#endif
}
 
/** Perform sparc64-specific tasks when an address space is removed from the
/branches/arm/kernel/arch/sparc64/src/mm/tsb.c
50,13 → 50,14
*
* @param as Address space.
* @param page First page to invalidate in TSB.
* @param pages Number of pages to invalidate. Value of (count_t) -1 means the
* @param pages Number of pages to invalidate. Value of (size_t) -1 means the
* whole TSB.
*/
void tsb_invalidate(as_t *as, uintptr_t page, count_t pages)
void tsb_invalidate(as_t *as, uintptr_t page, size_t pages)
{
index_t i0, i;
count_t cnt;
size_t i0;
size_t i;
size_t cnt;
ASSERT(as->arch.itsb && as->arch.dtsb);
63,7 → 64,7
i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
ASSERT(i0 < ITSB_ENTRY_COUNT && i0 < DTSB_ENTRY_COUNT);
 
if (pages == (count_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
if (pages == (size_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
cnt = ITSB_ENTRY_COUNT;
else
cnt = pages * 2;
81,11 → 82,11
* @param t Software PTE.
* @param index Zero if lower 8K-subpage, one if higher 8K subpage.
*/
void itsb_pte_copy(pte_t *t, index_t index)
void itsb_pte_copy(pte_t *t, size_t index)
{
as_t *as;
tsb_entry_t *tsb;
index_t entry;
size_t entry;
 
ASSERT(index <= 1);
112,9 → 113,9
tsb->data.value = 0;
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
tsb->data.cp = t->c;
tsb->data.p = t->k; /* p as privileged */
tsb->data.v = t->p;
tsb->data.cp = t->c; /* cp as cache in phys.-idxed, c as cacheable */
tsb->data.p = t->k; /* p as privileged, k as kernel */
tsb->data.v = t->p; /* v as valid, p as present */
write_barrier();
127,11 → 128,11
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the mapping is copied read-only.
*/
void dtsb_pte_copy(pte_t *t, index_t index, bool ro)
void dtsb_pte_copy(pte_t *t, size_t index, bool ro)
{
as_t *as;
tsb_entry_t *tsb;
index_t entry;
size_t entry;
ASSERT(index <= 1);
 
173,3 → 174,4
 
/** @}
*/
 
/branches/arm/kernel/arch/sparc64/src/mm/page.c
1,5 → 1,5
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64mm
/** @addtogroup sparc64mm
* @{
*/
/** @file
42,126 → 42,27
#include <align.h>
#include <config.h>
 
#ifdef CONFIG_SMP
/** Entries locked in DTLB of BSP.
*
* Application processors need to have the same locked entries in their DTLBs as
* the bootstrap processor.
*/
static struct {
uintptr_t virt_page;
uintptr_t phys_page;
int pagesize_code;
} bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT];
 
/** Number of entries in bsp_locked_dtlb_entry array. */
static count_t bsp_locked_dtlb_entries = 0;
#endif /* CONFIG_SMP */
 
/** Perform sparc64 specific initialization of paging. */
void page_arch_init(void)
{
if (config.cpu_active == 1) {
if (config.cpu_active == 1)
page_mapping_operations = &ht_mapping_operations;
} else {
 
#ifdef CONFIG_SMP
unsigned int i;
 
/*
* Copy locked DTLB entries from the BSP.
*/
for (i = 0; i < bsp_locked_dtlb_entries; i++) {
dtlb_insert_mapping(bsp_locked_dtlb_entry[i].virt_page,
bsp_locked_dtlb_entry[i].phys_page,
bsp_locked_dtlb_entry[i].pagesize_code, true,
false);
}
#endif
 
}
}
 
/** Map memory-mapped device into virtual memory.
*
* So far, only DTLB is used to map devices into memory. Chances are that there
* will be only a limited amount of devices that the kernel itself needs to
* lock in DTLB.
* We are currently using identity mapping for mapping device registers.
*
* @param physaddr Physical address of the page where the device is located.
* Must be at least page-aligned.
* @param size Size of the device's registers. Must not exceed 4M and must
* include extra space caused by the alignment.
* @param physaddr Physical address of the page where the device is
* located.
* @param size Size of the device's registers.
*
* @return Virtual address of the page where the device is mapped.
*
*/
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
unsigned int order;
unsigned int i;
 
ASSERT(config.cpu_active == 1);
 
struct {
int pagesize_code;
size_t increment;
count_t count;
} sizemap[] = {
{ PAGESIZE_8K, 0, 1 }, /* 8K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 2 }, /* 16K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 4 }, /* 32K */
{ PAGESIZE_64K, 0, 1}, /* 64K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 2 }, /* 128K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 4 }, /* 256K */
{ PAGESIZE_512K, 0, 1 }, /* 512K */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 2 }, /* 1M */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 4 }, /* 2M */
{ PAGESIZE_4M, 0, 1 }, /* 4M */
{ PAGESIZE_4M, 512 * MMU_PAGE_SIZE, 2 } /* 8M */
};
ASSERT(ALIGN_UP(physaddr, MMU_PAGE_SIZE) == physaddr);
ASSERT(size <= 8 * 1024 * 1024);
if (size <= MMU_FRAME_SIZE)
order = 0;
else
order = (fnzb64(size - 1) + 1) - MMU_FRAME_WIDTH;
 
/*
* Use virtual addresses that are beyond the limit of physical memory.
* Thus, the physical address space will not be wasted by holes created
* by frame_alloc().
*/
ASSERT(PA2KA(last_frame));
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame),
1 << (order + FRAME_WIDTH));
last_frame = ALIGN_UP(KA2PA(virtaddr) + size,
1 << (order + FRAME_WIDTH));
for (i = 0; i < sizemap[order].count; i++) {
/*
* First, insert the mapping into DTLB.
*/
dtlb_insert_mapping(virtaddr + i * sizemap[order].increment,
physaddr + i * sizemap[order].increment,
sizemap[order].pagesize_code, true, false);
#ifdef CONFIG_SMP
/*
* Second, save the information about the mapping for APs.
*/
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].virt_page =
virtaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].phys_page =
physaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].pagesize_code =
sizemap[order].pagesize_code;
bsp_locked_dtlb_entries++;
#endif
}
return virtaddr;
return PA2KA(physaddr);
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64mm
/** @addtogroup sparc64mm
* @{
*/
/** @file
79,7 → 79,8
*/
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
}
 
end_of_identity = PA2KA(last_frame);
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/mm/cache.S
47,45 → 47,3
retl
! beware SF Erratum #51, do not put the MEMBAR here
nop
 
/** Flush only D-cache lines of one virtual color.
*
* @param o0 Virtual color to be flushed.
*/
.global dcache_flush_color
dcache_flush_color:
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
set DCACHE_SIZE / 2, %g2
sllx %g2, %o0, %g2
sub %g2, DCACHE_LINE_SIZE, %g2
0: stxa %g0, [%g2] ASI_DCACHE_TAG
membar #Sync
subcc %g1, 1, %g1
bnz,pt %xcc, 0b
sub %g2, DCACHE_LINE_SIZE, %g2
retl
nop
 
/** Flush only D-cache lines of one virtual color and one tag.
*
* @param o0 Virtual color to lookup the tag.
* @param o1 Tag of the cachelines to be flushed.
*/
.global dcache_flush_tag
dcache_flush_tag:
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
set DCACHE_SIZE / 2, %g2
sllx %g2, %o0, %g2
sub %g2, DCACHE_LINE_SIZE, %g2
0: ldxa [%g2] ASI_DCACHE_TAG, %g3
srlx %g3, DCACHE_TAG_SHIFT, %g3
cmp %g3, %o1
bnz 1f
nop
stxa %g0, [%g2] ASI_DCACHE_TAG
membar #Sync
1: subcc %g1, 1, %g1
bnz,pt %xcc, 0b
sub %g2, DCACHE_LINE_SIZE, %g2
retl
nop
/branches/arm/kernel/arch/sparc64/src/drivers/fhc.c
45,6 → 45,7
#include <mm/slab.h>
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
#include <sysinfo/sysinfo.h>
 
fhc_t *central_fhc = NULL;
 
70,7 → 71,7
if (!prop || !prop->value)
return NULL;
count_t regs = prop->size / sizeof(ofw_central_reg_t);
size_t regs = prop->size / sizeof(ofw_central_reg_t);
if (regs + 1 < UART_IMAP_REG)
return NULL;
 
86,6 → 87,13
 
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size);
/*
* Set sysinfo data needed by the uspace FHC driver.
*/
sysinfo_set_item_val("fhc.uart.size", NULL, reg->size);
sysinfo_set_item_val("fhc.uart.physical", NULL, paddr);
sysinfo_set_item_val("kbd.cir.fhc", NULL, 1);
 
return fhc;
}
 
96,13 → 104,14
fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK;
break;
default:
panic("Unexpected INR (%d)\n", inr);
panic("Unexpected INR (%d).", inr);
break;
}
}
 
void fhc_clear_interrupt(fhc_t *fhc, int inr)
void fhc_clear_interrupt(void *fhcp, int inr)
{
fhc_t *fhc = (fhc_t *)fhcp;
ASSERT(fhc->uart_imap);
 
switch (inr) {
110,7 → 119,7
fhc->uart_imap[FHC_UART_ICLR] = 0;
break;
default:
panic("Unexpected INR (%d)\n", inr);
panic("Unexpected INR (%d).", inr);
break;
}
}
/branches/arm/kernel/arch/sparc64/src/drivers/pci.c
42,43 → 42,41
#include <arch/types.h>
#include <debug.h>
#include <print.h>
#include <func.h>
#include <string.h>
#include <arch/asm.h>
#include <sysinfo/sysinfo.h>
 
#define PCI_SABRE_REGS_REG 0
#define SABRE_INTERNAL_REG 0
#define PSYCHO_INTERNAL_REG 2
 
#define PCI_SABRE_IMAP_BASE 0x200
#define PCI_SABRE_ICLR_BASE 0x300
#define OBIO_IMR_BASE 0x200
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK))
 
#define PCI_PSYCHO_REGS_REG 2
#define OBIO_CIR_BASE 0x300
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK))
 
#define PCI_PSYCHO_IMAP_BASE 0x200
#define PCI_PSYCHO_ICLR_BASE 0x300
static void obio_enable_interrupt(pci_t *, int);
static void obio_clear_interrupt(pci_t *, int);
 
static pci_t *pci_sabre_init(ofw_tree_node_t *node);
static void pci_sabre_enable_interrupt(pci_t *pci, int inr);
static void pci_sabre_clear_interrupt(pci_t *pci, int inr);
static pci_t *pci_sabre_init(ofw_tree_node_t *);
static pci_t *pci_psycho_init(ofw_tree_node_t *);
 
static pci_t *pci_psycho_init(ofw_tree_node_t *node);
static void pci_psycho_enable_interrupt(pci_t *pci, int inr);
static void pci_psycho_clear_interrupt(pci_t *pci, int inr);
 
/** PCI operations for Sabre model. */
static pci_operations_t pci_sabre_ops = {
.enable_interrupt = pci_sabre_enable_interrupt,
.clear_interrupt = pci_sabre_clear_interrupt
.enable_interrupt = obio_enable_interrupt,
.clear_interrupt = obio_clear_interrupt
};
/** PCI operations for Psycho model. */
static pci_operations_t pci_psycho_ops = {
.enable_interrupt = pci_psycho_enable_interrupt,
.clear_interrupt = pci_psycho_clear_interrupt
.enable_interrupt = obio_enable_interrupt,
.clear_interrupt = obio_clear_interrupt
};
 
/** Initialize PCI controller (model Sabre).
*
* @param node OpenFirmware device tree node of the Sabre.
* @param node OpenFirmware device tree node of the Sabre.
*
* @return Address of the initialized PCI structure.
* @return Address of the initialized PCI structure.
*/
pci_t *pci_sabre_init(ofw_tree_node_t *node)
{
93,13 → 91,14
return NULL;
 
ofw_upa_reg_t *reg = prop->value;
count_t regs = prop->size / sizeof(ofw_upa_reg_t);
size_t regs = prop->size / sizeof(ofw_upa_reg_t);
 
if (regs < PCI_SABRE_REGS_REG + 1)
if (regs < SABRE_INTERNAL_REG + 1)
return NULL;
 
uintptr_t paddr;
if (!ofw_upa_apply_ranges(node->parent, &reg[PCI_SABRE_REGS_REG], &paddr))
if (!ofw_upa_apply_ranges(node->parent, &reg[SABRE_INTERNAL_REG],
&paddr))
return NULL;
 
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
108,8 → 107,14
 
pci->model = PCI_SABRE;
pci->op = &pci_sabre_ops;
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size);
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size);
 
/*
* Set sysinfo data needed by the uspace OBIO driver.
*/
sysinfo_set_item_val("obio.base.physical", NULL, paddr);
sysinfo_set_item_val("kbd.cir.obio", NULL, 1);
 
return pci;
}
 
116,9 → 121,9
 
/** Initialize the Psycho PCI controller.
*
* @param node OpenFirmware device tree node of the Psycho.
* @param node OpenFirmware device tree node of the Psycho.
*
* @return Address of the initialized PCI structure.
* @return Address of the initialized PCI structure.
*/
pci_t *pci_psycho_init(ofw_tree_node_t *node)
{
133,13 → 138,14
return NULL;
 
ofw_upa_reg_t *reg = prop->value;
count_t regs = prop->size / sizeof(ofw_upa_reg_t);
size_t regs = prop->size / sizeof(ofw_upa_reg_t);
 
if (regs < PCI_PSYCHO_REGS_REG + 1)
if (regs < PSYCHO_INTERNAL_REG + 1)
return NULL;
 
uintptr_t paddr;
if (!ofw_upa_apply_ranges(node->parent, &reg[PCI_PSYCHO_REGS_REG], &paddr))
if (!ofw_upa_apply_ranges(node->parent, &reg[PSYCHO_INTERNAL_REG],
&paddr))
return NULL;
 
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
148,31 → 154,27
 
pci->model = PCI_PSYCHO;
pci->op = &pci_psycho_ops;
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_PSYCHO_REGS_REG].size);
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size);
 
/*
* Set sysinfo data needed by the uspace OBIO driver.
*/
sysinfo_set_item_val("obio.base.physical", NULL, paddr);
sysinfo_set_item_val("kbd.cir.obio", NULL, 1);
 
return pci;
}
 
void pci_sabre_enable_interrupt(pci_t *pci, int inr)
void obio_enable_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK;
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK;
}
 
void pci_sabre_clear_interrupt(pci_t *pci, int inr)
void obio_clear_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0;
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */
}
 
void pci_psycho_enable_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_PSYCHO_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK;
}
 
void pci_psycho_clear_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_PSYCHO_ICLR_BASE + (inr & INO_MASK)] = 0;
}
 
/** Initialize PCI controller. */
pci_t *pci_init(ofw_tree_node_t *node)
{
181,7 → 183,7
/*
* First, verify this is a PCI node.
*/
ASSERT(strcmp(ofw_tree_node_name(node), "pci") == 0);
ASSERT(str_cmp(ofw_tree_node_name(node), "pci") == 0);
 
/*
* Determine PCI controller model.
190,13 → 192,13
if (!prop || !prop->value)
return NULL;
if (strcmp(prop->value, "SUNW,sabre") == 0) {
if (str_cmp(prop->value, "SUNW,sabre") == 0) {
/*
* PCI controller Sabre.
* This model is found on UltraSPARC IIi based machines.
*/
return pci_sabre_init(node);
} else if (strcmp(prop->value, "SUNW,psycho") == 0) {
} else if (str_cmp(prop->value, "SUNW,psycho") == 0) {
/*
* PCI controller Psycho.
* Used on UltraSPARC II based processors, for instance,
215,14 → 217,14
 
void pci_enable_interrupt(pci_t *pci, int inr)
{
ASSERT(pci->model);
ASSERT(pci->op && pci->op->enable_interrupt);
pci->op->enable_interrupt(pci, inr);
}
 
void pci_clear_interrupt(pci_t *pci, int inr)
void pci_clear_interrupt(void *pcip, int inr)
{
ASSERT(pci->model);
pci_t *pci = (pci_t *)pcip;
 
ASSERT(pci->op && pci->op->clear_interrupt);
pci->op->clear_interrupt(pci, inr);
}
/branches/arm/kernel/arch/sparc64/src/drivers/sgcn.c
0,0 → 1,387
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup sparc64
* @{
*/
/**
* @file
* @brief SGCN driver.
*/
 
#include <arch.h>
#include <arch/drivers/sgcn.h>
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
#include <debug.h>
#include <string.h>
#include <print.h>
#include <mm/page.h>
#include <proc/thread.h>
#include <console/chardev.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <synch/spinlock.h>
 
#define POLL_INTERVAL 10000
 
/*
* Physical address at which the SBBC starts. This value has been obtained
* by inspecting (using Simics) memory accesses made by OBP. It is valid
* for the Simics-simulated Serengeti machine. The author of this code is
* not sure whether this value is valid generally.
*/
#define SBBC_START 0x63000000000
 
/* offset of SRAM within the SBBC memory */
#define SBBC_SRAM_OFFSET 0x900000
 
/* size (in bytes) of the physical memory area which will be mapped */
#define MAPPED_AREA_SIZE (128 * 1024)
 
/* magic string contained at the beginning of SRAM */
#define SRAM_TOC_MAGIC "TOCSRAM"
 
/*
* Key into the SRAM table of contents which identifies the entry
* describing the OBP console buffer. It is worth mentioning
* that the OBP console buffer is not the only console buffer
* which can be used. It is, however, used because when the kernel
* is running, the OBP buffer is not used by OBP any more but OBP
* has already made necessary arrangements so that the output will
* be read from the OBP buffer and input will go to the OBP buffer.
* Therefore HelenOS needs to make no such arrangements any more.
*/
#define CONSOLE_KEY "OBPCONS"
 
/* magic string contained at the beginning of the console buffer */
#define SGCN_BUFFER_MAGIC "CON"
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the SRAM beginning.
*/
#define SRAM(type, offset) ((type *) (sram_begin + (offset)))
 
/* Returns a pointer to the SRAM table of contents. */
#define SRAM_TOC (SRAM(iosram_toc_t, 0))
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sgcn_buffer_begin + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
/** starting address of SRAM, will be set by the init_sram_begin function */
static uintptr_t sram_begin;
 
/**
* starting address of the SGCN buffer, will be set by the
* init_sgcn_buffer_begin function
*/
static uintptr_t sgcn_buffer_begin;
 
/* true iff the kernel driver should ignore pressed keys */
static bool kbd_disabled;
 
/*
* Ensures that writing to the buffer and consequent update of the write pointer
* are together one atomic operation.
*/
SPINLOCK_INITIALIZE(sgcn_output_lock);
 
/*
* Prevents the input buffer read/write pointers from getting to inconsistent
* state.
*/
SPINLOCK_INITIALIZE(sgcn_input_lock);
 
 
/* functions referenced from definitions of I/O operations structures */
static void sgcn_putchar(outdev_t *, const wchar_t, bool);
 
/** SGCN output device operations */
static outdev_operations_t sgcnout_ops = {
.write = sgcn_putchar
};
 
static outdev_t sgcnout; /**< SGCN output device. */
 
/**
* Set some sysinfo values (SRAM address and SRAM size).
*/
static void register_sram(uintptr_t sram_begin_physical)
{
sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE);
sysinfo_set_item_val("sram.address.physical", NULL,
sram_begin_physical);
}
 
/**
* Initializes the starting address of SRAM.
*
* The SRAM starts 0x900000 + C bytes behind the SBBC start in the
* physical memory, where C is the value read from the "iosram-toc"
* property of the "/chosen" OBP node. The sram_begin variable will
* be set to the virtual address which maps to the SRAM physical
* address.
*/
static void init_sram_begin(void)
{
ofw_tree_node_t *chosen;
ofw_tree_property_t *iosram_toc;
uintptr_t sram_begin_physical;
 
chosen = ofw_tree_lookup("/chosen");
if (!chosen)
panic("Cannot find '/chosen'.");
 
iosram_toc = ofw_tree_getprop(chosen, "iosram-toc");
if (!iosram_toc)
panic("Cannot find property 'iosram-toc'.");
if (!iosram_toc->value)
panic("Cannot find SRAM TOC.");
 
sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
+ *((uint32_t *) iosram_toc->value);
sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
register_sram(sram_begin_physical);
}
 
/**
* Initializes the starting address of the SGCN buffer.
*
* The offset of the SGCN buffer within SRAM is obtained from the
* SRAM table of contents. The table of contents contains
* information about several buffers, among which there is an OBP
* console buffer - this one will be used as the SGCN buffer.
*
* This function also writes the offset of the SGCN buffer within SRAM
* under the sram.buffer.offset sysinfo key.
*/
static void sgcn_buffer_begin_init(void)
{
static bool initialized;
if (initialized)
return;
 
init_sram_begin();
ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
/* lookup TOC entry with the correct key */
uint32_t i;
for (i = 0; i < MAX_TOC_ENTRIES; i++) {
if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
break;
}
ASSERT(i < MAX_TOC_ENTRIES);
sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
sysinfo_set_item_val("sram.buffer.offset", NULL,
SRAM_TOC->keys[i].offset);
initialized = true;
}
 
/**
* Writes a single character to the SGCN (circular) output buffer
* and updates the output write pointer so that SGCN gets to know
* that the character has been written.
*/
static void sgcn_do_putchar(const char c)
{
uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
uint32_t end = SGCN_BUFFER_HEADER->out_end;
uint32_t size = end - begin;
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
 
/*
* Write the character and increment the write pointer modulo the
* output buffer size. Note that if we are to rewrite a character
* which has not been read by the SGCN controller yet (i.e. the output
* buffer is full), we need to wait until the controller reads some more
* characters. We wait actively, which means that all threads waiting
* for the lock are blocked. However, this situation is
* 1) rare - the output buffer is big, so filling the whole
* output buffer is improbable
* 2) short-lasting - it will take the controller only a fraction
* of millisecond to pick the unread characters up
* 3) not serious - the blocked threads are those that print something
* to user console, which is not a time-critical operation
*/
uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
while (*out_rdptr_ptr == new_wrptr)
;
*buf_ptr = c;
*out_wrptr_ptr = new_wrptr;
}
 
/**
* SGCN output operation. Prints a single character to the SGCN. Newline
* character is converted to CRLF.
*/
static void sgcn_putchar(outdev_t *od, const wchar_t ch, bool silent)
{
if (!silent) {
spinlock_lock(&sgcn_output_lock);
if (ascii_check(ch)) {
if (ch == '\n')
sgcn_do_putchar('\r');
sgcn_do_putchar(ch);
} else
sgcn_do_putchar(U_SPECIAL);
spinlock_unlock(&sgcn_output_lock);
}
}
 
/**
* Grabs the input for kernel.
*/
void sgcn_grab(void)
{
kbd_disabled = false;
}
 
/**
* Releases the input so that userspace can use it.
*/
void sgcn_release(void)
{
kbd_disabled = true;
}
 
/**
* Function regularly called by the keyboard polling thread. Finds out whether
* there are some unread characters in the input queue. If so, it picks them up
* and sends them to the upper layers of HelenOS.
*/
static void sgcn_poll(sgcn_instance_t *instance)
{
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
 
if (kbd_disabled)
return;
 
spinlock_lock(&sgcn_input_lock);
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
while (*in_rdptr_ptr != *in_wrptr_ptr) {
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
char c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
indev_push_character(instance->srlnin, c);
}
 
spinlock_unlock(&sgcn_input_lock);
}
 
/**
* Polling thread function.
*/
static void ksgcnpoll(void *instance) {
while (1) {
if (!silent)
sgcn_poll(instance);
thread_usleep(POLL_INTERVAL);
}
}
 
/**
* A public function which initializes input from the Serengeti console.
*/
sgcn_instance_t *sgcnin_init(void)
{
sgcn_buffer_begin_init();
sgcn_instance_t *instance =
malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
if (instance) {
instance->srlnin = NULL;
instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
"ksgcnpoll", true);
if (!instance->thread) {
free(instance);
return NULL;
}
}
return instance;
}
 
void sgcnin_wire(sgcn_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
 
instance->srlnin = srlnin;
thread_ready(instance->thread);
 
sysinfo_set_item_val("kbd", NULL, true);
}
 
/**
* A public function which initializes output to the Serengeti console.
*/
void sgcnout_init(void)
{
sgcn_buffer_begin_init();
 
sysinfo_set_item_val("fb.kind", NULL, 4);
 
outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);
stdout = &sgcnout;
}
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/drivers/kbd.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
34,99 → 34,160
 
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
 
#ifdef CONFIG_SUN_KBD
#include <genarch/kbrd/kbrd.h>
#endif
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#include <genarch/drivers/z8530/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#include <genarch/drivers/ns16550/ns16550.h>
#endif
#include <ddi/device.h>
 
#include <console/console.h>
#include <ddi/irq.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <align.h>
#include <func.h>
#include <string.h>
#include <print.h>
#include <sysinfo/sysinfo.h>
 
kbd_type_t kbd_type = KBD_UNKNOWN;
#ifdef CONFIG_SUN_KBD
 
/** Initialize keyboard.
*
* Traverse OpenFirmware device tree in order to find necessary
* info about the keyboard device.
*
* @param node Keyboard device node.
*/
void kbd_init(ofw_tree_node_t *node)
#ifdef CONFIG_Z8530
 
static bool kbd_z8530_init(ofw_tree_node_t *node)
{
size_t offset;
uintptr_t aligned_addr;
ofw_tree_property_t *prop;
const char *name;
const char *name = ofw_tree_node_name(node);
name = ofw_tree_node_name(node);
if (str_cmp(name, "zs") != 0)
return false;
/*
* Determine keyboard serial controller type.
* Read 'interrupts' property.
*/
if (strcmp(name, "zs") == 0)
kbd_type = KBD_Z8530;
else if (strcmp(name, "su") == 0)
kbd_type = KBD_NS16550;
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
if ((!prop) || (!prop->value)) {
printf("z8530: Unable to find interrupts property\n");
return false;
}
if (kbd_type == KBD_UNKNOWN) {
printf("Unknown keyboard device.\n");
return;
uint32_t interrupts = *((uint32_t *) prop->value);
/*
* Read 'reg' property.
*/
prop = ofw_tree_getprop(node, "reg");
if ((!prop) || (!prop->value)) {
printf("z8530: Unable to find reg property\n");
return false;
}
size_t size = ((ofw_fhc_reg_t *) prop->value)->size;
uintptr_t pa;
if (!ofw_fhc_apply_ranges(node->parent,
((ofw_fhc_reg_t *) prop->value), &pa)) {
printf("z8530: Failed to determine address\n");
return false;
}
inr_t inr;
cir_t cir;
void *cir_arg;
if (!ofw_fhc_map_interrupt(node->parent,
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,
&cir_arg)) {
printf("z8530: Failed to determine interrupt\n");
return false;
}
/*
* Read 'interrupts' property.
* We need to pass aligned address to hw_map().
* However, the physical keyboard address can
* be pretty much unaligned, depending on the
* underlying controller.
*/
uint32_t interrupts;
prop = ofw_tree_getprop(node, "interrupts");
if (!prop || !prop->value)
panic("Can't find \"interrupts\" property.\n");
interrupts = *((uint32_t *) prop->value);
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
z8530_t *z8530 = (z8530_t *)
(hw_map(aligned_addr, offset + size) + offset);
z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg);
if (z8530_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
z8530_wire(z8530_instance, kbrd);
}
}
/*
* This is the necessary evil until the userspace drivers are
* entirely self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) z8530);
sysinfo_set_item_val("kbd.address.physical", NULL, pa);
sysinfo_set_item_val("kbd.type.z8530", NULL, true);
return true;
}
 
#endif /* CONFIG_Z8530 */
 
#ifdef CONFIG_NS16550
 
static bool kbd_ns16550_init(ofw_tree_node_t *node)
{
const char *name = ofw_tree_node_name(node);
if (str_cmp(name, "su") != 0)
return false;
/*
* Read 'interrupts' property.
*/
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
if ((!prop) || (!prop->value)) {
printf("ns16550: Unable to find interrupts property\n");
return false;
}
uint32_t interrupts = *((uint32_t *) prop->value);
/*
* Read 'reg' property.
*/
prop = ofw_tree_getprop(node, "reg");
if (!prop || !prop->value)
panic("Can't find \"reg\" property.\n");
if ((!prop) || (!prop->value)) {
printf("ns16550: Unable to find reg property\n");
return false;
}
size_t size = ((ofw_ebus_reg_t *) prop->value)->size;
uintptr_t pa;
size_t size;
if (!ofw_ebus_apply_ranges(node->parent,
((ofw_ebus_reg_t *) prop->value), &pa)) {
printf("ns16550: Failed to determine address\n");
return false;
}
inr_t inr;
devno_t devno = device_assign_devno();
switch (kbd_type) {
case KBD_Z8530:
size = ((ofw_fhc_reg_t *) prop->value)->size;
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
printf("Failed to determine keyboard interrupt.\n");
return;
}
break;
case KBD_NS16550:
size = ((ofw_ebus_reg_t *) prop->value)->size;
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
printf("Failed to determine keyboard interrupt.\n");
return;
};
break;
 
default:
panic("Unexpected type.\n");
cir_t cir;
void *cir_arg;
if (!ofw_ebus_map_interrupt(node->parent,
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
&cir_arg)) {
printf("ns16550: Failed to determine interrupt\n");
return false;
}
/*
135,25 → 196,58
* be pretty much unaligned, depending on the
* underlying controller.
*/
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
offset = pa - aligned_addr;
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
ns16550_t *ns16550 = (ns16550_t *)
(hw_map(aligned_addr, offset + size) + offset);
ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir, cir_arg);
if (ns16550_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
ns16550_wire(ns16550_instance, kbrd);
}
}
/*
* This is the necessary evil until the userspace drivers are
* entirely self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) ns16550);
sysinfo_set_item_val("kbd.address.physical", NULL, pa);
sysinfo_set_item_val("kbd.type.ns16550", NULL, true);
return true;
}
 
switch (kbd_type) {
#endif /* CONFIG_NS16550 */
 
/** Initialize keyboard.
*
* Traverse OpenFirmware device tree in order to find necessary
* info about the keyboard device.
*
* @param node Keyboard device node.
*
*/
void kbd_init(ofw_tree_node_t *node)
{
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_init(devno, inr, vaddr);
break;
kbd_z8530_init(node);
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_init(devno, inr, vaddr);
break;
kbd_ns16550_init(node);
#endif
default:
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n");
}
}
 
#endif /* CONFIG_SUN_KBD */
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/drivers/scr.c
37,7 → 37,7
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <arch/types.h>
#include <func.h>
#include <string.h>
#include <align.h>
#include <print.h>
 
55,23 → 55,30
void scr_init(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
ofw_pci_reg_t *pci_reg;
ofw_pci_reg_t pci_abs_reg;
ofw_upa_reg_t *upa_reg;
ofw_sbus_reg_t *sbus_reg;
const char *name;
name = ofw_tree_node_name(node);
if (strcmp(name, "SUNW,m64B") == 0)
if (str_cmp(name, "SUNW,m64B") == 0)
scr_type = SCR_ATYFB;
else if (strcmp(name, "SUNW,ffb") == 0)
else if (str_cmp(name, "SUNW,XVR-100") == 0)
scr_type = SCR_XVR;
else if (str_cmp(name, "SUNW,ffb") == 0)
scr_type = SCR_FFB;
else if (strcmp(name, "cgsix") == 0)
else if (str_cmp(name, "cgsix") == 0)
scr_type = SCR_CGSIX;
if (scr_type == SCR_UNKNOWN) {
printf("Unknown keyboard device.\n");
printf("Unknown screen device.\n");
return;
}
uintptr_t fb_addr;
unsigned int fb_offset = 0;
uint32_t fb_width = 0;
uint32_t fb_height = 0;
uint32_t fb_depth = 0;
97,7 → 104,7
 
prop = ofw_tree_getprop(node, "reg");
if (!prop)
panic("Can't find \"reg\" property.\n");
panic("Cannot find 'reg' property.");
 
switch (scr_type) {
case SCR_ATYFB:
106,15 → 113,15
return;
}
ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1];
ofw_pci_reg_t abs_reg;
pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) {
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
printf("Failed to absolutize fb register.\n");
return;
}
if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) {
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
&fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
142,12 → 149,56
}
break;
case SCR_XVR:
if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
printf("Too few screen registers.\n");
return;
}
pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
printf("Failed to absolutize fb register.\n");
return;
}
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
&fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
 
fb_offset = 4 * 0x2000;
 
switch (fb_depth) {
case 8:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_INDIRECT_8;
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_0_8_8_8;
break;
default:
printf("Unsupported bits per pixel.\n");
return;
}
break;
case SCR_FFB:
fb_scanline = 8192;
visual = VISUAL_BGR_0_8_8_8;
 
ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
if (!ofw_upa_apply_ranges(node->parent, reg, &fb_addr)) {
upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
164,8 → 215,8
return;
}
ofw_sbus_reg_t *cg6_reg = &((ofw_sbus_reg_t *) prop->value)[0];
if (!ofw_sbus_apply_ranges(node->parent, cg6_reg, &fb_addr)) {
sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
172,11 → 223,24
break;
default:
panic("Unexpected type.\n");
panic("Unexpected type.");
}
 
fb_init(fb_addr, fb_width, fb_height, fb_scanline, visual);
fb_properties_t props = {
.addr = fb_addr,
.offset = fb_offset,
.x = fb_width,
.y = fb_height,
.scan = fb_scanline,
.visual = visual,
};
fb_init(&props);
}
 
void scr_redraw(void)
{
fb_redraw();
}
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/drivers/tick.c
45,11 → 45,12
 
#define TICK_RESTART_TIME 50 /* Worst case estimate. */
 
/** Initialize tick interrupt. */
/** Initialize tick and stick interrupt. */
void tick_init(void)
{
/* initialize TICK interrupt */
tick_compare_reg_t compare;
 
interrupt_register(14, "tick_int", tick_interrupt);
compare.int_dis = false;
compare.tick_cmpr = CPU->arch.clock_frequency / HZ;
56,6 → 57,21
CPU->arch.next_tick_cmpr = compare.tick_cmpr;
tick_compare_write(compare.value);
tick_write(0);
 
#if defined (US3)
/* disable STICK interrupts and clear any pending ones */
tick_compare_reg_t stick_compare;
softint_reg_t clear;
 
stick_compare.value = stick_compare_read();
stick_compare.int_dis = true;
stick_compare.tick_cmpr = 0;
stick_compare_write(stick_compare.value);
 
clear.value = 0;
clear.stick_int = 1;
clear_softint_write(clear.value);
#endif
}
 
/** Process tick interrupt.
67,7 → 83,7
{
softint_reg_t softint, clear;
uint64_t drift;
 
softint.value = softint_read();
/*
/branches/arm/kernel/arch/sparc64/src/dummy.s
42,5 → 42,5
 
.global cpu_halt
cpu_halt:
b cpu_halt
ba %xcc, cpu_halt
nop
/branches/arm/kernel/arch/sparc64/src/trap/trap_table.S
341,7 → 341,7
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
.global trap_instruction_\cur\()_tl0
trap_instruction_\cur\()_tl0:
ba trap_instruction_handler
ba %xcc, trap_instruction_handler
mov \cur, %g2
.endr
 
478,9 → 478,9
*/
rdpr %tl, %g3
cmp %g3, 1
be 1f
be %xcc, 1f
nop
0: ba 0b ! this is for debugging, if we ever get here
0: ba %xcc, 0b ! this is for debugging, if we ever get here
nop ! it will be easy to find
 
1:
499,7 → 499,7
wrpr %g4, 0, %cwp ! resynchronize CWP
 
andcc %g3, TSTATE_PRIV_BIT, %g0 ! if this trap came from the privileged mode...
bnz 0f ! ...skip setting of kernel stack and primary context
bnz %xcc, 0f ! ...skip setting of kernel stack and primary context
nop
.endif
545,7 → 545,7
flush %l0
 
.if NOT(\is_syscall)
ba 1f
ba %xcc, 1f
nop
0:
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
606,10 → 606,10
add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
.else
/*
* Call the higher-level syscall handler.
* Call the higher-level syscall handler and enable interrupts.
*/
call syscall_handler
nop
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate
mov %o0, %i0 ! copy the value returned by the syscall
.endif
 
672,7 → 672,7
and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS
rdpr %cwp, %l1
cmp %l0, %l1
bz 0f ! CWP is ok
bz %xcc, 0f ! CWP is ok
nop
 
/*
712,7 → 712,7
.if NOT(\is_syscall)
rdpr %tstate, %g1
andcc %g1, TSTATE_PRIV_BIT, %g0 ! if we are not returning to userspace...,
bnz 1f ! ...skip restoring userspace windows
bnz %xcc, 1f ! ...skip restoring userspace windows
nop
.endif
 
748,9 → 748,8
* Fill all windows stored in the buffer.
*/
clr %g4
set PAGE_SIZE - 1, %g5
0: andcc %g7, %g5, %g0 ! PAGE_SIZE alignment check
bz 0f ! %g7 is page-aligned, no more windows to refill
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check
bz %xcc, 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
nop
 
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
775,7 → 774,7
and %g3, NWINDOWS - 1, %g3
wrpr %g3, 0, %cwp ! switch to the preceeding window
 
ba 0b
ba %xcc, 0b
inc %g4
 
0:
786,7 → 785,7
wrpr %g1, 0, %cwp
add %g4, %g2, %g2
cmp %g2, NWINDOWS - 2
bg 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly
bg %xcc, 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly
mov NWINDOWS - 2, %g1 ! use dealy slot for both cases
sub %g1, %g2, %g1
/branches/arm/kernel/arch/sparc64/src/trap/exception.c
40,62 → 40,67
#include <arch/asm.h>
#include <arch/register.h>
#include <debug.h>
#include <print.h>
#include <symtab.h>
#include <print.h>
 
void dump_istate(istate_t *istate)
{
char *tpcs, *tnpcs;
 
tpcs = symtab_fmt_name_lookup(istate->tpc);
tnpcs = symtab_fmt_name_lookup(istate->tnpc);
 
printf("TSTATE=%#" PRIx64 "\n", istate->tstate);
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, get_symtab_entry(istate->tpc));
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc));
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, tpcs);
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, tnpcs);
}
 
/** Handle instruction_access_exception. (0x8) */
void instruction_access_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle instruction_access_error. (0xa) */
void instruction_access_error(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle illegal_instruction. (0x10) */
void illegal_instruction(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle privileged_opcode. (0x11) */
void privileged_opcode(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle unimplemented_LDD. (0x12) */
void unimplemented_LDD(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle unimplemented_STD. (0x13) */
void unimplemented_STD(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle fp_disabled. (0x20) */
113,9 → 118,9
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
#endif
}
 
122,98 → 127,98
/** Handle fp_exception_ieee_754. (0x21) */
void fp_exception_ieee_754(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle fp_exception_other. (0x22) */
void fp_exception_other(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle tag_overflow. (0x23) */
void tag_overflow(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle division_by_zero. (0x28) */
void division_by_zero(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle data_access_exception. (0x30) */
void data_access_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
dump_sfsr_and_sfar();
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle data_access_error. (0x32) */
void data_access_error(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle mem_address_not_aligned. (0x34) */
void mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle LDDF_mem_address_not_aligned. (0x35) */
void LDDF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle STDF_mem_address_not_aligned. (0x36) */
void STDF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle privileged_action. (0x37) */
void privileged_action(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle LDQF_mem_address_not_aligned. (0x38) */
void LDQF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle STQF_mem_address_not_aligned. (0x39) */
void STQF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/trap/interrupt.c
67,11 → 67,19
*/
void interrupt(int n, istate_t *istate)
{
uint64_t status;
uint64_t intrcv;
uint64_t data0;
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
if (status & (!INTR_DISPATCH_STATUS_BUSY))
panic("Interrupt Dispatch Status busy bit not set.");
 
intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
#if defined (US)
data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
#elif defined (US3)
data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
#endif
 
irq_t *irq = irq_dispatch_and_lock(data0);
if (irq) {
78,7 → 86,13
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
irq->handler(irq);
/*
* See if there is a clear-interrupt-routine and call it.
*/
if (irq->cir) {
irq->cir(irq->cir_arg, irq->inr);
}
spinlock_unlock(&irq->lock);
} else if (data0 > config.base) {
/*
98,7 → 112,7
*/
#ifdef CONFIG_DEBUG
printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
#endif
}
 
/branches/arm/kernel/arch/sparc64/src/start.S
27,6 → 27,7
#
 
#include <arch/arch.h>
#include <arch/cpu.h>
#include <arch/regdef.h>
#include <arch/boot/boot.h>
#include <arch/stack.h>
47,6 → 48,16
#define BSP_FLAG 1
 
/*
* 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on
* a given processor.
*/
#if defined (US)
#define PHYSMEM_ADDR_SIZE 41
#elif defined (US3)
#define PHYSMEM_ADDR_SIZE 43
#endif
 
/*
* Here is where the kernel is passed control from the boot loader.
*
* The registers are expected to be in this state:
67,11 → 78,13
and %o0, %l0, %l7 ! l7 <= bootstrap processor?
andn %o0, %l0, %l6 ! l6 <= start of physical memory
 
! Get bits 40:13 of physmem_base.
! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
srlx %l6, 13, %l5
sllx %l5, 13 + (63 - 40), %l5
srlx %l5, 63 - 40, %l5 ! l5 <= physmem_base[40:13]
! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5
 
/*
* Setup basic runtime environment.
*/
83,6 → 96,8
! consistent
wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window
! traps for kernel
wrpr %g0, 0, %wstate ! use default spill/fill trap
 
wrpr %g0, 0, %tl ! TL = 0, primary context
! register is used
244,7 → 259,8
 
/*
* Precompute kernel 8K TLB data template.
* %l5 contains starting physical address bits [40:13]
* %l5 contains starting physical address
* bits [(PHYSMEM_ADDR_SIZE - 1):13]
*/
sethi %hi(kernel_8k_tlb_data_template), %l4
ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3
278,19 → 294,36
/* Not reached. */
 
0:
ba 0b
ba %xcc, 0b
nop
 
 
1:
#ifdef CONFIG_SMP
/*
* Determine the width of the MID and save its mask to %g3. The width
* is
* * 5 for US and US-IIIi,
* * 10 for US3 except US-IIIi.
*/
#if defined(US)
mov 0x1f, %g3
#elif defined(US3)
mov 0x3ff, %g3
rdpr %ver, %g2
sllx %g2, 16, %g2
srlx %g2, 48, %g2
cmp %g2, IMPL_ULTRASPARCIII_I
move %xcc, 0x1f, %g3
#endif
 
/*
* Read MID from the processor.
*/
1:
ldxa [%g0] ASI_UPA_CONFIG, %g1
srlx %g1, UPA_CONFIG_MID_SHIFT, %g1
and %g1, UPA_CONFIG_MID_MASK, %g1
ldxa [%g0] ASI_ICBUS_CONFIG, %g1
srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1
and %g1, %g3, %g1
 
#ifdef CONFIG_SMP
/*
* Active loop for APs until the BSP picks them up. A processor cannot
* leave the loop until the global variable 'waking_up_mid' equals its
300,7 → 333,7
2:
ldx [%g2], %g3
cmp %g3, %g1
bne 2b
bne %xcc, 2b
nop
 
/*
319,7 → 352,7
#endif
0:
ba 0b
ba %xcc, 0b
nop
 
 
348,10 → 381,31
.quad 0
 
/*
* This variable is used by the fast_data_MMU_miss trap handler. In runtime, it
* is further modified to reflect the starting address of physical memory.
* The fast_data_access_mmu_miss_data_hi label and the end_of_identity and
* kernel_8k_tlb_data_template variables are meant to stay together,
* aligned on 16B boundary.
*/
.global fast_data_access_mmu_miss_data_hi
.global end_of_identity
.global kernel_8k_tlb_data_template
 
.align 16
/*
* This label is used by the fast_data_access_MMU_miss trap handler.
*/
fast_data_access_mmu_miss_data_hi:
/*
* This variable is used by the fast_data_access_MMU_miss trap handler.
* In runtime, it is modified to contain the address of the end of physical
* memory.
*/
end_of_identity:
.quad -1
/*
* This variable is used by the fast_data_access_MMU_miss trap handler.
* In runtime, it is further modified to reflect the starting address of
* physical memory.
*/
kernel_8k_tlb_data_template:
#ifdef CONFIG_VIRT_IDX_DCACHE
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
/branches/arm/kernel/arch/sparc64/src/console.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
37,14 → 37,8
 
#include <arch/drivers/scr.h>
#include <arch/drivers/kbd.h>
 
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#endif
 
#include <arch/drivers/sgcn.h>
#include <genarch/srln/srln.h>
#include <console/chardev.h>
#include <console/console.h>
#include <arch/asm.h>
54,92 → 48,101
#include <genarch/ofw/ofw_tree.h>
#include <arch.h>
#include <panic.h>
#include <string.h>
#include <print.h>
 
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */
 
/** Initialize kernel console to use framebuffer and keyboard directly. */
void standalone_sparc64_console_init(void)
/**
* Initialize kernel console to use framebuffer and keyboard directly.
* Called on UltraSPARC machines with standard keyboard and framebuffer.
*
* @param aliases the "/aliases" OBP node
*/
static void standard_console_init(ofw_tree_node_t *aliases)
{
stdin = NULL;
 
ofw_tree_node_t *aliases;
ofw_tree_property_t *prop;
ofw_tree_node_t *screen;
ofw_tree_node_t *keyboard;
#ifdef CONFIG_FB
ofw_tree_property_t *prop_scr = ofw_tree_getprop(aliases, "screen");
if (!prop_scr)
panic("Cannot find property 'screen'.");
if (!prop_scr->value)
panic("Cannot find screen alias.");
ofw_tree_node_t *screen = ofw_tree_lookup(prop_scr->value);
if (!screen)
panic("Cannot find %s.", prop_scr->value);
aliases = ofw_tree_lookup("/aliases");
if (!aliases)
panic("Can't find /aliases.\n");
prop = ofw_tree_getprop(aliases, "screen");
if (!prop)
panic("Can't find property \"screen\".\n");
if (!prop->value)
panic("Can't find screen alias.\n");
screen = ofw_tree_lookup(prop->value);
if (!screen)
panic("Can't find %s\n", prop->value);
 
scr_init(screen);
#endif
 
prop = ofw_tree_getprop(aliases, "keyboard");
if (!prop)
panic("Can't find property \"keyboard\".\n");
if (!prop->value)
panic("Can't find keyboard alias.\n");
keyboard = ofw_tree_lookup(prop->value);
#ifdef CONFIG_SUN_KBD
ofw_tree_property_t *prop_kbd = ofw_tree_getprop(aliases, "keyboard");
if (!prop_kbd)
panic("Cannot find property 'keyboard'.");
if (!prop_kbd->value)
panic("Cannot find keyboard alias.");
ofw_tree_node_t *keyboard = ofw_tree_lookup(prop_kbd->value);
if (!keyboard)
panic("Can't find %s\n", prop->value);
 
panic("Cannot find %s.", prop_kbd->value);
kbd_init(keyboard);
#endif
}
 
/** Kernel thread for polling keyboard.
*
* @param arg Ignored.
*/
void kkbdpoll(void *arg)
/** Initilize I/O on the Serengeti machine. */
static void serengeti_init(void)
{
thread_detach(THREAD);
 
#ifdef CONFIG_Z8530
if (kbd_type == KBD_Z8530) {
/*
* The z8530 driver is interrupt-driven.
*/
return;
#ifdef CONFIG_SGCN_KBD
sgcn_instance_t *sgcn_instance = sgcnin_init();
if (sgcn_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
sgcnin_wire(sgcn_instance, srln);
}
}
#endif
#ifdef CONFIG_SGCN_PRN
sgcnout_init();
#endif
}
 
while (1) {
#ifdef CONFIG_NS16550
if (kbd_type == KBD_NS16550)
ns16550_poll();
#endif
thread_usleep(KEYBOARD_POLL_PAUSE);
/**
* Initialize input/output. Auto-detects the type of machine
* and calls the appropriate I/O init routine.
*/
void standalone_sparc64_console_init(void)
{
ofw_tree_node_t *aliases;
ofw_tree_property_t *prop;
aliases = ofw_tree_lookup("/aliases");
if (!aliases)
panic("Cannot find '/aliases'.");
/* "def-cn" = "default console" */
prop = ofw_tree_getprop(aliases, "def-cn");
if ((!prop) || (!prop->value) || (str_cmp(prop->value, "/sgcn") != 0)) {
standard_console_init(aliases);
} else {
serengeti_init();
}
}
 
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_grab();
break;
#ifdef CONFIG_FB
scr_redraw();
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_grab();
break;
#ifdef CONFIG_SGCN_KBD
sgcn_grab();
#endif
default:
break;
}
}
 
/** Return console to userspace
147,20 → 150,9
*/
void arch_release_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_release();
break;
#ifdef CONFIG_SGCN_KBD
sgcn_release();
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_release();
break;
#endif
default:
break;
}
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/sparc64.c
37,7 → 37,6
#include <config.h>
#include <arch/trap/trap.h>
#include <arch/console.h>
#include <proc/thread.h>
#include <console/console.h>
#include <arch/boot/boot.h>
#include <arch/arch.h>
47,10 → 46,11
#include <genarch/ofw/ofw_tree.h>
#include <userspace.h>
#include <ddi/irq.h>
#include <string.h>
 
bootinfo_t bootinfo;
 
/** Perform sparc64 specific initialization before main_bsp() is called. */
/** Perform sparc64-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Copy init task info. */
61,6 → 61,8
for (i = 0; i < bootinfo.taskmap.count; i++) {
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr;
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo.taskmap.tasks[i].name);
}
/* Copy boot allocations info. */
86,8 → 88,6
* But we only create 128 buckets.
*/
irq_init(1 << 11, 128);
standalone_sparc64_console_init();
}
}
 
101,18 → 101,7
 
void arch_post_smp_init(void)
{
static thread_t *t = NULL;
 
 
if (!t) {
/*
* Create thread that polls keyboard.
*/
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
}
standalone_sparc64_console_init();
}
 
/** Calibrate delay loop.
161,5 → 150,19
while (1);
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/ddi/ddi.c
41,7 → 41,7
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param ioaddr Starting I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
/branches/arm/kernel/arch/sparc64/src/cpu/cpu.c
32,12 → 32,46
/** @file
*/
 
#include <arch/cpu_family.h>
#include <cpu.h>
#include <arch.h>
#include <genarch/ofw/ofw_tree.h>
#include <arch/drivers/tick.h>
#include <print.h>
#include <arch/cpu_node.h>
 
/**
* Finds out the clock frequency of the current CPU.
*
* @param node node representing the current CPU in the OFW tree
* @return clock frequency if "node" is the current CPU and no error
* occurs, -1 if "node" is not the current CPU or on error
*/
static int find_cpu_frequency(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
uint32_t mid;
 
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
prop = ofw_tree_getprop(node, "upa-portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "cpuid");
if (prop && prop->value) {
mid = *((uint32_t *) prop->value);
if (mid == CPU->arch.mid) {
prop = ofw_tree_getprop(node, "clock-frequency");
if (prop && prop->value) {
return *((uint32_t *) prop->value);
}
}
}
return -1;
}
 
/** Perform sparc64 specific initialization of the processor structure for the
* current processor.
*/
44,34 → 78,37
void cpu_arch_init(void)
{
ofw_tree_node_t *node;
uint32_t mid;
uint32_t clock_frequency = 0;
upa_config_t upa_config;
upa_config.value = upa_config_read();
CPU->arch.mid = upa_config.mid;
CPU->arch.mid = read_mid();
/*
* Detect processor frequency.
*/
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
while (node) {
ofw_tree_property_t *prop;
prop = ofw_tree_getprop(node, "upa-portid");
if (prop && prop->value) {
mid = *((uint32_t *) prop->value);
if (mid == CPU->arch.mid) {
prop = ofw_tree_getprop(node,
"clock-frequency");
if (prop && prop->value)
clock_frequency = *((uint32_t *)
prop->value);
}
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
int f = find_cpu_frequency(node);
if (f != -1)
clock_frequency = (uint32_t) f;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
}
node = ofw_tree_find_peer_by_device_type(node, "cpu");
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
int f;
f = find_cpu_frequency(
ofw_tree_find_child(node, "cpu@0"));
if (f != -1)
clock_frequency = (uint32_t) f;
f = find_cpu_frequency(
ofw_tree_find_child(node, "cpu@1"));
if (f != -1)
clock_frequency = (uint32_t) f;
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
 
CPU->arch.clock_frequency = clock_frequency;
tick_init();
}
124,6 → 161,15
case IMPL_ULTRASPARCIII:
impl = "UltraSPARC III";
break;
case IMPL_ULTRASPARCIII_PLUS:
impl = "UltraSPARC III+";
break;
case IMPL_ULTRASPARCIII_I:
impl = "UltraSPARC IIIi";
break;
case IMPL_ULTRASPARCIV:
impl = "UltraSPARC IV";
break;
case IMPL_ULTRASPARCIV_PLUS:
impl = "UltraSPARC IV+";
break;
/branches/arm/kernel/arch/sparc64/src/proc/thread.c
34,9 → 34,8
 
#include <proc/thread.h>
#include <arch/proc/thread.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <arch/mm/page.h>
#include <mm/slab.h>
#include <arch/trap/regwin.h>
#include <align.h>
 
void thr_constructor_arch(thread_t *t)
50,12 → 49,12
void thr_destructor_arch(thread_t *t)
{
if (t->arch.uspace_window_buffer) {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
/*
* Mind the possible alignment of the userspace window buffer
* belonging to a killed thread.
*/
frame_free(KA2PA(ALIGN_DOWN((uintptr_t)
t->arch.uspace_window_buffer, PAGE_SIZE)));
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT));
}
}
 
67,7 → 66,7
* The thread needs userspace window buffer and the object
* returned from the slab allocator doesn't have any.
*/
t->arch.uspace_window_buffer = frame_alloc(ONE_FRAME, FRAME_KA);
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0);
} else {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
 
76,7 → 75,7
* belonging to a killed thread.
*/
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
PAGE_SIZE);
UWB_ASIZE);
}
}
 
/branches/arm/kernel/arch/sparc64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/sparc64/include/context.h
39,7 → 39,7
#include <arch/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
#ifdef context_set
#undef context_set
/branches/arm/kernel/arch/sparc64/include/types.h
46,8 → 46,6
typedef unsigned long uint64_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
57,11 → 55,12
typedef uint64_t unative_t;
typedef int64_t native_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t */
#define PRIp "llx"
#define PRIs "llu"
#define PRIc "llu"
#define PRIi "llu"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
/branches/arm/kernel/arch/sparc64/include/mm/tlb.h
35,9 → 35,17
#ifndef KERN_sparc64_TLB_H_
#define KERN_sparc64_TLB_H_
 
#if defined (US)
#define ITLB_ENTRY_COUNT 64
#define DTLB_ENTRY_COUNT 64
#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT
#endif
 
/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */
#if defined (US3)
#define DTLB_MAX_LOCKED_ENTRIES 16
#endif
 
#define MEM_CONTEXT_KERNEL 0
#define MEM_CONTEXT_TEMP 1
 
53,6 → 61,9
/* TLB Demap Operation types. */
#define TLB_DEMAP_PAGE 0
#define TLB_DEMAP_CONTEXT 1
#if defined (US3)
#define TLB_DEMAP_ALL 2
#endif
 
#define TLB_DEMAP_TYPE_SHIFT 6
 
61,6 → 72,18
#define TLB_DEMAP_SECONDARY 1
#define TLB_DEMAP_NUCLEUS 2
 
/* There are more TLBs in one MMU in US3, their codes are defined here. */
#if defined (US3)
/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
#define TLB_DSMALL 0
#define TLB_DBIG_0 2
#define TLB_DBIG_1 3
/* I-MMU: one small (16-entry) TLB and one big TLB */
#define TLB_ISMALL 0
#define TLB_IBIG 2
#endif
 
#define TLB_DEMAP_CONTEXT_SHIFT 4
 
/* TLB Tag Access shifts */
76,6 → 99,8
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
#include <arch/register.h>
#include <arch/cpu.h>
 
union tlb_context_reg {
uint64_t v;
90,6 → 115,9
typedef tte_data_t tlb_data_t;
 
/** I-/D-TLB Data Access Address in Alternate Space. */
 
#if defined (US)
 
union tlb_data_access_addr {
uint64_t value;
struct {
98,9 → 126,54
unsigned : 3;
} __attribute__ ((packed));
};
typedef union tlb_data_access_addr tlb_data_access_addr_t;
typedef union tlb_data_access_addr tlb_tag_read_addr_t;
typedef union tlb_data_access_addr dtlb_data_access_addr_t;
typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
typedef union tlb_data_access_addr itlb_data_access_addr_t;
typedef union tlb_data_access_addr itlb_tag_read_addr_t;
 
#elif defined (US3)
 
/*
* In US3, I-MMU and D-MMU have different formats of the data
* access register virtual address. In the corresponding
* structures the member variable for the entry number is
* called "local_tlb_entry" - it contrasts with the "tlb_entry"
* for the US data access register VA structure. The rationale
* behind this is to prevent careless mistakes in the code
* caused by setting only the entry number and not the TLB
* number in the US3 code (when taking the code from US).
*/
 
union dtlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 45;
unsigned : 1;
unsigned tlb_number : 2;
unsigned : 4;
unsigned local_tlb_entry : 9;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
 
union itlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 45;
unsigned : 1;
unsigned tlb_number : 2;
unsigned : 6;
unsigned local_tlb_entry : 7;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union itlb_data_access_addr itlb_data_access_addr_t;
typedef union itlb_data_access_addr itlb_tag_read_addr_t;
 
#endif
 
/** I-/D-TLB Tag Read Register. */
union tlb_tag_read_reg {
uint64_t value;
118,8 → 191,13
uint64_t value;
struct {
uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
#if defined (US)
unsigned : 6; /**< Ignored. */
unsigned type : 1; /**< The type of demap operation. */
#elif defined (US3)
unsigned : 5; /**< Ignored. */
unsigned type: 2; /**< The type of demap operation. */
#endif
unsigned context : 2; /**< Context register selection. */
unsigned : 4; /**< Zero. */
} __attribute__ ((packed));
130,10 → 208,19
union tlb_sfsr_reg {
uint64_t value;
struct {
#if defined (US)
unsigned long : 40; /**< Implementation dependent. */
unsigned asi : 8; /**< ASI. */
unsigned : 2;
unsigned ft : 7; /**< Fault type. */
#elif defined (US3)
unsigned long : 39; /**< Implementation dependent. */
unsigned nf : 1; /**< Non-faulting load. */
unsigned asi : 8; /**< ASI. */
unsigned tm : 1; /**< I-TLB miss. */
unsigned : 3; /**< Reserved. */
unsigned ft : 5; /**< Fault type. */
#endif
unsigned e : 1; /**< Side-effect bit. */
unsigned ct : 2; /**< Context Register selection. */
unsigned pr : 1; /**< Privilege bit. */
144,9 → 231,53
};
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
 
#if defined (US3)
 
/*
* Functions for determining the number of entries in TLBs. They either return
* a constant value or a value based on the CPU autodetection.
*/
 
/**
* Determine the number of entries in the DMMU's small TLB.
*/
static inline uint16_t tlb_dsmall_size(void)
{
return 16;
}
 
/**
* Determine the number of entries in each DMMU's big TLB.
*/
static inline uint16_t tlb_dbig_size(void)
{
return 512;
}
 
/**
* Determine the number of entries in the IMMU's small TLB.
*/
static inline uint16_t tlb_ismall_size(void)
{
return 16;
}
 
/**
* Determine the number of entries in the IMMU's big TLB.
*/
static inline uint16_t tlb_ibig_size(void)
{
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
return 512;
else
return 128;
}
 
#endif
 
/** Read MMU Primary Context Register.
*
* @return Current value of Primary Context Register.
* @return Current value of Primary Context Register.
*/
static inline uint64_t mmu_primary_context_read(void)
{
155,7 → 286,7
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
* @param v New value of Primary Context Register.
*/
static inline void mmu_primary_context_write(uint64_t v)
{
165,7 → 296,7
 
/** Read MMU Secondary Context Register.
*
* @return Current value of Secondary Context Register.
* @return Current value of Secondary Context Register.
*/
static inline uint64_t mmu_secondary_context_read(void)
{
174,7 → 305,7
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
* @param v New value of Primary Context Register.
*/
static inline void mmu_secondary_context_write(uint64_t v)
{
182,15 → 313,18
flush_pipeline();
}
 
#if defined (US)
 
/** Read IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access Register.
* @return Current value of specified IMMU TLB Data Access
* Register.
*/
static inline uint64_t itlb_data_access_read(index_t entry)
static inline uint64_t itlb_data_access_read(size_t entry)
{
tlb_data_access_addr_t reg;
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
199,12 → 333,12
 
/** Write IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(index_t entry, uint64_t value)
static inline void itlb_data_access_write(size_t entry, uint64_t value)
{
tlb_data_access_addr_t reg;
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
214,13 → 348,14
 
/** Read DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access Register.
* @return Current value of specified DMMU TLB Data Access
* Register.
*/
static inline uint64_t dtlb_data_access_read(index_t entry)
static inline uint64_t dtlb_data_access_read(size_t entry)
{
tlb_data_access_addr_t reg;
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
229,12 → 364,12
 
/** Write DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(index_t entry, uint64_t value)
static inline void dtlb_data_access_write(size_t entry, uint64_t value)
{
tlb_data_access_addr_t reg;
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
244,13 → 379,13
 
/** Read IMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(index_t entry)
static inline uint64_t itlb_tag_read_read(size_t entry)
{
tlb_tag_read_addr_t tag;
itlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
259,13 → 394,13
 
/** Read DMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(index_t entry)
static inline uint64_t dtlb_tag_read_read(size_t entry)
{
tlb_tag_read_addr_t tag;
dtlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
272,9 → 407,120
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
#elif defined (US3)
 
 
/** Read IMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access
* Register.
*/
static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write IMMU TLB Data Access Register.
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(int tlb, size_t entry,
uint64_t value)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
flush_pipeline();
}
 
/** Read DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access
* Register.
*/
static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(int tlb, size_t entry,
uint64_t value)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
membar();
}
 
/** Read IMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
{
itlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_number = tlb;
tag.local_tlb_entry = entry;
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
}
 
/** Read DMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
{
dtlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_number = tlb;
tag.local_tlb_entry = entry;
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
#endif
 
 
/** Write IMMU TLB Tag Access Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void itlb_tag_access_write(uint64_t v)
{
284,7 → 530,7
 
/** Read IMMU TLB Tag Access Register.
*
* @return Current value of IMMU TLB Tag Access Register.
* @return Current value of IMMU TLB Tag Access Register.
*/
static inline uint64_t itlb_tag_access_read(void)
{
293,7 → 539,7
 
/** Write DMMU TLB Tag Access Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void dtlb_tag_access_write(uint64_t v)
{
303,7 → 549,7
 
/** Read DMMU TLB Tag Access Register.
*
* @return Current value of DMMU TLB Tag Access Register.
* @return Current value of DMMU TLB Tag Access Register.
*/
static inline uint64_t dtlb_tag_access_read(void)
{
313,7 → 559,7
 
/** Write IMMU TLB Data in Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void itlb_data_in_write(uint64_t v)
{
323,7 → 569,7
 
/** Write DMMU TLB Data in Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void dtlb_data_in_write(uint64_t v)
{
333,7 → 579,7
 
/** Read ITLB Synchronous Fault Status Register.
*
* @return Current content of I-SFSR register.
* @return Current content of I-SFSR register.
*/
static inline uint64_t itlb_sfsr_read(void)
{
342,7 → 588,7
 
/** Write ITLB Synchronous Fault Status Register.
*
* @param v New value of I-SFSR register.
* @param v New value of I-SFSR register.
*/
static inline void itlb_sfsr_write(uint64_t v)
{
352,7 → 598,7
 
/** Read DTLB Synchronous Fault Status Register.
*
* @return Current content of D-SFSR register.
* @return Current content of D-SFSR register.
*/
static inline uint64_t dtlb_sfsr_read(void)
{
361,7 → 607,7
 
/** Write DTLB Synchronous Fault Status Register.
*
* @param v New value of D-SFSR register.
* @param v New value of D-SFSR register.
*/
static inline void dtlb_sfsr_write(uint64_t v)
{
371,7 → 617,7
 
/** Read DTLB Synchronous Fault Address Register.
*
* @return Current content of D-SFAR register.
* @return Current content of D-SFAR register.
*/
static inline uint64_t dtlb_sfar_read(void)
{
380,10 → 626,11
 
/** Perform IMMU TLB Demap Operation.
*
* @param type Selects between context and page demap.
* @param type Selects between context and page demap (and entire MMU
* demap on US3).
* @param context_encoding Specifies which Context register has Context ID for
* demap.
* @param page Address which is on the page to be demapped.
* demap.
* @param page Address which is on the page to be demapped.
*/
static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
{
397,18 → 644,19
da.context = context_encoding;
da.vpn = pg.vpn;
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
* address within the
* ASI */
/* da.value is the address within the ASI */
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
 
flush_pipeline();
}
 
/** Perform DMMU TLB Demap Operation.
*
* @param type Selects between context and page demap.
* @param type Selects between context and page demap (and entire MMU
* demap on US3).
* @param context_encoding Specifies which Context register has Context ID for
* demap.
* @param page Address which is on the page to be demapped.
* demap.
* @param page Address which is on the page to be demapped.
*/
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
{
422,17 → 670,17
da.context = context_encoding;
da.vpn = pg.vpn;
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
* address within the
* ASI */
/* da.value is the address within the ASI */
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
 
membar();
}
 
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
 
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
 
extern void dump_sfsr_and_sfar(void);
 
/branches/arm/kernel/arch/sparc64/include/mm/tsb.h
107,13 → 107,62
asi_u64_write(ASI_DMMU, VA_DMMU_TSB_BASE, v);
}
 
#if defined (US3)
 
/** Write DTSB Primary Extension register.
*
* @param v New content of the DTSB Primary Extension register.
*/
static inline void dtsb_primary_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_PRIMARY_EXTENSION, v);
}
 
/** Write DTSB Secondary Extension register.
*
* @param v New content of the DTSB Secondary Extension register.
*/
static inline void dtsb_secondary_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_SECONDARY_EXTENSION, v);
}
 
/** Write DTSB Nucleus Extension register.
*
* @param v New content of the DTSB Nucleus Extension register.
*/
static inline void dtsb_nucleus_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_NUCLEUS_EXTENSION, v);
}
 
/** Write ITSB Primary Extension register.
*
* @param v New content of the ITSB Primary Extension register.
*/
static inline void itsb_primary_extension_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_PRIMARY_EXTENSION, v);
}
 
/** Write ITSB Nucleus Extension register.
*
* @param v New content of the ITSB Nucleus Extension register.
*/
static inline void itsb_nucleus_extension_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_NUCLEUS_EXTENSION, v);
}
 
#endif
 
/* Forward declarations. */
struct as;
struct pte;
 
extern void tsb_invalidate(struct as *as, uintptr_t page, count_t pages);
extern void itsb_pte_copy(struct pte *t, index_t index);
extern void dtsb_pte_copy(struct pte *t, index_t index, bool ro);
extern void tsb_invalidate(struct as *as, uintptr_t page, size_t pages);
extern void itsb_pte_copy(struct pte *t, size_t index);
extern void dtsb_pte_copy(struct pte *t, size_t index, bool ro);
 
#endif /* !def __ASM__ */
 
/branches/arm/kernel/arch/sparc64/include/mm/frame.h
59,8 → 59,13
union frame_address {
uintptr_t address;
struct {
#if defined (US)
unsigned : 23;
uint64_t pfn : 28; /**< Physical Frame Number. */
#elif defined (US3)
unsigned : 21;
uint64_t pfn : 30; /**< Physical Frame Number. */
#endif
unsigned offset : 13; /**< Offset. */
} __attribute__ ((packed));
};
68,6 → 73,8
typedef union frame_address frame_address_t;
 
extern uintptr_t last_frame;
extern uintptr_t end_of_identity;
 
extern void frame_arch_init(void);
#define physmem_print()
 
/branches/arm/kernel/arch/sparc64/include/mm/tte.h
50,6 → 50,7
 
#include <arch/types.h>
 
/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */
#define VA_TAG_PAGE_SHIFT 22
 
/** Translation Table Entry - Tag. */
75,8 → 76,13
unsigned nfo : 1; /**< No-Fault-Only. */
unsigned ie : 1; /**< Invert Endianness. */
unsigned soft2 : 9; /**< Software defined field. */
#if defined (US)
unsigned diag : 9; /**< Diagnostic data. */
unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */
#elif defined (US3)
unsigned : 7; /**< Reserved. */
unsigned pfn : 30; /**< Physical Address bits, bits 42:13 */
#endif
unsigned soft : 6; /**< Software defined field. */
unsigned l : 1; /**< Lock. */
unsigned cp : 1; /**< Cacheable in physically indexed cache. */
/branches/arm/kernel/arch/sparc64/include/mm/cache_spec.h
38,19 → 38,20
/*
* The following macros are valid for the following processors:
*
* UltraSPARC, UltraSPARC II, UltraSPARC IIi
* UltraSPARC, UltraSPARC II, UltraSPARC IIi, UltraSPARC III,
* UltraSPARC III+, UltraSPARC IV, UltraSPARC IV+
*
* Should we support other UltraSPARC processors, we need to make sure that
* the macros are defined correctly for them.
*/
 
#if defined (US)
#define DCACHE_SIZE (16 * 1024)
#elif defined (US3)
#define DCACHE_SIZE (64 * 1024)
#endif
#define DCACHE_LINE_SIZE 32
 
#define ICACHE_SIZE (16 * 1024)
#define ICACHE_WAYS 2
#define ICACHE_LINE_SIZE 32
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/mm/mmu.h
35,8 → 35,10
#ifndef KERN_sparc64_MMU_H_
#define KERN_sparc64_MMU_H_
 
#if defined(US)
/* LSU Control Register ASI. */
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */
#endif
 
/* I-MMU ASIs. */
#define ASI_IMMU 0x50
52,7 → 54,12
#define VA_IMMU_SFSR 0x18 /**< IMMU sync fault status register. */
#define VA_IMMU_TSB_BASE 0x28 /**< IMMU TSB base register. */
#define VA_IMMU_TAG_ACCESS 0x30 /**< IMMU TLB tag access register. */
#if defined (US3)
#define VA_IMMU_PRIMARY_EXTENSION 0x48 /**< IMMU TSB primary extension register */
#define VA_IMMU_NUCLEUS_EXTENSION 0x58 /**< IMMU TSB nucleus extension register */
#endif
 
 
/* D-MMU ASIs. */
#define ASI_DMMU 0x58
#define ASI_DMMU_TSB_8KB_PTR_REG 0x59
73,6 → 80,11
#define VA_DMMU_TAG_ACCESS 0x30 /**< DMMU TLB tag access register. */
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */
#if defined (US3)
#define VA_DMMU_PRIMARY_EXTENSION 0x48 /**< DMMU TSB primary extension register */
#define VA_DMMU_SECONDARY_EXTENSION 0x50 /**< DMMU TSB secondary extension register */
#define VA_DMMU_NUCLEUS_EXTENSION 0x58 /**< DMMU TSB nucleus extension register */
#endif
 
#ifndef __ASM__
 
80,6 → 92,7
#include <arch/barrier.h>
#include <arch/types.h>
 
#if defined(US)
/** LSU Control Register. */
typedef union {
uint64_t value;
100,6 → 113,7
} __attribute__ ((packed));
} lsu_cr_reg_t;
#endif /* US */
 
#endif /* !def __ASM__ */
 
/branches/arm/kernel/arch/sparc64/include/mm/cache.h
38,15 → 38,6
#include <mm/page.h>
#include <mm/frame.h>
 
#define dcache_flush_page(p) \
dcache_flush_color(PAGE_COLOR((p)))
#define dcache_flush_frame(p, f) \
dcache_flush_tag(PAGE_COLOR((p)), ADDR2PFN((f)));
 
extern void dcache_flush(void);
extern void dcache_flush_color(int c);
extern void dcache_flush_tag(int c, pfn_t tag);
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/trap/trap_table.h
100,7 → 100,7
 
.macro PREEMPTIBLE_HANDLER f
sethi %hi(\f), %g1
b preemptible_handler
ba %xcc, preemptible_handler
or %g1, %lo(\f), %g1
.endm
 
/branches/arm/kernel/arch/sparc64/include/trap/mmu.h
103,17 → 103,20
* Note that branch-delay slots are used in order to save space.
*/
0:
mov VA_DMMU_TAG_ACCESS, %g1
ldxa [%g1] ASI_DMMU, %g1 ! read the faulting Context and VPN
sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
wr %g0, ASI_DMMU, %asi
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1 ! read the faulting Context and VPN
set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
andcc %g1, %g2, %g3 ! get Context
bnz 0f ! Context is non-zero
bnz %xcc, 0f ! Context is non-zero
andncc %g1, %g2, %g3 ! get page address into %g3
bz 0f ! page address is zero
bz %xcc, 0f ! page address is zero
ldx [%g7 + %lo(end_of_identity)], %g4
cmp %g3, %g4
bgeu %xcc, 0f
 
sethi %hi(kernel_8k_tlb_data_template), %g2
ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2
or %g3, %g2, %g2
ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
add %g3, %g2, %g2
stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page
retry
 
138,8 → 141,7
* Read the Tag Access register for the higher-level handler.
* This is necessary to survive nested DTLB misses.
*/
mov VA_DMMU_TAG_ACCESS, %g2
ldxa [%g2] ASI_DMMU, %g2
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
 
/*
* g2 will be passed as an argument to fast_data_access_mmu_miss().
/branches/arm/kernel/arch/sparc64/include/trap/interrupt.h
49,21 → 49,43
 
 
/* Interrupt ASI registers. */
#define ASI_UDB_INTR_W 0x77
#define ASI_INTR_W 0x77
#define ASI_INTR_DISPATCH_STATUS 0x48
#define ASI_UDB_INTR_R 0x7f
#define ASI_INTR_R 0x7f
#define ASI_INTR_RECEIVE 0x49
 
/* VA's used with ASI_UDB_INTR_W register. */
/* VA's used with ASI_INTR_W register. */
#if defined (US)
#define ASI_UDB_INTR_W_DATA_0 0x40
#define ASI_UDB_INTR_W_DATA_1 0x50
#define ASI_UDB_INTR_W_DATA_2 0x60
#define ASI_UDB_INTR_W_DISPATCH 0x70
#elif defined (US3)
#define VA_INTR_W_DATA_0 0x40
#define VA_INTR_W_DATA_1 0x48
#define VA_INTR_W_DATA_2 0x50
#define VA_INTR_W_DATA_3 0x58
#define VA_INTR_W_DATA_4 0x60
#define VA_INTR_W_DATA_5 0x68
#define VA_INTR_W_DATA_6 0x80
#define VA_INTR_W_DATA_7 0x88
#endif
#define VA_INTR_W_DISPATCH 0x70
 
/* VA's used with ASI_UDB_INTR_R register. */
/* VA's used with ASI_INTR_R register. */
#if defined(US)
#define ASI_UDB_INTR_R_DATA_0 0x40
#define ASI_UDB_INTR_R_DATA_1 0x50
#define ASI_UDB_INTR_R_DATA_2 0x60
#elif defined (US3)
#define VA_INTR_R_DATA_0 0x40
#define VA_INTR_R_DATA_1 0x48
#define VA_INTR_R_DATA_2 0x50
#define VA_INTR_R_DATA_3 0x58
#define VA_INTR_R_DATA_4 0x60
#define VA_INTR_R_DATA_5 0x68
#define VA_INTR_R_DATA_6 0x80
#define VA_INTR_R_DATA_7 0x88
#endif
 
/* Shifts in the Interrupt Vector Dispatch virtual address. */
#define INTR_VEC_DISPATCH_MID_SHIFT 14
/branches/arm/kernel/arch/sparc64/include/trap/regwin.h
39,6 → 39,7
 
#include <arch/stack.h>
#include <arch/arch.h>
#include <align.h>
 
#define TT_CLEAN_WINDOW 0x24
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */
72,6 → 73,11
#define I6_OFFSET 112
#define I7_OFFSET 120
 
/* Uspace Window Buffer constants. */
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE)
#define UWB_ALIGNMENT 1024
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT)
 
#ifdef __ASM__
 
/*
/branches/arm/kernel/arch/sparc64/include/atomic.h
123,7 → 123,7
"ldx %0, %2\n"
"brz %2, 0b\n"
"nop\n"
"ba 1b\n"
"ba %xcc, 1b\n"
"nop\n"
"2:\n"
: "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0)
/branches/arm/kernel/arch/sparc64/include/drivers/z8530.h
File deleted
/branches/arm/kernel/arch/sparc64/include/drivers/ns16550.h
File deleted
/branches/arm/kernel/arch/sparc64/include/drivers/sgcn.h
0,0 → 1,134
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_SGCN_H_
#define KERN_sparc64_SGCN_H_
 
#include <arch/types.h>
#include <console/chardev.h>
#include <proc/thread.h>
 
/* number of bytes in the TOC magic, including the NULL-terminator */
#define TOC_MAGIC_BYTES 8
 
/* number of bytes in the TOC key, including the NULL-terminator */
#define TOC_KEY_SIZE 8
 
/* maximum number of entries in the SRAM table of contents */
#define MAX_TOC_ENTRIES 32
 
/* number of bytes in the SGCN buffer magic, including the NULL-terminator */
#define SGCN_MAGIC_BYTES 4
 
/**
* Entry in the SRAM table of contents. Describes one segment of the SRAM
* which serves a particular purpose (e.g. OBP serial console, Solaris serial
* console, Solaris mailbox,...).
*/
typedef struct {
/** key (e.g. "OBPCONS", "SOLCONS", "SOLMBOX",...) */
char key[TOC_KEY_SIZE];
/** size of the segment in bytes */
uint32_t size;
/** offset of the segment within SRAM */
uint32_t offset;
} __attribute ((packed)) toc_entry_t;
 
/**
* SRAM table of contents. Describes all segments within the SRAM.
*/
typedef struct {
/** hard-wired to "TOCSRAM" */
char magic[TOC_MAGIC_BYTES];
/** we don't need this */
char unused[8];
/** TOC entries */
toc_entry_t keys[MAX_TOC_ENTRIES];
} __attribute__ ((packed)) iosram_toc_t;
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[SGCN_MAGIC_BYTES];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
/** offset within the SGCN buffer of the output buffer end */
uint32_t out_end;
/** offset within the SGCN buffer of the output buffer read pointer */
uint32_t out_rdptr;
/** offset within the SGCN buffer of the output buffer write pointer */
uint32_t out_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
typedef struct {
thread_t *thread;
indev_t *srlnin;
} sgcn_instance_t;
 
extern void sgcn_grab(void);
extern void sgcn_release(void);
extern sgcn_instance_t *sgcnin_init(void);
extern void sgcnin_wire(sgcn_instance_t *, indev_t *);
extern void sgcnout_init(void);
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/include/drivers/kbd.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
38,14 → 38,6
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
typedef enum {
KBD_UNKNOWN,
KBD_Z8530,
KBD_NS16550
} kbd_type_t;
 
extern kbd_type_t kbd_type;
 
extern void kbd_init(ofw_tree_node_t *node);
 
#endif
/branches/arm/kernel/arch/sparc64/include/drivers/scr.h
42,12 → 42,14
SCR_UNKNOWN,
SCR_ATYFB,
SCR_FFB,
SCR_CGSIX
SCR_CGSIX,
SCR_XVR
} scr_type_t;
 
extern scr_type_t scr_type;
 
extern void scr_init(ofw_tree_node_t *node);
extern void scr_redraw(void);
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/drivers/pci.h
51,8 → 51,8
};
 
struct pci_operations {
void (* enable_interrupt)(pci_t *pci, int inr);
void (* clear_interrupt)(pci_t *pci, int inr);
void (* enable_interrupt)(pci_t *, int);
void (* clear_interrupt)(pci_t *, int);
};
 
struct pci {
61,9 → 61,9
volatile uint64_t *reg; /**< Registers including interrupt registers. */
};
 
extern pci_t *pci_init(ofw_tree_node_t *node);
extern void pci_enable_interrupt(pci_t *pci, int inr);
extern void pci_clear_interrupt(pci_t *pci, int inr);
extern pci_t *pci_init(ofw_tree_node_t *);
extern void pci_enable_interrupt(pci_t *, int);
extern void pci_clear_interrupt(void *, int);
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/drivers/fhc.h
44,9 → 44,9
 
extern fhc_t *central_fhc;
 
extern fhc_t *fhc_init(ofw_tree_node_t *node);
extern void fhc_enable_interrupt(fhc_t *fhc, int inr);
extern void fhc_clear_interrupt(fhc_t *fhc, int inr);
extern fhc_t *fhc_init(ofw_tree_node_t *);
extern void fhc_enable_interrupt(fhc_t *, int);
extern void fhc_clear_interrupt(void *, int);
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/memstr.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
/branches/arm/kernel/arch/sparc64/include/boot/boot.h
48,9 → 48,12
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
typedef struct {
void * addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
/branches/arm/kernel/arch/sparc64/include/asm.h
42,7 → 42,56
#include <arch/register.h>
#include <config.h>
#include <arch/stack.h>
#include <arch/barrier.h>
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
memory_barrier();
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
memory_barrier();
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
memory_barrier();
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
/** Read Processor State register.
*
* @return Value of PSTATE register.
87,6 → 136,28
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
}
 
/** Read STICK_compare Register.
*
* @return Value of STICK_compare register.
*/
static inline uint64_t stick_compare_read(void)
{
uint64_t v;
asm volatile ("rd %%asr25, %0\n" : "=r" (v));
return v;
}
 
/** Write STICK_compare Register.
*
* @param v New value of STICK_comapre register.
*/
static inline void stick_compare_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0));
}
 
/** Read TICK Register.
*
* @return Value of TICK register.
358,15 → 429,6
asm volatile ("wrpr %g0, %g0, %tl\n");
}
 
/** Read UPA_CONFIG register.
*
* @return Value of the UPA_CONFIG register.
*/
static inline uint64_t upa_config_read(void)
{
return asi_u64_read(ASI_UPA_CONFIG, 0);
}
 
extern void cpu_halt(void);
extern void cpu_sleep(void);
extern void asm_delay_loop(const uint32_t usec);
/branches/arm/kernel/arch/sparc64/include/arch.h
41,10 → 41,16
#define ASI_AIUS 0x11 /** Access to secondary context with user privileges. */
#define ASI_NUCLEUS_QUAD_LDD 0x24 /** ASI for 16-byte atomic loads. */
#define ASI_DCACHE_TAG 0x47 /** ASI D-Cache Tag. */
#define ASI_UPA_CONFIG 0x4a /** ASI of the UPA_CONFIG register. */
#define ASI_ICBUS_CONFIG 0x4a /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */
 
#define NWINDOWS 8 /** Number of register window sets. */
 
#ifndef __ASM__
 
extern void arch_pre_main(void);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/cpu_node.h
0,0 → 1,59
/*
* Copyright (c) 2005 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_NODE_H_
#define KERN_sparc64_CPU_NODE_H_
 
#include <genarch/ofw/ofw_tree.h>
 
 
/** Finds the parent node of all the CPU nodes (nodes named "cpu" or "cmp").
*
* Depending on the machine type (and possibly the OFW version), CPUs can be
* at "/" or at "/ssm@0,0".
*/
static inline ofw_tree_node_t *cpus_parent(void)
{
ofw_tree_node_t *parent;
parent = ofw_tree_find_child(ofw_tree_lookup("/"), "ssm@0,0");
if (parent == NULL)
parent = ofw_tree_lookup("/");
return parent;
}
 
#endif
 
/** @}
*/
 
/branches/arm/kernel/arch/sparc64/include/cpu_family.h
0,0 → 1,83
/*
* Copyright (c) 2008 Pavel Rimsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_FAMILY_H_
#define KERN_sparc64_CPU_FAMILY_H_
 
#include <arch.h>
#include <cpu.h>
#include <arch/register.h>
#include <arch/asm.h>
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US family
*/
static inline bool is_us(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCI) || (impl == IMPL_ULTRASPARCII) ||
(impl == IMPL_ULTRASPARCII_I) || (impl == IMPL_ULTRASPARCII_E);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-III subfamily
*/
static inline bool is_us_iii(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIII) ||
(impl == IMPL_ULTRASPARCIII_PLUS) ||
(impl == IMPL_ULTRASPARCIII_I);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-IV subfamily
*/
static inline bool is_us_iv(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIV) || (impl == IMPL_ULTRASPARCIV_PLUS);
}
#endif
 
/** @}
*/
 
/branches/arm/kernel/arch/sparc64/include/fpu_context.h
37,7 → 37,6
 
#include <arch/types.h>
 
#define ARCH_HAS_FPU
#define FPU_CONTEXT_ALIGN 8
 
typedef struct {
/branches/arm/kernel/arch/sparc64/include/barrier.h
82,6 → 82,8
asm volatile ("membar #Sync\n");
}
 
#if defined (US)
 
#define smc_coherence(a) \
{ \
write_barrier(); \
97,6 → 99,22
flush((void *)(a) + i); \
}
 
#elif defined (US3)
 
#define smc_coherence(a) \
{ \
write_barrier(); \
flush_pipeline(); \
}
 
#define smc_coherence_block(a, l) \
{ \
write_barrier(); \
flush_pipeline(); \
}
 
#endif /* defined(US3) */
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/regdef.h
55,8 → 55,11
#define WSTATE_NORMAL(n) (n)
#define WSTATE_OTHER(n) ((n) << 3)
 
#define UPA_CONFIG_MID_SHIFT 17
#define UPA_CONFIG_MID_MASK 0x1f
/*
* The following definitions concern the UPA_CONFIG register on US and the
* FIREPLANE_CONFIG register on US3.
*/
#define ICBUS_CONFIG_MID_SHIFT 17
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/register.h
117,23 → 117,6
};
typedef union fprs_reg fprs_reg_t;
 
/** UPA_CONFIG register.
*
* Note that format of this register differs significantly from
* processor version to version. The format defined here
* is the common subset for all supported processor versions.
*/
union upa_config {
uint64_t value;
struct {
uint64_t : 34;
unsigned pcon : 8; /**< Processor configuration. */
unsigned mid : 5; /**< Module (processor) ID register. */
unsigned pcap : 17; /**< Processor capabilities. */
} __attribute__ ((packed));
};
typedef union upa_config upa_config_t;
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/cpu.h
35,15 → 35,6
#ifndef KERN_sparc64_CPU_H_
#define KERN_sparc64_CPU_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/register.h>
#include <arch/asm.h>
 
#ifdef CONFIG_SMP
#include <arch/mm/cache.h>
#endif
 
#define MANUF_FUJITSU 0x04
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */
#define MANUF_SUN 0x3e
52,14 → 43,29
#define IMPL_ULTRASPARCII 0x11
#define IMPL_ULTRASPARCII_I 0x12
#define IMPL_ULTRASPARCII_E 0x13
#define IMPL_ULTRASPARCIII 0x15
#define IMPL_ULTRASPARCIII 0x14
#define IMPL_ULTRASPARCIII_PLUS 0x15
#define IMPL_ULTRASPARCIII_I 0x16
#define IMPL_ULTRASPARCIV 0x18
#define IMPL_ULTRASPARCIV_PLUS 0x19
 
#define IMPL_SPARC64V 0x5
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/register.h>
#include <arch/regdef.h>
#include <arch/asm.h>
 
#ifdef CONFIG_SMP
#include <arch/mm/cache.h>
#endif
 
typedef struct {
uint32_t mid; /**< Processor ID as read from
UPA_CONFIG. */
UPA_CONFIG/FIREPLANE_CONFIG. */
ver_reg_t ver;
uint32_t clock_frequency; /**< Processor frequency in Hz. */
uint64_t next_tick_cmpr; /**< Next clock interrupt should be
66,8 → 72,28
generated when the TICK register
matches this value. */
} cpu_arch_t;
 
 
/**
* Reads the module ID (agent ID/CPUID) of the current CPU.
*/
static inline uint32_t read_mid(void)
{
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT;
#if defined (US)
return icbus_config & 0x1f;
#elif defined (US3)
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I)
return icbus_config & 0x1f;
else
return icbus_config & 0x3ff;
#endif
}
 
#endif
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-sparc
BFD_ARCH = sparc
BFD = binary
44,82 → 40,58
 
LFLAGS += -no-check-sections -N
 
DEFS += -D__64_BITS__
BITS = 64
ENDIANESS = BE
 
## Own configuration directives
#
ifeq ($(PROCESSOR),us)
DEFS += -DUS
endif
 
## Compile with page hash table support.
#
ifeq ($(PROCESSOR),us3)
DEFS += -DUS3
endif
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
ARCH_SOURCES = \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/console.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/cache.S \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/sparc64.c \
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/proc/thread.c \
arch/$(KARCH)/src/trap/mmu.S \
arch/$(KARCH)/src/trap/trap_table.S \
arch/$(KARCH)/src/trap/trap.c \
arch/$(KARCH)/src/trap/exception.c \
arch/$(KARCH)/src/trap/interrupt.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/tick.c \
arch/$(KARCH)/src/drivers/kbd.c \
arch/$(KARCH)/src/drivers/sgcn.c \
arch/$(KARCH)/src/drivers/pci.c \
arch/$(KARCH)/src/drivers/fhc.c
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for framebuffer.
#
 
CONFIG_FB = y
 
## Compile with support for Sun keyboard.
#
 
CONFIG_SUN_KBD = y
 
## Compile with support for OpenFirmware device tree.
#
 
CONFIG_OFW_TREE = y
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
ifeq ($(CONFIG_FB),y)
ARCH_SOURCES += \
arch/$(KARCH)/src/drivers/scr.c
endif
 
ARCH_SOURCES = \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/cache.S \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/sparc64.c \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/trap/mmu.S \
arch/$(ARCH)/src/trap/trap_table.S \
arch/$(ARCH)/src/trap/trap.c \
arch/$(ARCH)/src/trap/exception.c \
arch/$(ARCH)/src/trap/interrupt.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/tick.c \
arch/$(ARCH)/src/drivers/kbd.c \
arch/$(ARCH)/src/drivers/scr.c \
arch/$(ARCH)/src/drivers/pci.c
 
ifeq ($(CONFIG_SMP),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/smp/smp.c
ARCH_SOURCES += \
arch/$(KARCH)/src/smp/ipi.c \
arch/$(KARCH)/src/smp/smp.c
endif
 
ifeq ($(CONFIG_TSB),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/mm/tsb.c
ARCH_SOURCES += \
arch/$(KARCH)/src/mm/tsb.c
endif
 
ifdef CONFIG_Z8530
ARCH_SOURCES += \
arch/$(ARCH)/src/drivers/fhc.c
endif
/branches/arm/kernel/arch/sparc64/_link.ld.in
1,8 → 1,8
/** SPARC64 linker script
*
* It is ELF format, but its only section looks like this:
* kernel text
* kernel data
* kernel text
* kernel data
*
*/
 
11,7 → 11,7
ENTRY(kernel_image_start)
 
SECTIONS {
.image VMA: AT (LMA) {
.image VMA: AT (LMA) {
ktext_start = .;
*(K_TEXT_START)
*(.text);
21,23 → 21,23
*(K_DATA_START)
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
. = ALIGN(8);
hardcoded_ktext_size = .;
QUAD(ktext_end - ktext_start);
QUAD(ktext_end - ktext_start);
hardcoded_kdata_size = .;
QUAD(kdata_end - kdata_start);
hardcoded_load_address = .;
QUAD(VMA);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
*(symtab.*); /* Symbol table, must be LAST symbol!*/
kdata_end = .;
}
44,5 → 44,5
/DISCARD/ : {
*(*);
}
 
}
/branches/arm/kernel/arch/mips32/include/console.h
File deleted
/branches/arm/kernel/arch/mips32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/mips32/include/boot.h
File deleted
/branches/arm/kernel/arch/mips32/include/context_offset.h
76,26 → 76,17
#define EOFFSET_T5 0x30
#define EOFFSET_T6 0x34
#define EOFFSET_T7 0x38
#define EOFFSET_S0 0x3c
#define EOFFSET_S1 0x40
#define EOFFSET_S2 0x44
#define EOFFSET_S3 0x48
#define EOFFSET_S4 0x4c
#define EOFFSET_S5 0x50
#define EOFFSET_S6 0x54
#define EOFFSET_S7 0x58
#define EOFFSET_T8 0x5c
#define EOFFSET_T9 0x60
#define EOFFSET_GP 0x64
#define EOFFSET_SP 0x68
#define EOFFSET_S8 0x6c
#define EOFFSET_RA 0x70
#define EOFFSET_LO 0x74
#define EOFFSET_HI 0x78
#define EOFFSET_STATUS 0x7c
#define EOFFSET_EPC 0x80
#define EOFFSET_K1 0x84
#define REGISTER_SPACE 136
#define EOFFSET_T8 0x3c
#define EOFFSET_T9 0x40
#define EOFFSET_GP 0x44
#define EOFFSET_SP 0x48
#define EOFFSET_RA 0x4c
#define EOFFSET_LO 0x50
#define EOFFSET_HI 0x54
#define EOFFSET_STATUS 0x58
#define EOFFSET_EPC 0x5c
#define EOFFSET_K1 0x60
#define REGISTER_SPACE 104 /* respect stack alignment */
 
#ifdef __ASM__
 
114,10 → 105,10
sw $s8,OFFSET_S8(\ctx)
sw $gp,OFFSET_GP(\ctx)
 
#ifndef KERNEL
#ifndef KERNEL
sw $k1,OFFSET_TLS(\ctx)
 
# ifdef CONFIG_MIPS_FPU
#ifdef CONFIG_FPU
mfc1 $t0,$20
sw $t0, OFFSET_F20(\ctx)
 
150,7 → 141,7
mfc1 $t0,$30
sw $t0, OFFSET_F30(\ctx)
# endif /* CONFIG_MIPS_FPU */
#endif /* CONFIG_FPU */
#endif /* KERNEL */
 
sw $ra,OFFSET_PC(\ctx)
172,7 → 163,7
#ifndef KERNEL
lw $k1,OFFSET_TLS(\ctx)
 
# ifdef CONFIG_MIPS_FPU
#ifdef CONFIG_FPU
lw $t0, OFFSET_F20(\ctx)
mtc1 $t0,$20
 
205,9 → 196,9
 
lw $t0, OFFSET_F30(\ctx)
mtc1 $t0,$30
# endif /* CONFIG_MIPS_FPU */
#endif /* CONFIG_FPU */
#endif /* KERNEL */
 
lw $ra,OFFSET_PC(\ctx)
lw $sp,OFFSET_SP(\ctx)
.endm
/branches/arm/kernel/arch/mips32/include/elf.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
35,15 → 35,15
#ifndef KERN_mips32_ELF_H_
#define KERN_mips32_ELF_H_
 
#define ELF_MACHINE EM_MIPS
#define ELF_MACHINE EM_MIPS
 
#ifdef BIG_ENDIAN
# define ELF_DATA_ENCODING ELFDATA2MSB
#ifdef __BE__
#define ELF_DATA_ENCODING ELFDATA2MSB
#else
# define ELF_DATA_ENCODING ELFDATA2LSB
#define ELF_DATA_ENCODING ELFDATA2LSB
#endif
 
#define ELF_CLASS ELFCLASS32
#define ELF_CLASS ELFCLASS32
 
#endif
 
/branches/arm/kernel/arch/mips32/include/types.h
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
57,10 → 55,11
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
#define PRIc "u" /**< Format for count_t. */
#define PRIi "u" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/mips32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
35,6 → 35,29
#ifndef KERN_mips32_ARCH_H_
#define KERN_mips32_ARCH_H_
 
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <typedefs.h>
 
extern size_t cpu_count;
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
uint32_t cpumap;
uint32_t cnt;
utask_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
 
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo);
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/mm/page.h
112,21 → 112,21
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Last-level info macros. */
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
140,7 → 140,7
#include <mm/mm.h>
#include <arch/exception.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
153,7 → 153,7
(p->g << PAGE_GLOBAL_SHIFT));
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
/branches/arm/kernel/arch/mips32/include/mm/tlb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,42 → 40,38
#include <arch/mm/asid.h>
#include <arch/exception.h>
 
#ifdef TLBCNT
# define TLB_ENTRY_COUNT TLBCNT
#else
# define TLB_ENTRY_COUNT 48
#endif
#define TLB_ENTRY_COUNT 48
 
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
 
#define TLB_PAGE_MASK_4K (0x000 << 13)
#define TLB_PAGE_MASK_16K (0x003 << 13)
#define TLB_PAGE_MASK_64K (0x00f << 13)
#define TLB_PAGE_MASK_256K (0x03f << 13)
#define TLB_PAGE_MASK_1M (0x0ff << 13)
#define TLB_PAGE_MASK_4M (0x3ff << 13)
#define TLB_PAGE_MASK_16M (0xfff << 13)
#define TLB_PAGE_MASK_4K (0x000 << 13)
#define TLB_PAGE_MASK_16K (0x003 << 13)
#define TLB_PAGE_MASK_64K (0x00f << 13)
#define TLB_PAGE_MASK_256K (0x03f << 13)
#define TLB_PAGE_MASK_1M (0x0ff << 13)
#define TLB_PAGE_MASK_4M (0x3ff << 13)
#define TLB_PAGE_MASK_16M (0xfff << 13)
 
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
 
typedef union {
struct {
#ifdef BIG_ENDIAN
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
#else
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
#endif
} __attribute__ ((packed));
uint32_t value;
163,7 → 159,7
asm volatile ("tlbwr\n\t");
}
 
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
 
extern void tlb_invalid(istate_t *istate);
extern void tlb_refill(istate_t *istate);
/branches/arm/kernel/arch/mips32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
35,12 → 35,14
#ifndef KERN_mips32_FRAME_H_
#define KERN_mips32_FRAME_H_
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <typedefs.h>
 
extern void frame_arch_init(void);
extern void physmem_print(void);
 
/branches/arm/kernel/arch/mips32/include/mm/asid.h
37,7 → 37,7
 
#include <arch/types.h>
 
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */
 
typedef uint8_t asid_t;
 
/branches/arm/kernel/arch/mips32/include/debugger.h
53,7 → 53,7
unative_t instruction; /**< Original instruction */
unative_t nextinstruction; /**< Original instruction following break */
int flags; /**< Flags regarding breakpoint */
count_t counter;
size_t counter;
void (*bkfunc)(void *b, istate_t *istate);
} bpinfo_t;
 
/branches/arm/kernel/arch/mips32/include/drivers/serial.h
File deleted
/branches/arm/kernel/arch/mips32/include/drivers/msim.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
36,16 → 36,10
#define KERN_mips32_MSIM_H_
 
/** Address of devices. */
#define MSIM_VIDEORAM 0x90000000
#define MSIM_KBD_ADDRESS 0x90000000
#define MSIM_KBD_IRQ 2
#define MSIM_VIDEORAM 0x90000000
#define MSIM_KBD_ADDRESS 0x90000000
#define MSIM_KBD_IRQ 2
 
#include <console/chardev.h>
 
void msim_console(devno_t devno);
void msim_kbd_release(void);
void msim_kbd_grab(void);
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/asm.h
36,6 → 36,7
#define KERN_mips32_ASM_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
 
55,7 → 56,11
{
uintptr_t v;
asm volatile ("and %0, $29, %1\n" : "=r" (v) : "r" (~(STACK_SIZE-1)));
asm volatile (
"and %0, $29, %1\n"
: "=r" (v)
: "r" (~(STACK_SIZE-1))
);
return v;
}
63,13 → 68,44
extern void cpu_halt(void);
extern void asm_delay_loop(uint32_t t);
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
uintptr_t entry);
uintptr_t entry);
 
extern ipl_t interrupts_disable(void);
extern ipl_t interrupts_enable(void);
extern void interrupts_restore(ipl_t ipl);
extern ipl_t interrupts_read(void);
extern void asm_delay_loop(uint32_t t);
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/asm/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
/branches/arm/kernel/arch/mips32/include/interrupt.h
38,9 → 38,11
#include <typedefs.h>
#include <arch/exception.h>
 
#define IVT_ITEMS 32
#define IVT_FIRST 0
#define IVT_ITEMS 32
#define IVT_FIRST 0
 
#define VECTOR_TLB_SHOOTDOWN_IPI EXC_Int
 
extern function virtual_timer_fnc;
extern uint32_t count_hi;
 
/branches/arm/kernel/arch/mips32/include/smp/order.h
File deleted
/branches/arm/kernel/arch/mips32/include/smp/dorder.h
0,0 → 1,34
/*
* Copyright (c) 2007 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#ifndef KERN_mips32_DORDER_H_
#define KERN_mips32_DORDER_H_
 
extern void ipi_broadcast_arch(int ipi);
 
#endif
/branches/arm/kernel/arch/mips32/include/atomic.h
35,14 → 35,14
#ifndef KERN_mips32_ATOMIC_H_
#define KERN_mips32_ATOMIC_H_
 
#define atomic_inc(x) ((void) atomic_add(x, 1))
#define atomic_dec(x) ((void) atomic_add(x, -1))
#define atomic_inc(x) ((void) atomic_add(x, 1))
#define atomic_dec(x) ((void) atomic_add(x, -1))
 
#define atomic_postinc(x) (atomic_add(x, 1) - 1)
#define atomic_postdec(x) (atomic_add(x, -1) + 1)
#define atomic_postinc(x) (atomic_add(x, 1) - 1)
#define atomic_postdec(x) (atomic_add(x, -1) + 1)
 
#define atomic_preinc(x) atomic_add(x, 1)
#define atomic_predec(x) atomic_add(x, -1)
#define atomic_preinc(x) atomic_add(x, 1)
#define atomic_predec(x) atomic_add(x, -1)
 
/* Atomic addition of immediate value.
*
54,19 → 54,37
static inline long atomic_add(atomic_t *val, int i)
{
long tmp, v;
 
asm volatile (
"1:\n"
" ll %0, %1\n"
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" move %2, %0\n"
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" move %2, %0\n"
" sc %0, %1\n"
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
" nop\n"
: "=&r" (tmp), "+m" (val->count), "=&r" (v)
: "r" (i), "i" (0)
);
);
return v;
}
 
static inline uint32_t test_and_set(atomic_t *val) {
uint32_t tmp, v;
asm volatile (
"1:\n"
" ll %2, %1\n"
" bnez %2, 2f\n"
" li %0, %3\n"
" sc %0, %1\n"
" beqz %0, 1b\n"
"2:\n"
: "=&r" (tmp), "+m" (val->count), "=&r" (v)
: "i" (1)
);
return v;
}
 
/branches/arm/kernel/arch/mips32/include/cpu.h
42,7 → 42,7
uint32_t imp_num;
uint32_t rev_num;
} cpu_arch_t;
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/exception.h
73,19 → 73,10
uint32_t t5;
uint32_t t6;
uint32_t t7;
uint32_t s0;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t s5;
uint32_t s6;
uint32_t s7;
uint32_t t8;
uint32_t t9;
uint32_t gp;
uint32_t sp;
uint32_t s8;
uint32_t ra;
uint32_t lo;
/branches/arm/kernel/arch/mips32/Makefile.inc
29,87 → 29,51
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_ARCH = mips
BFD = binary
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel
 
KERNEL_LOAD_ADDRESS = 0x80100000
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
 
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss
BITS = 32
 
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS}
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Accepted MACHINEs
#
 
ifeq ($(MACHINE),lgxemul)
BFD_NAME = elf32-tradlittlemips
BFD = binary
GCC_CFLAGS += -DFB_INVERT_ENDIAN -DARCH_HAS_FPU -mips3
ENDIANESS = LE
endif
ifeq ($(MACHINE),bgxemul)
BFD_NAME = elf32-bigmips
BFD = ecoff-bigmips
TARGET = mips-sgi-irix5
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3
BFD_NAME = elf32-tradbigmips
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips
TARGET = mips-linux-gnu
ENDIANESS = BE
GCC_CFLAGS += -D__BE__
endif
ifeq ($(MACHINE),simics)
# SIMICS 4kc emulation is broken, although for instructions
# that do not bother us
BFD_NAME = elf32-tradlittlemips
BFD = elf32-tradlittlemips
GCC_CFLAGS += -mhard-float -mips3 -DTLBCNT=16
TLBCNT = 16
endif
ifeq ($(MACHINE),msim)
BFD_NAME = elf32-tradlittlemips
BFD = binary
GCC_CFLAGS += -mhard-float -mips3
ENDIANESS = LE
GCC_CFLAGS += -mhard-float
endif
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/mips32.c \
arch/$(ARCH)/src/dummy.S \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/exception.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/cache.c \
arch/$(ARCH)/src/debugger.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/msim.c \
arch/$(ARCH)/src/drivers/serial.c \
arch/$(ARCH)/src/smp/order.c
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/mips32.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/exception.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/cache.c \
arch/$(KARCH)/src/debugger.c \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/smp/dorder.c \
arch/$(KARCH)/src/smp/smp.c
/branches/arm/kernel/arch/mips32/src/drivers/msim.c
File deleted
/branches/arm/kernel/arch/mips32/src/drivers/serial.c
File deleted
/branches/arm/kernel/arch/mips32/src/dummy.S
File deleted
/branches/arm/kernel/arch/mips32/src/console.c
File deleted
/branches/arm/kernel/arch/mips32/src/mm/tlb.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,12 → 40,12
#include <arch/cp0.h>
#include <panic.h>
#include <arch.h>
#include <symtab.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <print.h>
#include <debug.h>
#include <align.h>
#include <interrupt.h>
#include <symtab.h>
 
static void tlb_refill_fail(istate_t *);
static void tlb_invalid_fail(istate_t *);
92,15 → 92,15
uintptr_t badvaddr;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
spinlock_lock(&AS->lock);
mutex_lock(&AS->lock);
asid = AS->asid;
spinlock_unlock(&AS->lock);
 
mutex_unlock(&AS->lock);
page_table_lock(AS, true);
 
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
if (!pte) {
switch (pfrc) {
115,7 → 115,7
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
 
199,7 → 199,7
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
 
282,7 → 282,7
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
 
320,19 → 320,14
 
void tlb_refill_fail(istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
char *symbol, *sym2;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
s = get_symtab_entry(istate->ra);
if (s)
sym2 = s;
 
fault_if_from_uspace(istate, "TLB Refill Exception on %p",
symbol = symtab_fmt_name_lookup(istate->epc);
sym2 = symtab_fmt_name_lookup(istate->ra);
fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(),
panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(),
istate->epc, symbol, sym2);
}
 
339,27 → 334,25
 
void tlb_invalid_fail(istate_t *istate)
{
char *symbol = "";
char *symbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Invalid Exception on %p",
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(),
panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
}
 
void tlb_modified_fail(istate_t *istate)
{
char *symbol = "";
char *symbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Modified Exception on %p",
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(),
panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
}
 
429,12 → 422,11
break;
case AS_PF_FAULT:
page_table_lock(AS, true);
printf("Page fault.\n");
*pfrc = AS_PF_FAULT;
return NULL;
break;
default:
panic("unexpected rc (%d)\n", rc);
panic("Unexpected rc (%d).", rc);
}
}
568,7 → 560,7
* @param page First page whose TLB entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
unsigned int i;
ipl_t ipl;
/branches/arm/kernel/arch/mips32/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,22 → 40,22
#include <mm/asid.h>
#include <config.h>
#include <arch/drivers/msim.h>
#include <arch/drivers/serial.h>
#include <print.h>
 
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K
#define ZERO_FRAMES 2048
#define ZERO_PAGE_WIDTH 18 /* 256K */
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
#define ZERO_PAGE_ASID ASID_INVALID
#define ZERO_PAGE_TLBI 0
#define ZERO_PAGE_ADDR 0
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K
#define ZERO_FRAMES 2048
#define ZERO_PAGE_WIDTH 18 /* 256K */
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
#define ZERO_PAGE_ASID ASID_INVALID
#define ZERO_PAGE_TLBI 0
#define ZERO_PAGE_ADDR 0
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
 
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
#define ZERO_PAGE_VALUE_KSEG1(frame) \
(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
 
#define MAX_REGIONS 32
#define MAX_REGIONS 32
 
typedef struct {
pfn_t start;
62,10 → 62,9
pfn_t count;
} phys_region_t;
 
static count_t phys_regions_count = 0;
static size_t phys_regions_count = 0;
static phys_region_t phys_regions[MAX_REGIONS];
 
 
/** Check whether frame is available
*
* Returns true if given frame is generally available for use.
75,7 → 74,7
*/
static bool frame_available(pfn_t frame)
{
#if MACHINE == msim
#ifdef MACHINE_msim
/* MSIM device (dprinter) */
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
return false;
84,14 → 83,8
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#if MACHINE == simics
/* Simics device (serial line) */
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#if (MACHINE == lgxemul) || (MACHINE == bgxemul)
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
/* gxemul devices */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
0x10000000, MB2SIZE(256)))
126,7 → 119,7
/* Init tasks */
bool safe = true;
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++)
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
181,7 → 174,7
cp0_entry_lo1_write(0);
cp0_entry_hi_write(0);
 
count_t i;
size_t i;
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbwi();
218,7 → 211,7
ZERO_PAGE_VALUE = 0xdeadbeef;
if (ZERO_PAGE_VALUE != 0xdeadbeef)
avail = false;
#if (MACHINE == lgxemul) || (MACHINE == bgxemul)
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
else {
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd;
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd)
258,7 → 251,7
printf("Base Size\n");
printf("---------- ----------\n");
count_t i;
size_t i;
for (i = 0; i < phys_regions_count; i++) {
printf("%#010x %10u\n",
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count));
/branches/arm/kernel/arch/mips32/src/mm/page.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
35,6 → 35,7
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <mm/page.h>
#include <mm/frame.h>
 
void page_arch_init(void)
{
/branches/arm/kernel/arch/mips32/src/mips32.c
33,20 → 33,17
*/
 
#include <arch.h>
#include <arch/boot.h>
#include <arch/cp0.h>
#include <arch/exception.h>
#include <mm/as.h>
 
#include <userspace.h>
#include <arch/console.h>
#include <memstr.h>
#include <proc/thread.h>
#include <proc/uarg.h>
#include <print.h>
#include <console/console.h>
#include <syscall/syscall.h>
#include <sysinfo/sysinfo.h>
 
#include <arch/interrupt.h>
#include <console/chardev.h>
#include <arch/barrier.h>
53,39 → 50,51
#include <arch/debugger.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <macros.h>
#include <ddi/device.h>
 
#include <config.h>
#include <string.h>
#include <arch/drivers/msim.h>
#include <arch/asm/regname.h>
 
/* Size of the code jumping to the exception handler code
* - J+NOP
/* Size of the code jumping to the exception handler code
* - J+NOP
*/
#define EXCEPTION_JUMP_SIZE 8
#define EXCEPTION_JUMP_SIZE 8
 
#define TLB_EXC ((char *) 0x80000000)
#define NORM_EXC ((char *) 0x80000180)
#define CACHE_EXC ((char *) 0x80000100)
#define TLB_EXC ((char *) 0x80000000)
#define NORM_EXC ((char *) 0x80000180)
#define CACHE_EXC ((char *) 0x80000100)
 
 
/* Why the linker moves the variable 64K away in assembler
* when not in .text section ????????
* when not in .text section?
*/
 
/* Stack pointer saved when entering user mode */
uintptr_t supervisor_sp __attribute__ ((section (".text")));
/* Stack pointer saved when entering user mode */
/* TODO: How do we do it on SMP system???? */
bootinfo_t bootinfo __attribute__ ((section (".text")));
 
void arch_pre_main(void)
size_t cpu_count = 0;
 
/** Performs mips32-specific initialization before main_bsp() is called. */
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
{
/* Setup usermode */
init.cnt = bootinfo.cnt;
init.cnt = bootinfo->cnt;
uint32_t i;
size_t i;
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
init.tasks[i].addr = bootinfo->tasks[i].addr;
init.tasks[i].size = bootinfo->tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo->tasks[i].name);
}
for (i = 0; i < bootinfo.cnt; i++) {
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
if ((bootinfo->cpumap & (1 << i)) != 0)
cpu_count++;
}
}
 
111,12 → 120,12
*/
cp0_status_write(cp0_status_read() &
~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit));
 
/*
* Mask all interrupts
/*
* Mask all interrupts
*/
cp0_mask_all_int();
debugger_init();
}
 
123,12 → 132,23
void arch_post_mm_init(void)
{
interrupt_init();
console_init(device_assign_devno());
#ifdef CONFIG_FB
/* GXemul framebuffer */
fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8);
#endif
sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1);
fb_properties_t gxemul_prop = {
.addr = 0x12000000,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&gxemul_prop);
#else
#ifdef CONFIG_MIPS_PRN
dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
#endif /* CONFIG_MIPS_PRN */
#endif /* CONFIG_FB */
}
 
void arch_post_cpu_init(void)
141,8 → 161,37
 
void arch_post_smp_init(void)
{
#ifdef CONFIG_MIPS_KBD
/*
* Initialize the msim/GXemul keyboard port. Then initialize the serial line
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts.
*/
dsrlnin_instance_t *dsrlnin_instance
= dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ);
if (dsrlnin_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
dsrlnin_wire(dsrlnin_instance, srln);
cp0_unmask_int(MSIM_KBD_IRQ);
}
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
#endif
}
 
void calibrate_delay_loop(void)
{
}
 
void userspace(uspace_arg_t *kernel_uarg)
{
/* EXL = 1, UM = 1, IE = 1 */
153,8 → 202,7
(uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_entry);
while (1)
;
while (1);
}
 
/** Perform mips32 specific tasks needed before the new task is run. */
186,10 → 234,36
void arch_reboot(void)
{
___halt();
while (1)
;
while (1);
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
void arch_grab_console(void)
{
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/asm.S
27,17 → 27,17
#
 
#include <arch/asm/regname.h>
 
.text
 
.macro cp0_read reg
mfc0 $2,\reg
mfc0 $2, \reg
j $31
nop
.endm
 
.macro cp0_write reg
mtc0 $4,\reg
mtc0 $4, \reg
j $31
nop
.endm
46,6 → 46,11
.set noreorder
.set nomacro
 
.global asm_delay_loop
asm_delay_loop:
j $31
nop
 
.global cpu_halt
cpu_halt:
j cpu_halt
58,6 → 63,12
nop
 
 
.global memsetw
memsetw:
j _memsetw
nop
 
 
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
66,235 → 77,238
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
addiu $v0,$a1,3
li $v1,-4 # 0xfffffffffffffffc
and $v0,$v0,$v1
beq $a1,$v0,3f
move $t0,$a0
move $t2,$a0 # save dst
move $t2, $a0 # save dst
addiu $v0, $a1, 3
li $v1, -4 # 0xfffffffffffffffc
and $v0, $v0, $v1
beq $a1, $v0, 3f
move $t0, $a0
0:
beq $a2, $zero, 2f
move $a3, $zero
1:
addu $v0, $a1, $a3
lbu $a0, 0($v0)
addu $v1, $t0, $a3
addiu $a3, $a3, 1
bne $a3, $a2, 1b
sb $a0, 0($v1)
2:
jr $ra
move $v0, $t2
3:
addiu $v0, $a0, 3
and $v0, $v0, $v1
bne $a0, $v0, 0b
srl $t1, $a2, 2
beq $t1, $zero, 5f
move $a3, $zero
move $a3, $zero
move $a0, $zero
4:
addu $v0, $a1, $a0
lw $v1, 0($v0)
addiu $a3, $a3, 1
addu $v0, $t0, $a0
sw $v1, 0($v0)
bne $a3, $t1, 4b
addiu $a0, $a0, 4
5:
andi $a2, $a2, 0x3
beq $a2, $zero, 2b
nop
sll $v0, $a3, 2
addu $t1, $v0, $t0
move $a3, $zero
addu $t0, $v0, $a1
6:
addu $v0, $t0, $a3
lbu $a0, 0($v0)
addu $v1, $t1, $a3
addiu $a3, $a3, 1
bne $a3, $a2, 6b
sb $a0, 0($v1)
jr $ra
move $v0, $t2
 
0:
beq $a2,$zero,2f
move $a3,$zero
 
1:
addu $v0,$a1,$a3
lbu $a0,0($v0)
addu $v1,$t0,$a3
addiu $a3,$a3,1
bne $a3,$a2,1b
sb $a0,0($v1)
 
2:
jr $ra
move $v0,$t2
 
3:
addiu $v0,$a0,3
and $v0,$v0,$v1
bne $a0,$v0,0b
srl $t1,$a2,2
 
beq $t1,$zero,5f
move $a3,$zero
 
move $a3,$zero
move $a0,$zero
4:
addu $v0,$a1,$a0
lw $v1,0($v0)
addiu $a3,$a3,1
addu $v0,$t0,$a0
sw $v1,0($v0)
bne $a3,$t1,4b
addiu $a0,$a0,4
 
5:
andi $a2,$a2,0x3
beq $a2,$zero,2b
nop
 
sll $v0,$a3,2
addu $t1,$v0,$t0
move $a3,$zero
addu $t0,$v0,$a1
6:
addu $v0,$t0,$a3
lbu $a0,0($v0)
addu $v1,$t1,$a3
addiu $a3,$a3,1
bne $a3,$a2,6b
sb $a0,0($v1)
 
jr $ra
move $v0,$t2
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
jr $ra
move $v0, $zero
jr $ra
move $v0, $zero
 
 
 
.macro fpu_gp_save reg ctx
mfc1 $t0,$\reg
sw $t0, \reg*4(\ctx)
mfc1 $t0, $\reg
sw $t0, \reg * 4(\ctx)
.endm
 
.macro fpu_gp_restore reg ctx
lw $t0, \reg*4(\ctx)
mtc1 $t0,$\reg
lw $t0, \reg * 4(\ctx)
mtc1 $t0, $\reg
.endm
 
.macro fpu_ct_save reg ctx
cfc1 $t0,$1
sw $t0, (\reg+32)*4(\ctx)
cfc1 $t0, $1
sw $t0, (\reg + 32) * 4(\ctx)
.endm
 
.macro fpu_ct_restore reg ctx
lw $t0, (\reg+32)*4(\ctx)
ctc1 $t0,$\reg
lw $t0, (\reg + 32) * 4(\ctx)
ctc1 $t0, $\reg
.endm
 
 
.global fpu_context_save
fpu_context_save:
#ifdef ARCH_HAS_FPU
fpu_gp_save 0,$a0
fpu_gp_save 1,$a0
fpu_gp_save 2,$a0
fpu_gp_save 3,$a0
fpu_gp_save 4,$a0
fpu_gp_save 5,$a0
fpu_gp_save 6,$a0
fpu_gp_save 7,$a0
fpu_gp_save 8,$a0
fpu_gp_save 9,$a0
fpu_gp_save 10,$a0
fpu_gp_save 11,$a0
fpu_gp_save 12,$a0
fpu_gp_save 13,$a0
fpu_gp_save 14,$a0
fpu_gp_save 15,$a0
fpu_gp_save 16,$a0
fpu_gp_save 17,$a0
fpu_gp_save 18,$a0
fpu_gp_save 19,$a0
fpu_gp_save 20,$a0
fpu_gp_save 21,$a0
fpu_gp_save 22,$a0
fpu_gp_save 23,$a0
fpu_gp_save 24,$a0
fpu_gp_save 25,$a0
fpu_gp_save 26,$a0
fpu_gp_save 27,$a0
fpu_gp_save 28,$a0
fpu_gp_save 29,$a0
fpu_gp_save 30,$a0
fpu_gp_save 31,$a0
 
fpu_ct_save 1,$a0
fpu_ct_save 2,$a0
fpu_ct_save 3,$a0
fpu_ct_save 4,$a0
fpu_ct_save 5,$a0
fpu_ct_save 6,$a0
fpu_ct_save 7,$a0
fpu_ct_save 8,$a0
fpu_ct_save 9,$a0
fpu_ct_save 10,$a0
fpu_ct_save 11,$a0
fpu_ct_save 12,$a0
fpu_ct_save 13,$a0
fpu_ct_save 14,$a0
fpu_ct_save 15,$a0
fpu_ct_save 16,$a0
fpu_ct_save 17,$a0
fpu_ct_save 18,$a0
fpu_ct_save 19,$a0
fpu_ct_save 20,$a0
fpu_ct_save 21,$a0
fpu_ct_save 22,$a0
fpu_ct_save 23,$a0
fpu_ct_save 24,$a0
fpu_ct_save 25,$a0
fpu_ct_save 26,$a0
fpu_ct_save 27,$a0
fpu_ct_save 28,$a0
fpu_ct_save 29,$a0
fpu_ct_save 30,$a0
fpu_ct_save 31,$a0
#endif
#ifdef CONFIG_FPU
fpu_gp_save 0, $a0
fpu_gp_save 1, $a0
fpu_gp_save 2, $a0
fpu_gp_save 3, $a0
fpu_gp_save 4, $a0
fpu_gp_save 5, $a0
fpu_gp_save 6, $a0
fpu_gp_save 7, $a0
fpu_gp_save 8, $a0
fpu_gp_save 9, $a0
fpu_gp_save 10, $a0
fpu_gp_save 11, $a0
fpu_gp_save 12, $a0
fpu_gp_save 13, $a0
fpu_gp_save 14, $a0
fpu_gp_save 15, $a0
fpu_gp_save 16, $a0
fpu_gp_save 17, $a0
fpu_gp_save 18, $a0
fpu_gp_save 19, $a0
fpu_gp_save 20, $a0
fpu_gp_save 21, $a0
fpu_gp_save 22, $a0
fpu_gp_save 23, $a0
fpu_gp_save 24, $a0
fpu_gp_save 25, $a0
fpu_gp_save 26, $a0
fpu_gp_save 27, $a0
fpu_gp_save 28, $a0
fpu_gp_save 29, $a0
fpu_gp_save 30, $a0
fpu_gp_save 31, $a0
fpu_ct_save 1, $a0
fpu_ct_save 2, $a0
fpu_ct_save 3, $a0
fpu_ct_save 4, $a0
fpu_ct_save 5, $a0
fpu_ct_save 6, $a0
fpu_ct_save 7, $a0
fpu_ct_save 8, $a0
fpu_ct_save 9, $a0
fpu_ct_save 10, $a0
fpu_ct_save 11, $a0
fpu_ct_save 12, $a0
fpu_ct_save 13, $a0
fpu_ct_save 14, $a0
fpu_ct_save 15, $a0
fpu_ct_save 16, $a0
fpu_ct_save 17, $a0
fpu_ct_save 18, $a0
fpu_ct_save 19, $a0
fpu_ct_save 20, $a0
fpu_ct_save 21, $a0
fpu_ct_save 22, $a0
fpu_ct_save 23, $a0
fpu_ct_save 24, $a0
fpu_ct_save 25, $a0
fpu_ct_save 26, $a0
fpu_ct_save 27, $a0
fpu_ct_save 28, $a0
fpu_ct_save 29, $a0
fpu_ct_save 30, $a0
fpu_ct_save 31, $a0
#endif
j $ra
nop
 
.global fpu_context_restore
fpu_context_restore:
#ifdef ARCH_HAS_FPU
fpu_gp_restore 0,$a0
fpu_gp_restore 1,$a0
fpu_gp_restore 2,$a0
fpu_gp_restore 3,$a0
fpu_gp_restore 4,$a0
fpu_gp_restore 5,$a0
fpu_gp_restore 6,$a0
fpu_gp_restore 7,$a0
fpu_gp_restore 8,$a0
fpu_gp_restore 9,$a0
fpu_gp_restore 10,$a0
fpu_gp_restore 11,$a0
fpu_gp_restore 12,$a0
fpu_gp_restore 13,$a0
fpu_gp_restore 14,$a0
fpu_gp_restore 15,$a0
fpu_gp_restore 16,$a0
fpu_gp_restore 17,$a0
fpu_gp_restore 18,$a0
fpu_gp_restore 19,$a0
fpu_gp_restore 20,$a0
fpu_gp_restore 21,$a0
fpu_gp_restore 22,$a0
fpu_gp_restore 23,$a0
fpu_gp_restore 24,$a0
fpu_gp_restore 25,$a0
fpu_gp_restore 26,$a0
fpu_gp_restore 27,$a0
fpu_gp_restore 28,$a0
fpu_gp_restore 29,$a0
fpu_gp_restore 30,$a0
fpu_gp_restore 31,$a0
 
fpu_ct_restore 1,$a0
fpu_ct_restore 2,$a0
fpu_ct_restore 3,$a0
fpu_ct_restore 4,$a0
fpu_ct_restore 5,$a0
fpu_ct_restore 6,$a0
fpu_ct_restore 7,$a0
fpu_ct_restore 8,$a0
fpu_ct_restore 9,$a0
fpu_ct_restore 10,$a0
fpu_ct_restore 11,$a0
fpu_ct_restore 12,$a0
fpu_ct_restore 13,$a0
fpu_ct_restore 14,$a0
fpu_ct_restore 15,$a0
fpu_ct_restore 16,$a0
fpu_ct_restore 17,$a0
fpu_ct_restore 18,$a0
fpu_ct_restore 19,$a0
fpu_ct_restore 20,$a0
fpu_ct_restore 21,$a0
fpu_ct_restore 22,$a0
fpu_ct_restore 23,$a0
fpu_ct_restore 24,$a0
fpu_ct_restore 25,$a0
fpu_ct_restore 26,$a0
fpu_ct_restore 27,$a0
fpu_ct_restore 28,$a0
fpu_ct_restore 29,$a0
fpu_ct_restore 30,$a0
fpu_ct_restore 31,$a0
#endif
#ifdef CONFIG_FPU
fpu_gp_restore 0, $a0
fpu_gp_restore 1, $a0
fpu_gp_restore 2, $a0
fpu_gp_restore 3, $a0
fpu_gp_restore 4, $a0
fpu_gp_restore 5, $a0
fpu_gp_restore 6, $a0
fpu_gp_restore 7, $a0
fpu_gp_restore 8, $a0
fpu_gp_restore 9, $a0
fpu_gp_restore 10, $a0
fpu_gp_restore 11, $a0
fpu_gp_restore 12, $a0
fpu_gp_restore 13, $a0
fpu_gp_restore 14, $a0
fpu_gp_restore 15, $a0
fpu_gp_restore 16, $a0
fpu_gp_restore 17, $a0
fpu_gp_restore 18, $a0
fpu_gp_restore 19, $a0
fpu_gp_restore 20, $a0
fpu_gp_restore 21, $a0
fpu_gp_restore 22, $a0
fpu_gp_restore 23, $a0
fpu_gp_restore 24, $a0
fpu_gp_restore 25, $a0
fpu_gp_restore 26, $a0
fpu_gp_restore 27, $a0
fpu_gp_restore 28, $a0
fpu_gp_restore 29, $a0
fpu_gp_restore 30, $a0
fpu_gp_restore 31, $a0
fpu_ct_restore 1, $a0
fpu_ct_restore 2, $a0
fpu_ct_restore 3, $a0
fpu_ct_restore 4, $a0
fpu_ct_restore 5, $a0
fpu_ct_restore 6, $a0
fpu_ct_restore 7, $a0
fpu_ct_restore 8, $a0
fpu_ct_restore 9, $a0
fpu_ct_restore 10, $a0
fpu_ct_restore 11, $a0
fpu_ct_restore 12, $a0
fpu_ct_restore 13, $a0
fpu_ct_restore 14, $a0
fpu_ct_restore 15, $a0
fpu_ct_restore 16, $a0
fpu_ct_restore 17, $a0
fpu_ct_restore 18, $a0
fpu_ct_restore 19, $a0
fpu_ct_restore 20, $a0
fpu_ct_restore 21, $a0
fpu_ct_restore 22, $a0
fpu_ct_restore 23, $a0
fpu_ct_restore 24, $a0
fpu_ct_restore 25, $a0
fpu_ct_restore 26, $a0
fpu_ct_restore 27, $a0
fpu_ct_restore 28, $a0
fpu_ct_restore 29, $a0
fpu_ct_restore 30, $a0
fpu_ct_restore 31, $a0
#endif
j $ra
nop
/branches/arm/kernel/arch/mips32/src/exception.c
41,13 → 41,12
#include <arch.h>
#include <debug.h>
#include <proc/thread.h>
#include <symtab.h>
#include <print.h>
#include <interrupt.h>
#include <func.h>
#include <console/kconsole.h>
#include <ddi/irq.h>
#include <arch/debugger.h>
#include <symtab.h>
 
static char * exctable[] = {
"Interrupt",
74,25 → 73,21
 
static void print_regdump(istate_t *istate)
{
char *pcsymbol = "";
char *rasymbol = "";
char *pcsymbol, *rasymbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
pcsymbol = s;
s = get_symtab_entry(istate->ra);
if (s)
rasymbol = s;
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp);
pcsymbol = symtab_fmt_name_lookup(istate->epc);
rasymbol = symtab_fmt_name_lookup(istate->ra);
 
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol,
istate->ra, rasymbol, istate->sp);
}
 
static void unhandled_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]);
fault_if_from_uspace(istate, "Unhandled exception %s.", exctable[n]);
print_regdump(istate);
panic("unhandled exception %s\n", exctable[n]);
panic("Unhandled exception %s.", exctable[n]);
}
 
static void reserved_instr_exception(int n, istate_t *istate)
133,8 → 128,8
if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
scheduler_fpu_lazy_request();
else {
fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception");
panic("unhandled Coprocessor Unusable Exception\n");
fault_if_from_uspace(istate, "Unhandled Coprocessor Unusable Exception.");
panic("Unhandled Coprocessor Unusable Exception.");
}
}
#endif
145,7 → 140,7
int i;
/* decode interrupt number and process the interrupt */
cause = (cp0_cause_read() >> 8) &0xff;
cause = (cp0_cause_read() >> 8) & 0xff;
for (i = 0; i < 8; i++) {
if (cause & (1 << i)) {
154,7 → 149,7
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
161,7 → 156,8
* Spurious interrupt.
*/
#ifdef CONFIG_DEBUG
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, i);
printf("cpu%u: spurious interrupt (inum=%d)\n",
CPU->id, i);
#endif
}
}
171,7 → 167,7
/** Handle syscall userspace call */
static void syscall_exception(int n, istate_t *istate)
{
panic("Syscall is handled through shortcut");
panic("Syscall is handled through shortcut.");
}
 
void exception_init(void)
/branches/arm/kernel/arch/mips32/src/debugger.c
37,16 → 37,18
#include <memstr.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <arch.h>
#include <arch/cp0.h>
#include <func.h>
#include <symtab.h>
 
bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
 
#ifdef CONFIG_KCONSOLE
 
static int cmd_print_breakpoints(cmd_arg_t *argv);
static cmd_info_t bkpts_info = {
.name = "bkpts",
123,10 → 125,12
{0, 0} /* EndOfTable */
};
 
 
/** Test, if the given instruction is a jump or branch instruction
*
* @param instr Instruction code
* @return true - it is jump instruction, false otherwise
*
*/
static bool is_jump(unative_t instr)
{
158,7 → 162,7
for (i = 0; i < BKPOINTS_MAX; i++) {
if (breakpoints[i].address == (uintptr_t)argv->intval) {
printf("Duplicate breakpoint %d.\n", i);
spinlock_unlock(&bkpoints_lock);
spinlock_unlock(&bkpoint_lock);
return 0;
} else if (breakpoints[i].address == (uintptr_t)argv->intval +
sizeof(unative_t) || breakpoints[i].address ==
165,10 → 169,10
(uintptr_t)argv->intval - sizeof(unative_t)) {
printf("Adjacent breakpoints not supported, conflict "
"with %d.\n", i);
spinlock_unlock(&bkpoints_lock);
spinlock_unlock(&bkpoint_lock);
return 0;
}
}
 
for (i = 0; i < BKPOINTS_MAX; i++)
255,8 → 259,9
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
symbol = symtab_fmt_name_lookup(
breakpoints[i].address);
 
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
267,6 → 272,8
return 1;
}
 
#endif
 
/** Initialize debugger */
void debugger_init()
{
274,22 → 281,24
 
for (i = 0; i < BKPOINTS_MAX; i++)
breakpoints[i].address = NULL;
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&bkpts_info);
if (!cmd_register(&bkpts_info))
panic("could not register command %s\n", bkpts_info.name);
printf("Cannot register command %s\n", bkpts_info.name);
 
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
panic("could not register command %s\n", delbkpt_info.name);
printf("Cannot register command %s\n", delbkpt_info.name);
 
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
printf("Cannot register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addbkpte_info);
if (!cmd_register(&addbkpte_info))
panic("could not register command %s\n", addbkpte_info.name);
printf("Cannot register command %s\n", addbkpte_info.name);
#endif
}
 
/** Handle breakpoint
308,7 → 317,7
 
/* test branch delay slot */
if (cp0_cause_read() & 0x80000000)
panic("Breakpoint in branch delay slot not supported.\n");
panic("Breakpoint in branch delay slot not supported.");
 
spinlock_lock(&bkpoint_lock);
for (i = 0; i < BKPOINTS_MAX; i++) {
340,9 → 349,10
if (cur->flags & BKPOINT_INPROG)
printf("Warning: breakpoint recursion\n");
if (!(cur->flags & BKPOINT_FUNCCALL))
if (!(cur->flags & BKPOINT_FUNCCALL)) {
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
get_symtab_entry(istate->epc));
symtab_fmt_name_lookup(istate->epc));
}
 
/* Return first instruction back */
((uint32_t *)cur->address)[0] = cur->instruction;
355,8 → 365,9
}
cur->flags |= BKPOINT_INPROG;
} else {
printf("***Breakpoint %p in %s.\n", fireaddr,
get_symtab_entry(fireaddr));
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
symtab_fmt_name_lookup(fireaddr));
 
/* Move on to next instruction */
istate->epc += 4;
}
367,19 → 378,20
if (cur->bkfunc)
cur->bkfunc(cur, istate);
} else {
printf("***Type 'exit' to exit kconsole.\n");
#ifdef CONFIG_KCONSOLE
/* This disables all other processors - we are not SMP,
* actually this gets us to cpu_halt, if scheduler() is run
* - we generally do not want scheduler to be run from debug,
* so this is a good idea
*/
atomic_set(&haltstate,1);
atomic_set(&haltstate, 1);
spinlock_unlock(&bkpoint_lock);
 
kconsole("debug");
 
kconsole("debug", "Debug console ready.\n", false);
spinlock_lock(&bkpoint_lock);
atomic_set(&haltstate,0);
atomic_set(&haltstate, 0);
#endif
}
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
/* Remove one-shot breakpoint */
/branches/arm/kernel/arch/mips32/src/interrupt.c
41,8 → 41,9
#include <ipc/sysipc.h>
#include <ddi/device.h>
 
#define IRQ_COUNT 8
#define TIMER_IRQ 7
#define IRQ_COUNT 8
#define TIMER_IRQ 7
#define DORDER_IRQ 5
 
function virtual_timer_fnc = NULL;
static irq_t timer_irq;
100,12 → 101,12
cp0_compare_write(nextcount);
}
 
static irq_ownership_t timer_claim(void)
static irq_ownership_t timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
static void timer_irq_handler(irq_t *irq, void *arg, ...)
static void timer_irq_handler(irq_t *irq)
{
unsigned long drift;
/branches/arm/kernel/arch/mips32/src/start.S
31,7 → 31,7
#include <arch/asm/boot.h>
#include <arch/context_offset.h>
#include <arch/stack.h>
 
.text
 
.set noat
75,18 → 75,6
mfhi $at
sw $at, EOFFSET_HI(\r)
#ifdef CONFIG_DEBUG_ALLREGS
sw $s0, EOFFSET_S0(\r)
sw $s1, EOFFSET_S1(\r)
sw $s2, EOFFSET_S2(\r)
sw $s3, EOFFSET_S3(\r)
sw $s4, EOFFSET_S4(\r)
sw $s5, EOFFSET_S5(\r)
sw $s6, EOFFSET_S6(\r)
sw $s7, EOFFSET_S7(\r)
sw $s8, EOFFSET_S8(\r)
#endif
sw $gp, EOFFSET_GP(\r)
sw $ra, EOFFSET_RA(\r)
sw $k1, EOFFSET_K1(\r)
132,17 → 120,6
lw $t8, EOFFSET_T8(\r)
lw $t9, EOFFSET_T9(\r)
#ifdef CONFIG_DEBUG_ALLREGS
lw $s0, EOFFSET_S0(\r)
lw $s1, EOFFSET_S1(\r)
lw $s2, EOFFSET_S2(\r)
lw $s3, EOFFSET_S3(\r)
lw $s4, EOFFSET_S4(\r)
lw $s5, EOFFSET_S5(\r)
lw $s6, EOFFSET_S6(\r)
lw $s7, EOFFSET_S7(\r)
lw $s8, EOFFSET_S8(\r)
#endif
lw $gp, EOFFSET_GP(\r)
lw $ra, EOFFSET_RA(\r)
lw $k1, EOFFSET_K1(\r)
175,9 → 152,9
ori $k0, $k0, %lo(supervisor_sp)
# Move $k0 (superveisor_sp)
lw $k0, 0($k0)
1:
1:
.endm
 
.org 0x0
kernel_image_start:
/* Load temporary stack */
184,31 → 161,12
lui $sp, %hi(end_stack)
ori $sp, $sp, %lo(end_stack)
/* $a1 contains physical address of bootinfo_t */
/* $a2 contains size of bootinfo_t */
beq $a2, $0, bootinfo_end
/* Not sure about this, but might be needed for PIC code???? */
/* Not sure about this, but might
be needed for PIC code */
lui $gp, 0x8000
lui $a3, %hi(bootinfo)
ori $a3, $a3, %lo(bootinfo)
/* $a1 contains physical address of bootinfo_t */
bootinfo_loop:
lw $v0, 0($a1)
sw $v0, 0($a3)
addi $a1, $a1, 4
addi $a3, $a3, 4
addi $a2, $a2, -4
bgtz $a2, bootinfo_loop
nop
bootinfo_end:
jal arch_pre_main
nop
228,8 → 186,8
 
exception_entry:
j exception_handler
nop
nop
 
exception_handler:
KERNEL_STACK_TO_K0
sub $k0, REGISTER_SPACE
238,17 → 196,17
mfc0 $k0, $cause
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
sub $k0, 8 # 8 = SYSCALL
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
sub $k0, 8 # 8 = SYSCALL
beqz $k0, syscall_shortcut
add $k0, 8 # Revert $k0 back to correct exc number
add $k0, 8 # Revert $k0 back to correct exc number
REGISTERS_STORE_AND_EXC_RESET $sp
move $a1, $sp
jal exc_dispatch # exc_dispatch(excno, register_space)
jal exc_dispatch # exc_dispatch(excno, register_space)
move $a0, $k0
 
REGISTERS_LOAD $sp
/branches/arm/kernel/arch/mips32/src/smp/order.c
File deleted
/branches/arm/kernel/arch/mips32/src/smp/smp.c
0,0 → 1,53
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup mips32
* @{
*/
/** @file
*/
 
#include <config.h>
#include <smp/smp.h>
#include <arch/arch.h>
 
#ifdef CONFIG_SMP
 
void smp_init(void)
{
config.cpu_count = cpu_count;
}
 
void kmp(void *arg __attribute__((unused)))
{
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/smp/dorder.c
0,0 → 1,47
/*
* Copyright (c) 2007 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup mips32
* @{
*/
/** @file
*/
 
#include <arch/smp/dorder.h>
 
#define MSIM_DORDER_ADDRESS 0xB0000004
 
void ipi_broadcast_arch(int ipi)
{
#ifdef CONFIG_SMP
*((volatile unsigned int *) MSIM_DORDER_ADDRESS) = 0x7FFFFFFF;
#endif
}
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/fpu_context.c
40,7 → 40,7
 
void fpu_disable(void)
{
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit);
#endif
}
47,7 → 47,7
 
void fpu_enable(void)
{
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
cp0_status_write(cp0_status_read() | cp0_status_fpu_bit);
#endif
}
/branches/arm/kernel/arch/mips32/src/cache.c
38,7 → 38,7
 
void cache_error(istate_t *istate)
{
panic("cache_error exception (epc=%p)\n", istate->epc);
panic("cache_error exception (epc=%p).", istate->epc);
}
 
/** @}
/branches/arm/kernel/arch/mips32/src/cpu/cpu.c
48,7 → 48,7
{ "MIPS", "R2000" }, /* 0x01 */
{ "MIPS", "R3000" }, /* 0x02 */
{ "MIPS", "R6000" }, /* 0x03 */
{ "MIPS", " R4000/R4400" }, /* 0x04 */
{ "MIPS", "R4000/R4400" }, /* 0x04 */
{ "LSI Logic", "R3000" }, /* 0x05 */
{ "MIPS", "R6000A" }, /* 0x06 */
{ "IDT", "3051/3052" }, /* 0x07 */
123,9 → 123,9
data = &imp_data[m->arch.imp_num];
}
 
printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n",
printf("cpu%u: %s %s (rev=%d.%d, imp=%d)\n",
m->id, data->vendor, data->model, m->arch.rev_num >> 4,
m->arch.rev_num & 0xf, m->arch.imp_num);
m->arch.rev_num & 0x0f, m->arch.imp_num);
}
 
/** @}
/branches/arm/kernel/arch/mips32/_link.ld.in
1,15 → 1,17
/*
* MIPS32 linker script
*
* MIPS32 linker script
*
* kernel text
* kernel data
*
*
*/
 
#undef mips
#define mips mips
 
#define KERNEL_LOAD_ADDRESS 0x80100000
 
OUTPUT_ARCH(mips)
 
ENTRY(kernel_image_start)
 
SECTIONS {
21,9 → 23,9
}
.data : {
kdata_start = .;
*(.data); /* initialized data */
*(.data); /* initialized data */
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
33,21 → 35,21
*(.reginfo);
*(.sbss);
*(.scommon);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*);
*(symtab.*);
}
_gp = . + 0x8000;
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
 
kdata_end = .;
 
/DISCARD/ : {
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
}
}
/branches/arm/kernel/arch/ia64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ia64/include/ski/ski.h
File deleted
/branches/arm/kernel/arch/ia64/include/mm/tlb.h
35,9 → 35,6
#ifndef KERN_ia64_TLB_H_
#define KERN_ia64_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
#include <arch/interrupt.h>
46,8 → 43,8
/** Data and instruction Translation Register indices. */
#define DTR_KERNEL 0
#define ITR_KERNEL 0
#define DTR_KSTACK1 1
#define DTR_KSTACK2 2
#define DTR_KSTACK1 4
#define DTR_KSTACK2 5
 
/** Portion of TLB insertion format data structure. */
union tlb_entry {
79,12 → 76,12
extern void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
extern void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
 
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr);
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr);
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr);
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, size_t tr);
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr);
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr);
 
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr);
extern void dtr_purge(uintptr_t page, count_t width);
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, size_t tr);
extern void dtr_purge(uintptr_t page, size_t width);
 
extern void dtc_pte_copy(pte_t *t);
extern void itc_pte_copy(pte_t *t);
95,6 → 92,7
extern void data_dirty_bit_fault(uint64_t vector, istate_t *istate);
extern void instruction_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_rights_fault(uint64_t vector, istate_t *istate);
extern void page_not_present(uint64_t vector, istate_t *istate);
 
#endif
/branches/arm/kernel/arch/ia64/include/mm/page.h
46,8 → 46,25
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 28 /* 256M */
#define IO_PAGE_WIDTH 26 /* 64M */
#define FW_PAGE_WIDTH 28 /* 256M */
 
#define USPACE_IO_PAGE_WIDTH 12 /* 4K */
 
 
/*
* Statically mapped IO spaces - offsets to 0xe...00 of virtual addresses
* because of "minimal virtual bits implemented is 51" it is possible to
* have values up to 0x0007000000000000
*/
 
/* Firmware area (bellow 4GB in phys mem) */
#define FW_OFFSET 0x00000000F0000000
/* Legacy IO space */
#define IO_OFFSET 0x0001000000000000
/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */
#define VIO_OFFSET 0x0002000000000000
 
 
#define PPN_SHIFT 12
 
#define VRN_SHIFT 61
62,8 → 79,8
 
#define REGION_REGISTERS 8
 
#define KA2PA(x) ((uintptr_t) (x-(VRN_KERNEL<<VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x+(VRN_KERNEL<<VRN_SHIFT)))
#define KA2PA(x) ((uintptr_t) (x - (VRN_KERNEL << VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x + (VRN_KERNEL << VRN_SHIFT)))
 
#define VHPT_WIDTH 20 /* 1M */
#define VHPT_SIZE (1 << VHPT_WIDTH)
223,7 → 240,7
*
* @return Current contents of rr[i].
*/
static inline uint64_t rr_read(index_t i)
static inline uint64_t rr_read(size_t i)
{
uint64_t ret;
ASSERT(i < REGION_REGISTERS);
236,7 → 253,7
* @param i Region register index.
* @param v Value to be written to rr[i].
*/
static inline void rr_write(index_t i, uint64_t v)
static inline void rr_write(size_t i, uint64_t v)
{
ASSERT(i < REGION_REGISTERS);
asm volatile (
/branches/arm/kernel/arch/ia64/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
35,12 → 35,16
#ifndef KERN_ia64_FRAME_H_
#define KERN_ia64_FRAME_H_
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
extern void frame_arch_init(void);
#define physmem_print()
 
/branches/arm/kernel/arch/ia64/include/mm/vhpt.h
44,8 → 44,8
{
vhpt_entry_t ventry;
ventry.word[0]=tentry.word[0];
ventry.word[1]=tentry.word[1];
ventry.word[0] = tentry.word[0];
ventry.word[1] = tentry.word[1];
return ventry;
}
/branches/arm/kernel/arch/ia64/include/types.h
54,8 → 54,6
} uint128_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
65,10 → 63,13
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef struct {
unative_t fnc;
unative_t gp;
} fncptr_t;
 
#define PRIp "lx" /**< Format for uintptr_t. */
#define PRIs "lu" /**< Format for size_t. */
#define PRIc "lu" /**< Format for count_t. */
#define PRIi "lu" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/ia64/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64
/** @addtogroup ia64
* @{
*/
/** @file
37,8 → 37,10
 
#define LOADED_PROG_STACK_PAGES_NO 2
 
#include <arch/ski/ski.h>
#include <arch/drivers/ski.h>
 
extern void arch_pre_main(void);
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/include/drivers/i8042.h
File deleted
/branches/arm/kernel/arch/ia64/include/drivers/ega.h
File deleted
/branches/arm/kernel/arch/ia64/include/drivers/ski.h
0,0 → 1,56
/*
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ia64
* @{
*/
/** @file
*/
 
#ifndef KERN_ia64_SKI_H_
#define KERN_ia64_SKI_H_
 
#include <console/chardev.h>
#include <proc/thread.h>
 
typedef struct {
thread_t *thread;
indev_t *srlnin;
} ski_instance_t;
 
extern void skiout_init(void);
 
extern ski_instance_t *skiin_init(void);
extern void skiin_wire(ski_instance_t *, indev_t *);
extern void ski_kbd_grab(void);
extern void ski_kbd_release(void);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/arch/ia64/include/drivers/kbd.h
0,0 → 1,46
/*
* Copyright (c) 2006 Jakub Jermar, Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ia6464
* @{
*/
/** @file
*/
 
#ifndef KERN_ia64_KBD_H_
#define KERN_ia64_KBD_H_
 
#define KBD_UNKNOWN 0
#define KBD_SKI 1
#define KBD_LEGACY 2
#define KBD_NS16550 3
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/ia64/include/drivers/it.h
41,7 → 41,7
* from firmware.
*
*/
#define IT_DELTA 100000
#define IT_DELTA it_delta
 
extern void it_init(void);
 
/branches/arm/kernel/arch/ia64/include/asm.h
36,29 → 36,72
#define KERN_ia64_ASM_H_
 
#include <config.h>
#include <typedefs.h>
#include <arch/types.h>
#include <arch/register.h>
 
 
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
 
static inline void outb(uint64_t port,uint8_t v)
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
uintptr_t prt = (uintptr_t) port;
 
*((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
uintptr_t prt = (uintptr_t) port;
 
static inline uint8_t inb(uint64_t port)
*((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
uintptr_t prt = (uintptr_t) port;
 
*((ioport32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
static inline uint8_t pio_read_8(ioport8_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
/** Return base address of current stack
*
* Return the base address of the current stack.
69,9 → 112,14
{
uint64_t v;
 
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//I'm not sure why but this code bad inlines in scheduler,
//so THE shifts about 16B and causes kernel panic
//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//return v;
return v;
//this code have the same meaning but inlines well
asm volatile ("mov %0 = r12" : "=r" (v) );
return v & (~(STACK_SIZE-1));
}
 
/** Return Processor State Register.
123,6 → 171,16
return v;
}
 
static inline uint64_t cr64_read(void)
{
uint64_t v;
asm volatile ("mov %0 = cr64\n" : "=r" (v));
return v;
}
 
 
/** Write ITC (Interval Timer Counter) register.
*
* @param v New counter value.
297,7 → 355,8
extern void cpu_sleep(void);
extern void asm_delay_loop(uint32_t t);
 
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc);
extern void switch_to_userspace(uintptr_t, uintptr_t, uintptr_t, uintptr_t,
uint64_t, uint64_t);
 
#endif
 
/branches/arm/kernel/arch/ia64/include/bootinfo.h
29,13 → 29,23
#ifndef KERN_ia64_BOOTINFO_H_
#define KERN_ia64_BOOTINFO_H_
 
#define BOOTINFO_ADDRESS 0x4401000
 
 
#define CONFIG_INIT_TASKS 32
 
#define MEMMAP_ITEMS 128
 
#define EFI_MEMMAP_FREE_MEM 0
#define EFI_MEMMAP_IO 1
#define EFI_MEMMAP_IO_PORTS 2
 
/** Size of buffer for storing task name in binit_task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
typedef struct {
void *addr;
unsigned long size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} binit_task_t;
typedef struct {
43,9 → 53,24
binit_task_t tasks[CONFIG_INIT_TASKS];
} binit_t;
 
typedef struct {
unsigned int type;
unsigned long base;
unsigned long size;
}efi_memmap_item_t;
 
 
typedef struct {
binit_t taskmap;
 
efi_memmap_item_t memmap[MEMMAP_ITEMS];
unsigned int memmap_items;
 
unsigned long * sapic;
unsigned long sys_freq;
unsigned long freq_scale;
unsigned int wakeup_intno;
int hello_configured;
} bootinfo_t;
 
extern bootinfo_t *bootinfo;
/branches/arm/kernel/arch/ia64/include/interrupt.h
50,10 → 50,13
#define IVT_FIRST 0
 
/** External Interrupt vectors. */
 
#define VECTOR_TLB_SHOOTDOWN_IPI 0xf0
#define INTERRUPT_TIMER 255
#define IRQ_KBD 241
#define IRQ_MOUSE 252
#define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE)
#define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE)
#define INTERRUPT_SPURIOUS 15
#define LEGACY_INTERRUPT_BASE 0x20
 
/** General Exception codes. */
#define GE_ILLEGALOP 0
114,7 → 117,7
/*
* The following variables are defined only for break_instruction
* handler.
* handler.
*/
uint64_t in0;
uint64_t in1;
150,6 → 153,8
extern void external_interrupt(uint64_t vector, istate_t *istate);
extern void disabled_fp_register(uint64_t vector, istate_t *istate);
 
extern void trap_virtual_enable_irqs(uint16_t irqmask);
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/include/fpu_context.h
35,7 → 35,6
#ifndef KERN_ia64_FPU_CONTEXT_H_
#define KERN_ia64_FPU_CONTEXT_H_
 
#define ARCH_HAS_FPU 1
#define FPU_CONTEXT_ALIGN 16
 
#include <arch/types.h>
/branches/arm/kernel/arch/ia64/include/atomic.h
37,29 → 37,65
 
/** Atomic addition.
*
* @param val Atomic value.
* @param imm Value to add.
* @param val Atomic value.
* @param imm Value to add.
*
* @return Value before addition.
* @return Value before addition.
*/
static inline long atomic_add(atomic_t *val, int imm)
{
long v;
 
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm));
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v),
"+m" (val->count) : "i" (imm));
return v;
}
 
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
 
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; }
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; }
static inline uint64_t test_and_set(atomic_t *val) {
uint64_t v;
asm volatile (
"movl %0 = 0x01;;\n"
"xchg8 %0 = %1, %0;;\n"
: "=r" (v), "+m" (val->count)
);
return v;
}
 
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); }
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); }
 
static inline void atomic_inc(atomic_t *val)
{
atomic_add(val, 1);
}
 
static inline void atomic_dec(atomic_t *val)
{
atomic_add(val, -1);
}
 
static inline long atomic_preinc(atomic_t *val)
{
return atomic_add(val, 1) + 1;
}
 
static inline long atomic_predec(atomic_t *val)
{
return atomic_add(val, -1) - 1;
}
 
static inline long atomic_postinc(atomic_t *val)
{
return atomic_add(val, 1);
}
 
static inline long atomic_postdec(atomic_t *val)
{
return atomic_add(val, -1);
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/include/proc/task.h
31,14 → 31,19
*/
/** @file
*/
#include <proc/task.h>
 
#ifndef KERN_ia64_TASK_H_
#define KERN_ia64_TASK_H_
 
#include <adt/bitmap.h>
 
typedef struct {
bitmap_t *iomap;
} task_arch_t;
 
#define task_create_arch(t)
 
#define task_create_arch(t) { (t)->arch.iomap = NULL; }
#define task_destroy_arch(t)
 
#endif
/branches/arm/kernel/arch/ia64/include/register.h
40,11 → 40,11
#define PSR_I_MASK 0x4000
#define PSR_PK_MASK 0x8000
 
#define PSR_DT_MASK (1<<17)
#define PSR_RT_MASK (1<<27)
#define PSR_DT_MASK (1 << 17)
#define PSR_RT_MASK (1 << 27)
 
#define PSR_DFL_MASK (1<<18)
#define PSR_DFH_MASK (1<<19)
#define PSR_DFL_MASK (1 << 18)
#define PSR_DFH_MASK (1 << 19)
 
#define PSR_IT_MASK 0x0000001000000000
 
/branches/arm/kernel/arch/ia64/include/debug.h
1,5 → 1,5
/*
* Copyright (c) 2005
* Copyright (c) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/branches/arm/kernel/arch/ia64/include/cpu.h
38,6 → 38,7
#include <arch/types.h>
#include <arch/register.h>
#include <arch/asm.h>
#include <arch/bootinfo.h>
 
#define FAMILY_ITANIUM 0x7
#define FAMILY_ITANIUM2 0x1f
63,6 → 64,32
return v;
}
 
 
#define CR64_ID_SHIFT 24
#define CR64_ID_MASK 0xff000000
#define CR64_EID_SHIFT 16
#define CR64_EID_MASK 0xff0000
 
static inline int ia64_get_cpu_id(void)
{
uint64_t cr64=cr64_read();
return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT;
}
 
static inline int ia64_get_cpu_eid(void)
{
uint64_t cr64=cr64_read();
return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT;
}
 
 
static inline void ipi_send_ipi(int id, int eid, int intno)
{
(bootinfo->sapic)[2 * (id * 256 + eid)] = intno;
srlz_d();
 
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/src/ski/ski.c
File deleted
/branches/arm/kernel/arch/ia64/src/putchar.c
File deleted
/branches/arm/kernel/arch/ia64/src/ivt.S
536,7 → 536,7
HEAVYWEIGHT_HANDLER 0x5000 page_not_present
HEAVYWEIGHT_HANDLER 0x5100
HEAVYWEIGHT_HANDLER 0x5200
HEAVYWEIGHT_HANDLER 0x5300
HEAVYWEIGHT_HANDLER 0x5300 data_access_rights_fault
HEAVYWEIGHT_HANDLER 0x5400 general_exception
HEAVYWEIGHT_HANDLER 0x5500 disabled_fp_register
HEAVYWEIGHT_HANDLER 0x5600
/branches/arm/kernel/arch/ia64/src/mm/tlb.c
92,7 → 92,7
 
/** Invalidate entries belonging to an address space.
*
* @param asid Address space identifier.
* @param asid Address space identifier.
*/
void tlb_invalidate_asid(asid_t asid)
{
100,7 → 100,7
}
 
 
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
region_register rr;
bool restore_rr = false;
131,59 → 131,45
uint64_t ps;
switch (b) {
case 0: /*cnt 1-3*/
case 0: /* cnt 1 - 3 */
ps = PAGE_WIDTH;
break;
case 1: /*cnt 4-15*/
/*cnt=((cnt-1)/4)+1;*/
ps = PAGE_WIDTH+2;
va &= ~((1<<ps)-1);
case 1: /* cnt 4 - 15 */
ps = PAGE_WIDTH + 2;
va &= ~((1 << ps) - 1);
break;
case 2: /*cnt 16-63*/
/*cnt=((cnt-1)/16)+1;*/
ps = PAGE_WIDTH+4;
va &= ~((1<<ps)-1);
case 2: /* cnt 16 - 63 */
ps = PAGE_WIDTH + 4;
va &= ~((1 << ps) - 1);
break;
case 3: /*cnt 64-255*/
/*cnt=((cnt-1)/64)+1;*/
ps = PAGE_WIDTH+6;
va &= ~((1<<ps)-1);
case 3: /* cnt 64 - 255 */
ps = PAGE_WIDTH + 6;
va &= ~((1 << ps) - 1);
break;
case 4: /*cnt 256-1023*/
/*cnt=((cnt-1)/256)+1;*/
ps = PAGE_WIDTH+8;
va &= ~((1<<ps)-1);
case 4: /* cnt 256 - 1023 */
ps = PAGE_WIDTH + 8;
va &= ~((1 << ps) - 1);
break;
case 5: /*cnt 1024-4095*/
/*cnt=((cnt-1)/1024)+1;*/
ps = PAGE_WIDTH+10;
va &= ~((1<<ps)-1);
case 5: /* cnt 1024 - 4095 */
ps = PAGE_WIDTH + 10;
va &= ~((1 << ps) - 1);
break;
case 6: /*cnt 4096-16383*/
/*cnt=((cnt-1)/4096)+1;*/
ps = PAGE_WIDTH+12;
va &= ~((1<<ps)-1);
case 6: /* cnt 4096 - 16383 */
ps = PAGE_WIDTH + 12;
va &= ~((1 << ps) - 1);
break;
case 7: /*cnt 16384-65535*/
case 8: /*cnt 65536-(256K-1)*/
/*cnt=((cnt-1)/16384)+1;*/
ps = PAGE_WIDTH+14;
va &= ~((1<<ps)-1);
case 7: /* cnt 16384 - 65535 */
case 8: /* cnt 65536 - (256K - 1) */
ps = PAGE_WIDTH + 14;
va &= ~((1 << ps) - 1);
break;
default:
/*cnt=((cnt-1)/(16384*16))+1;*/
ps=PAGE_WIDTH+18;
va&=~((1<<ps)-1);
ps = PAGE_WIDTH + 18;
va &= ~((1 << ps) - 1);
break;
}
/*cnt+=(page!=va);*/
for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) {
asm volatile (
"ptc.l %0,%1;;"
:
: "r" (va), "r" (ps<<2)
);
}
for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps))
asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2));
srlz_d();
srlz_i();
196,9 → 182,10
 
/** Insert data into data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
*/
void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
207,9 → 194,10
 
/** Insert data into instruction translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
*/
void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
218,10 → 206,12
 
/** Insert data into instruction or data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param dtc If true, insert into data translation cache, use
* instruction translation cache otherwise.
*/
void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc)
{
244,19 → 234,20
}
asm volatile (
"mov r8=psr;;\n"
"mov r8 = psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"mov cr.ifa = %1\n" /* va */
"mov cr.itir = %2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"(p6) itc.i %3;;\n"
"(p7) itc.d %3;;\n"
"mov psr.l=r8;;\n"
"mov psr.l = r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
"r" (entry.word[0]), "r" (dtc)
: "p6", "p7", "r8"
);
269,12 → 260,14
 
/** Insert data into instruction translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param tr Translation register.
*/
void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
void
itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
{
tr_mapping_insert(va, asid, entry, false, tr);
}
281,12 → 274,14
 
/** Insert data into data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param tr Translation register.
*/
void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
void
dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
{
tr_mapping_insert(va, asid, entry, true, tr);
}
293,13 → 288,17
 
/** Insert data into instruction or data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtr If true, insert into data translation register, use instruction translation register otherwise.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param dtr If true, insert into data translation register, use
* instruction translation register otherwise.
* @param tr Translation register.
*/
void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
void
tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr,
size_t tr)
{
region_register rr;
bool restore_rr = false;
320,19 → 319,20
}
 
asm volatile (
"mov r8=psr;;\n"
"mov r8 = psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4]=%3;;\n"
"(p7) itr.d dtr[%4]=%3;;\n"
"mov psr.l=r8;;\n"
"mov cr.ifa = %1\n" /* va */
"mov cr.itir = %2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4] = %3;;\n"
"(p7) itr.d dtr[%4] = %3;;\n"
"mov psr.l = r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
"r" (entry.word[0]), "r" (tr), "r" (dtr)
: "p6", "p7", "r8"
);
345,12 → 345,15
 
/** Insert data into DTLB.
*
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data
* translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
*/
void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr)
void
dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr,
size_t tr)
{
tlb_entry_t entry;
376,18 → 379,18
*
* Purge DTR entries used by the kernel.
*
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
*/
void dtr_purge(uintptr_t page, count_t width)
void dtr_purge(uintptr_t page, size_t width)
{
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width<<2));
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2));
}
 
 
/** Copy content of PTE into data translation cache.
*
* @param t PTE.
* @param t PTE.
*/
void dtc_pte_copy(pte_t *t)
{
413,7 → 416,7
 
/** Copy content of PTE into instruction translation cache.
*
* @param t PTE.
* @param t PTE.
*/
void itc_pte_copy(pte_t *t)
{
440,8 → 443,8
 
/** Instruction TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate)
{
469,16 → 472,77
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
}
 
static int is_io_page_accessible(int page)
{
if (TASK->arch.iomap)
return bitmap_get(TASK->arch.iomap, page);
else
return 0;
}
 
#define IO_FRAME_BASE 0xFFFFC000000
 
/**
* There is special handling of memory mapped legacy io, because of 4KB sized
* access for userspace.
*
* @param va Virtual address of page fault.
* @param istate Structure with saved interruption state.
*
* @return One on success, zero on failure.
*/
static int try_memmap_io_insertion(uintptr_t va, istate_t *istate)
{
if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) {
if (TASK) {
uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >>
USPACE_IO_PAGE_WIDTH;
 
if (is_io_page_accessible(io_page)) {
uint64_t page, frame;
 
page = IO_OFFSET +
(1 << USPACE_IO_PAGE_WIDTH) * io_page;
frame = IO_FRAME_BASE +
(1 << USPACE_IO_PAGE_WIDTH) * io_page;
 
tlb_entry_t entry;
entry.word[0] = 0;
entry.word[1] = 0;
entry.p = true; /* present */
entry.ma = MA_UNCACHEABLE;
entry.a = true; /* already accessed */
entry.d = true; /* already dirty */
entry.pl = PL_USER;
entry.ar = AR_READ | AR_WRITE;
entry.ppn = frame >> PPN_SHIFT;
entry.ps = USPACE_IO_PAGE_WIDTH;
dtc_mapping_insert(page, TASK->as->asid, entry);
return 1;
} else {
fault_if_from_uspace(istate,
"IO access fault at %p.", va);
}
}
}
return 0;
}
 
/** Data TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_data_tlb_fault(uint64_t vector, istate_t *istate)
{
511,13 → 575,17
dtc_pte_copy(t);
page_table_unlock(AS, true);
} else {
page_table_unlock(AS, true);
if (try_memmap_io_insertion(va, istate))
return;
/*
* Forward the page fault to the address space page fault handler.
* Forward the page fault to the address space page fault
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
}
526,18 → 594,18
*
* This fault should not occur.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_nested_tlb_fault(uint64_t vector, istate_t *istate)
{
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Data Dirty bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_dirty_bit_fault(uint64_t vector, istate_t *istate)
{
562,10 → 630,9
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->d = true;
dtc_pte_copy(t);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
573,8 → 640,8
 
/** Instruction access bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void instruction_access_bit_fault(uint64_t vector, istate_t *istate)
{
599,10 → 666,9
itc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
636,15 → 702,45
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
}
 
/** Data access rights fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_access_rights_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
 
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
/*
* Assume a write to a read-only page.
*/
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
ASSERT(!t->w);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
page_table_unlock(AS, true);
}
 
/** Page not present fault handler.
*
* @param vector Interruption vector.
678,11 → 774,19
} else {
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d\n", __func__, va, rid);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d.", __func__, va, rid);
}
}
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/mm/vhpt.c
41,7 → 41,8
 
uintptr_t vhpt_set_up(void)
{
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, FRAME_KA | FRAME_ATOMIC);
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH,
FRAME_KA | FRAME_ATOMIC);
if (!vhpt_base)
panic("Kernel configured with VHPT but no memory for table.");
vhpt_invalidate_all();
52,7 → 53,7
void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
uint64_t tag;
 
/branches/arm/kernel/arch/ia64/src/mm/page.c
27,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
47,6 → 47,7
#include <arch/asm.h>
#include <arch/barrier.h>
#include <memstr.h>
#include <align.h>
 
static void set_environment(void);
 
62,9 → 63,9
void set_environment(void)
{
region_register rr;
pta_register pta;
pta_register pta;
int i;
#ifdef CONFIG_VHPT
#ifdef CONFIG_VHPT
uintptr_t vhpt_base;
#endif
 
122,15 → 123,15
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return VHPT entry address.
* @return VHPT entry address.
*/
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
vhpt_entry_t *v;
 
166,15 → 167,16
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return True if page and asid match the page and asid of t, false otherwise.
* @return True if page and asid match the page and asid of t,
* false otherwise.
*/
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
bool match;
 
210,15 → 212,18
/** Set up one VHPT entry.
*
* @param v VHPT entry to be set up.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which
* page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
*/
void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags)
void
vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame,
int flags)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
uint64_t tag;
 
249,7 → 254,8
v->word[3] = 0;
v->present.p = true;
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
v->present.ma = (flags & PAGE_CACHEABLE) ?
MA_WRITEBACK : MA_UNCACHEABLE;
v->present.a = false; /* not accessed */
v->present.d = false; /* not dirty */
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
262,5 → 268,11
v->present.tag.tag_word = tag;
}
 
uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused)))
{
/* THIS is a dirty hack. */
return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET);
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
36,26 → 36,55
#include <mm/frame.h>
#include <config.h>
#include <panic.h>
#include <arch/bootinfo.h>
#include <align.h>
#include <macros.h>
 
/*
* This is Ski-specific and certainly not sufficient
* for real ia64 systems that provide memory map.
*/
#define MEMORY_SIZE (64 * 1024 * 1024)
#define MEMORY_BASE (64 * 1024 * 1024)
#define KERNEL_RESERVED_AREA_BASE (0x4400000)
#define KERNEL_RESERVED_AREA_SIZE (16 * 1024 * 1024)
 
#define ROM_BASE 0xa0000 //For ski
#define ROM_SIZE (384 * 1024) //For ski
void poke_char(int x,int y,char ch, char c);
#define ROM_BASE 0xa0000 /* for simulators */
#define ROM_SIZE (384 * 1024) /* for simulators */
 
#define MIN_ZONE_SIZE (64 * 1024)
 
#define MINCONF 1
 
uintptr_t last_frame = 0;
 
void frame_arch_init(void)
{
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE));
if (config.cpu_active == 1) {
unsigned int i;
for (i = 0; i < bootinfo->memmap_items; i++) {
if (bootinfo->memmap[i].type == EFI_MEMMAP_FREE_MEM) {
uint64_t base = bootinfo->memmap[i].base;
uint64_t size = bootinfo->memmap[i].size;
uint64_t abase = ALIGN_UP(base, FRAME_SIZE);
 
if (size > FRAME_SIZE)
size -= abase - base;
 
if (size > MIN_ZONE_SIZE) {
zone_create(abase >> FRAME_WIDTH,
size >> FRAME_WIDTH,
max(MINCONF, abase >> FRAME_WIDTH),
0);
}
if (abase + size > last_frame)
last_frame = abase + size;
}
}
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE),
SIZE2FRAMES(ROM_SIZE));
 
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE),
SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE));
}
}
 
/** @}
/branches/arm/kernel/arch/ia64/src/mm/as.c
68,7 → 68,7
continue;
rr.word = rr_read(i);
rr.map.ve = false; /* disable VHPT walker */
rr.map.ve = false; /* disable VHPT walker */
rr.map.rid = ASID2RID(as->asid, i);
rr.map.ps = PAGE_WIDTH;
rr_write(i, rr.word);
/branches/arm/kernel/arch/ia64/src/drivers/ega.c
File deleted
/branches/arm/kernel/arch/ia64/src/drivers/ski.c
0,0 → 1,246
/*
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ia64
* @{
*/
/** @file
*/
 
#include <arch/drivers/ski.h>
#include <console/console.h>
#include <console/chardev.h>
#include <sysinfo/sysinfo.h>
#include <arch/types.h>
#include <proc/thread.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch/drivers/kbd.h>
#include <string.h>
#include <arch.h>
 
enum {
/** Interval between polling in microseconds */
POLL_INTERVAL = 10000, /* 0.01 s */
 
/** Max. number of characters to pull out at a time */
POLL_LIMIT = 30,
 
SKI_INIT_CONSOLE = 20,
SKI_GETCHAR = 21,
SKI_PUTCHAR = 31
};
 
static void ski_putchar(outdev_t *, const wchar_t, bool);
 
static outdev_operations_t skiout_ops = {
.write = ski_putchar
};
 
static outdev_t skiout; /**< Ski output device. */
static bool initialized = false;
static bool kbd_disabled = false;
 
/** Initialize debug console
*
* Issue SSC (Simulator System Call) to
* to open debug console.
*
*/
static void ski_init(void)
{
if (initialized)
return;
asm volatile (
"mov r15 = %0\n"
"break 0x80000\n"
:
: "i" (SKI_INIT_CONSOLE)
: "r15", "r8"
);
initialized = true;
}
 
static void ski_do_putchar(const wchar_t ch)
{
asm volatile (
"mov r15 = %[cmd]\n"
"mov r32 = %[ch]\n" /* r32 is in0 */
"break 0x80000\n" /* modifies r8 */
:
: [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
: "r15", "in0", "r8"
);
}
 
/** Display character on debug console
*
* Use SSC (Simulator System Call) to
* display character on debug console.
*
* @param dev Character device.
* @param ch Character to be printed.
* @param silent Whether the output should be silenced.
*
*/
static void ski_putchar(outdev_t *dev, const wchar_t ch, bool silent)
{
if (!silent) {
if (ascii_check(ch)) {
if (ch == '\n')
ski_do_putchar('\r');
ski_do_putchar(ch);
} else
ski_do_putchar(U_SPECIAL);
}
}
 
void skiout_init(void)
{
ski_init();
outdev_initialize("skiout", &skiout, &skiout_ops);
stdout = &skiout;
sysinfo_set_item_val("fb", NULL, false);
}
 
/** Ask debug console if a key was pressed.
*
* Use SSC (Simulator System Call) to
* get character from debug console.
*
* This call is non-blocking.
*
* @return ASCII code of pressed key or 0 if no key pressed.
*
*/
static wchar_t ski_getchar(void)
{
uint64_t ch;
asm volatile (
"mov r15 = %1\n"
"break 0x80000;;\n" /* modifies r8 */
"mov %0 = r8;;\n"
: "=r" (ch)
: "i" (SKI_GETCHAR)
: "r15", "r8"
);
return (wchar_t) ch;
}
 
/** Ask keyboard if a key was pressed.
*
* If so, it will repeat and pull up to POLL_LIMIT characters.
*/
static void poll_keyboard(ski_instance_t *instance)
{
wchar_t ch;
int count;
 
if (kbd_disabled)
return;
 
count = POLL_LIMIT;
 
while (count > 0) {
ch = ski_getchar();
 
if (ch == '\0')
break;
 
indev_push_character(instance->srlnin, ch);
--count;
}
}
 
/** Kernel thread for polling keyboard. */
static void kskipoll(void *arg)
{
ski_instance_t *instance = (ski_instance_t *) arg;
while (true) {
if (!silent)
poll_keyboard(instance);
thread_usleep(POLL_INTERVAL);
}
}
 
ski_instance_t *skiin_init(void)
{
ski_init();
ski_instance_t *instance =
malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread = thread_create(kskipoll, instance, TASK, 0,
"kskipoll", true);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->srlnin = NULL;
}
return instance;
}
 
void skiin_wire(ski_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
instance->srlnin = srlnin;
thread_ready(instance->thread);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
}
 
void ski_kbd_grab(void)
{
kbd_disabled = false;
}
 
void ski_kbd_release(void)
{
kbd_disabled = true;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/arch/ia64/src/drivers/it.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64
/** @addtogroup ia64
* @{
*/
/** @file
44,25 → 44,44
#include <ddi/device.h>
#include <arch.h>
 
#define IT_SERVICE_CLOCKS 64
#define IT_SERVICE_CLOCKS 64
 
#define FREQ_NUMERATOR_SHIFT 32
#define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL
 
#define FREQ_DENOMINATOR_SHIFT 0
#define FREQ_DENOMINATOR_MASK 0xffffffffULL
 
uint64_t it_delta;
 
static irq_t it_irq;
 
static irq_ownership_t it_claim(void);
static void it_interrupt(irq_t *irq, void *arg, ...);
static irq_ownership_t it_claim(irq_t *);
static void it_interrupt(irq_t *);
 
/** Initialize Interval Timer. */
void it_init(void)
{
cr_itv_t itv;
 
irq_initialize(&it_irq);
it_irq.inr = INTERRUPT_TIMER;
it_irq.devno = device_assign_devno();
it_irq.claim = it_claim;
it_irq.handler = it_interrupt;
irq_register(&it_irq);
 
if (config.cpu_active == 1) {
irq_initialize(&it_irq);
it_irq.inr = INTERRUPT_TIMER;
it_irq.devno = device_assign_devno();
it_irq.claim = it_claim;
it_irq.handler = it_interrupt;
irq_register(&it_irq);
uint64_t base_freq;
base_freq = ((bootinfo->freq_scale) & FREQ_NUMERATOR_MASK) >>
FREQ_NUMERATOR_SHIFT;
base_freq *= bootinfo->sys_freq;
base_freq /= ((bootinfo->freq_scale) & FREQ_DENOMINATOR_MASK) >>
FREQ_DENOMINATOR_SHIFT;
it_delta = base_freq / HZ;
}
/* initialize Interval Timer external interrupt vector */
itv.value = itv_read();
itv.vector = INTERRUPT_TIMER;
85,13 → 104,13
*
* @return Always IRQ_ACCEPT.
*/
irq_ownership_t it_claim(void)
irq_ownership_t it_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Process Interval Timer interrupt. */
void it_interrupt(irq_t *irq, void *arg, ...)
void it_interrupt(irq_t *irq)
{
int64_t c;
int64_t m;
/branches/arm/kernel/arch/ia64/src/smp/smp.c
0,0 → 1,167
/*
* Copyright (c) 2005 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ia64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <arch/drivers/ski.h>
#include <arch/drivers/it.h>
#include <arch/interrupt.h>
#include <arch/barrier.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <arch/types.h>
#include <arch/context.h>
#include <arch/stack.h>
#include <arch/mm/page.h>
#include <mm/as.h>
#include <config.h>
#include <userspace.h>
#include <console/console.h>
#include <proc/uarg.h>
#include <syscall/syscall.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <arch/bootinfo.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
#include <panic.h>
#include <print.h>
 
#ifdef CONFIG_SMP
 
extern char cpu_by_id_eid_list[256][256];
 
static void sapic_init(void)
{
bootinfo->sapic = (unative_t *)(PA2KA((unative_t)(bootinfo->sapic)) |
FW_OFFSET);
}
 
static void ipi_broadcast_arch_all(int ipi)
{
int id, eid;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if ((id != myid) || (eid != myeid))
ipi_send_ipi(id, eid, ipi);
}
 
void ipi_broadcast_arch(int ipi )
{
int id, eid;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if ((id != myid) || (eid != myeid))
if (cpu_by_id_eid_list[id][eid])
ipi_send_ipi(id, eid, ipi);
}
 
void smp_init(void)
{
if (!bootinfo->hello_configured)
return;
/*
* If we have not got system prepared by hello, we are not able to start
* AP's. This means we are running on a simulator.
*/
sapic_init();
ipi_broadcast_arch_all(bootinfo->wakeup_intno);
volatile long long brk;
for (brk = 0; brk < 100LL * 1024LL * 1024LL; brk++)
; /* wait a while before CPUs starts */
 
config.cpu_count = 0;
int id, eid;
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if (cpu_by_id_eid_list[id][eid] == 1) {
config.cpu_count++;
cpu_by_id_eid_list[id][eid] = 2;
}
}
 
void kmp(void *arg __attribute__((unused)))
{
int id, eid;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if ((id != myid) || (eid != myeid))
if (cpu_by_id_eid_list[id][eid] != 0) {
if (cpu_by_id_eid_list[id][eid] == 1) {
printf("Found Late CPU ID:%d "
"EDI:%d Not added to "
"system!!!\n", id, eid);
continue;
}
cpu_by_id_eid_list[id][eid] = 3;
/*
* There may be just one AP being
* initialized at the time. After
* it comes completely up, it is
* supposed to wake us up.
*/
if (waitq_sleep_timeout(
&ap_completion_wq, 1000000,
SYNCH_FLAGS_NONE) ==
ESYNCH_TIMEOUT) {
printf("%s: waiting for cpu "
"ID:%d EID:%d timed out\n",
__FUNCTION__, id, eid);
}
}
}
 
#endif
 
/** @}
*/
 
/branches/arm/kernel/arch/ia64/src/ia64.c
33,7 → 33,7
*/
 
#include <arch.h>
#include <arch/ski/ski.h>
#include <arch/drivers/ski.h>
#include <arch/drivers/it.h>
#include <arch/interrupt.h>
#include <arch/barrier.h>
50,64 → 50,91
#include <proc/uarg.h>
#include <syscall/syscall.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <arch/drivers/ega.h>
#include <arch/bootinfo.h>
#include <genarch/kbd/i8042.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <genarch/kbrd/kbrd.h>
#include <genarch/srln/srln.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/drivers/ns16550/ns16550.h>
#include <arch/drivers/kbd.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
#include <panic.h>
#include <print.h>
#include <sysinfo/sysinfo.h>
#include <string.h>
 
/* NS16550 as a COM 1 */
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE)
 
bootinfo_t *bootinfo;
 
static uint64_t iosapic_base = 0xfec00000;
 
/** Performs ia64-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Setup usermode init tasks. */
 
//#ifdef I460GX
unsigned int i;
init.cnt = bootinfo->taskmap.count;
for (i = 0; i < init.cnt; i++) {
init.tasks[i].addr = ((unsigned long) bootinfo->taskmap.tasks[i].addr) | VRN_MASK;
init.tasks[i].addr =
((unsigned long) bootinfo->taskmap.tasks[i].addr) |
VRN_MASK;
init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo->taskmap.tasks[i].name);
}
/*
#else
init.cnt = 8;
init.tasks[0].addr = INIT0_ADDRESS;
init.tasks[0].size = INIT0_SIZE;
init.tasks[1].addr = INIT0_ADDRESS + 0x400000;
init.tasks[1].size = INIT0_SIZE;
init.tasks[2].addr = INIT0_ADDRESS + 0x800000;
init.tasks[2].size = INIT0_SIZE;
init.tasks[3].addr = INIT0_ADDRESS + 0xc00000;
init.tasks[3].size = INIT0_SIZE;
init.tasks[4].addr = INIT0_ADDRESS + 0x1000000;
init.tasks[4].size = INIT0_SIZE;
init.tasks[5].addr = INIT0_ADDRESS + 0x1400000;
init.tasks[5].size = INIT0_SIZE;
init.tasks[6].addr = INIT0_ADDRESS + 0x1800000;
init.tasks[6].size = INIT0_SIZE;
init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000;
init.tasks[7].size = INIT0_SIZE;
#endif*/
}
 
void arch_pre_mm_init(void)
{
/* Set Interruption Vector Address (i.e. location of interruption vector table). */
/*
* Set Interruption Vector Address (i.e. location of interruption vector
* table).
*/
iva_write((uintptr_t) &ivt);
srlz_d();
}
 
static void iosapic_init(void)
{
uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET;
int i;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (i = 0; i < 16; i++) {
if (i == 2)
continue; /* Disable Cascade interrupt */
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i;
srlz_d();
((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i;
srlz_d();
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1;
srlz_d();
((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) |
myeid << (48 - 32);
srlz_d();
}
 
}
 
void arch_post_mm_init(void)
{
irq_init(INR_COUNT, INR_COUNT);
#ifdef SKI
ski_init_console();
#else
ega_init();
#endif
if (config.cpu_active == 1) {
iosapic_init();
irq_init(INR_COUNT, INR_COUNT);
}
it_init();
}
 
119,51 → 146,73
{
}
 
 
#ifdef I460GX
#define POLL_INTERVAL 50000 /* 50 ms */
/** Kernel thread for polling keyboard. */
static void i8042_kkbdpoll(void *arg)
void arch_post_smp_init(void)
{
while (1) {
i8042_poll();
thread_usleep(POLL_INTERVAL);
#ifdef MACHINE_ski
ski_instance_t *ski_instance = skiin_init();
if (ski_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
skiin_wire(ski_instance, srln);
}
}
}
skiout_init();
#endif
 
void arch_post_smp_init(void)
{
 
if (config.cpu_active == 1) {
/*
* Create thread that polls keyboard.
*/
#ifdef SKI
thread_t *t;
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
#endif
 
#ifdef I460GX
devno_t kbd = device_assign_devno();
devno_t mouse = device_assign_devno();
/* keyboard controller */
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
 
thread_t *t;
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
 
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM);
#endif
 
#ifdef CONFIG_NS16550
ns16550_instance_t *ns16550_instance
= ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL);
if (ns16550_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
ns16550_wire(ns16550_instance, srln);
}
}
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ);
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) NS16550_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) NS16550_BASE);
#endif
#ifdef CONFIG_I8042
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
if (i8042_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
i8042_wire(i8042_instance, kbrd);
}
}
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) I8042_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
sysinfo_set_item_val("ia64_iospace", NULL, true);
sysinfo_set_item_val("ia64_iospace.address", NULL, true);
sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
}
 
 
/** Enter userspace and never return. */
void userspace(uspace_arg_t *kernel_uarg)
{
172,26 → 221,25
 
psr.value = psr_read();
psr.cpl = PL_USER;
psr.i = true; /* start with interrupts enabled */
psr.i = true; /* start with interrupts enabled */
psr.ic = true;
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
 
asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
rsc.loadrs = 0;
rsc.be = false;
rsc.pl = PL_USER;
rsc.mode = 3; /* eager mode */
rsc.mode = 3; /* eager mode */
 
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg,
psr.value, rsc.value);
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE -
ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
 
while (1) {
while (1)
;
}
}
 
/** Set thread-local-storage pointer.
208,16 → 256,17
*/
void arch_grab_console(void)
{
#ifdef SKI
#ifdef MACHINE_ski
ski_kbd_grab();
#endif
#endif
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
#ifdef SKI
#ifdef MACHINE_ski
ski_kbd_release();
#endif
}
224,9 → 273,27
 
void arch_reboot(void)
{
// TODO
while (1);
pio_write_8((ioport8_t *)0x64, 0xfe);
while (1)
;
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
fptr->fnc = (unative_t) addr;
fptr->gp = ((unative_t *) caller)[1];
return (void *) fptr;
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/cpu/cpu.c
55,7 → 55,7
*((uint64_t *) &vendor[0 * sizeof(uint64_t)]) = CPU->arch.cpuid0;
*((uint64_t *) &vendor[1 * sizeof(uint64_t)]) = CPU->arch.cpuid1;
vendor[sizeof(vendor) - 1] = '\0';
vendor[sizeof(vendor) - 1] = 0;
switch(m->arch.cpuid3.family) {
case FAMILY_ITANIUM:
70,8 → 70,8
}
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id,
family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model,
CPU->arch.cpuid3.revision);
family_str, vendor, CPU->arch.cpuid3.archrev,
CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision);
}
 
/** @}
/branches/arm/kernel/arch/ia64/src/interrupt.c
38,7 → 38,6
#include <ddi/irq.h>
#include <panic.h>
#include <print.h>
#include <symtab.h>
#include <debug.h>
#include <console/console.h>
#include <arch/types.h>
53,6 → 52,9
#include <ipc/irq.h>
#include <ipc/ipc.h>
#include <synch/spinlock.h>
#include <mm/tlb.h>
#include <symtab.h>
#include <putchar.h>
 
#define VECTORS_64_BUNDLE 20
#define VECTORS_16_BUNDLE 48
136,9 → 138,9
{
char *ifa, *iipa, *iip;
 
ifa = get_symtab_entry(istate->cr_ifa);
iipa = get_symtab_entry(istate->cr_iipa);
iip = get_symtab_entry(istate->cr_iip);
ifa = symtab_fmt_name_lookup(istate->cr_ifa);
iipa = symtab_fmt_name_lookup(istate->cr_iipa);
iip = symtab_fmt_name_lookup(istate->cr_iip);
 
putchar('\n');
printf("Interrupted context dump:\n");
185,21 → 187,21
break;
}
 
fault_if_from_uspace(istate, "General Exception (%s)", desc);
fault_if_from_uspace(istate, "General Exception (%s).", desc);
 
dump_interrupted_context(istate);
panic("General Exception (%s)\n", desc);
panic("General Exception (%s).", desc);
}
 
void disabled_fp_register(uint64_t vector, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "Interruption: %#hx (%s)",
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
panic("Interruption: %#hx (%s).", (uint16_t) vector,
vector_to_string(vector));
#endif
}
227,40 → 229,82
 
void universal_handler(uint64_t vector, istate_t *istate)
{
fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n",
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
panic("Interruption: %#hx (%s).", (uint16_t) vector,
vector_to_string(vector));
}
 
static void end_of_local_irq(void)
{
asm volatile ("mov cr.eoi=r0;;");
}
 
 
void external_interrupt(uint64_t vector, istate_t *istate)
{
cr_ivr_t ivr;
irq_t *irq;
cr_ivr_t ivr;
ivr.value = ivr_read();
srlz_d();
 
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
switch (ivr.vector) {
case INTERRUPT_SPURIOUS:
switch (ivr.vector) {
case INTERRUPT_SPURIOUS:
#ifdef CONFIG_DEBUG
printf("cpu%d: spurious interrupt\n", CPU->id);
printf("cpu%d: spurious interrupt\n", CPU->id);
#endif
break;
break;
 
default:
panic("\nUnhandled External Interrupt Vector %d\n",
#ifdef CONFIG_SMP
case VECTOR_TLB_SHOOTDOWN_IPI:
tlb_shootdown_ipi_recv();
end_of_local_irq();
break;
#endif
 
case INTERRUPT_TIMER:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
panic("Unhandled Internal Timer Interrupt (%d).",
ivr.vector);
break;
}
break;
default:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
end_of_local_irq();
}
irq->handler(irq);
if (!irq->preack)
end_of_local_irq();
spinlock_unlock(&irq->lock);
} else {
/*
* Unhandled interrupt.
*/
end_of_local_irq();
#ifdef CONFIG_DEBUG
printf("\nUnhandled External Interrupt Vector %d\n",
ivr.vector);
#endif
}
break;
}
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/asm.S
51,7 → 51,7
 
adds r14 = 7, in1
mov r2 = ar.lc
mov r8 = in0
mov r8 = in0 ;;
and r14 = -8, r14 ;;
cmp.ne p6, p7 = r14, in1
(p7) br.cond.dpnt 3f ;;
128,6 → 128,10
memsetb:
br _memsetb
 
.global memsetw
memsetw:
br _memsetw
 
.global cpu_halt
cpu_halt:
br cpu_halt
/branches/arm/kernel/arch/ia64/src/start.S
32,19 → 32,15
#include <mm/asid.h>
 
#define RR_MASK (0xFFFFFFFF00000002)
#define RID_SHIFT 8
#define PS_SHIFT 2
#define RID_SHIFT 8
#define PS_SHIFT 2
 
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define VIO_OFFSET 0x0002000000000000
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define KERNEL_TRANSLATION_FW 0x00100000F0000671
 
#define IO_OFFSET 0x0001000000000000
 
 
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
53,6 → 49,19
kernel_image_start:
.auto
 
#ifdef CONFIG_SMP
# Identify self(CPU) in OS structures by ID / EID
 
mov r9 = cr64
mov r10 = 1
movl r12 = 0xffffffff
movl r8 = cpu_by_id_eid_list
and r8 = r8, r12
shr r9 = r9, 16
add r8 = r8, r9
st1 [r8] = r10
#endif
 
mov psr.l = r0
srlz.i
srlz.d
59,39 → 68,29
 
# Fill TR.i and TR.d using Region Register #VRN_KERNEL
 
 
movl r8 = (VRN_KERNEL << VRN_SHIFT)
mov r9 = rr[r8]
 
 
movl r10 = (RR_MASK)
and r9 = r10, r9
movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
or r9 = r10, r9
 
 
mov rr[r8] = r9
 
 
 
movl r8 = (VRN_KERNEL << VRN_SHIFT)
mov cr.ifa = r8
 
mov r11 = cr.itir ;;
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
mov r11 = cr.itir
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
movl r10 = (KERNEL_TRANSLATION_I)
itr.i itr[r0] = r10
 
movl r10 = (KERNEL_TRANSLATION_D)
itr.d dtr[r0] = r10
 
 
movl r7 = 1
movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET
mov cr.ifa = r8
98,15 → 97,13
movl r10 = (KERNEL_TRANSLATION_VIO)
itr.d dtr[r7] = r10
 
mov r11 = cr.itir
movl r10 = ~0xfc
and r10 = r10, r11
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
mov r11 = cr.itir ;;
movl r10 = ~0xfc;;
and r10 =r10 , r11 ;;
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
 
 
movl r7 = 2
movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET
mov cr.ifa = r8
113,12 → 110,26
movl r10 = (KERNEL_TRANSLATION_IO)
itr.d dtr[r7] = r10
 
# Setup mapping for fimware arrea (also SAPIC)
 
mov r11 = cr.itir
movl r10 = ~0xfc
and r10 = r10, r11
movl r11 = (FW_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
movl r7 = 3
movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET
mov cr.ifa = r8
movl r10 = (KERNEL_TRANSLATION_FW)
itr.d dtr[r7] = r10
 
# initialize PSR
# Initialize PSR
 
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */
mov r9 = psr
 
or r10 = r10, r9
mov cr.ipsr = r10
mov cr.ifs = r0
128,11 → 139,14
srlz.i
 
.explicit
 
/*
* Return From Interupt is the only the way to fill upper half word of PSR.
* Return From Interrupt is the only way to
* fill the upper half word of PSR.
*/
rfi;;
rfi ;;
 
 
.global paging_start
paging_start:
 
140,45 → 154,64
* Now we are paging.
*/
 
# switch to register bank 1
# Switch to register bank 1
bsw.1
 
#ifdef CONFIG_SMP
# Am I BSP or AP?
movl r20 = bsp_started ;;
ld8 r20 = [r20] ;;
cmp.eq p3, p2 = r20, r0 ;;
#else
cmp.eq p3, p2 = r0, r0 ;; /* you are BSP */
#endif /* CONFIG_SMP */
# initialize register stack
# Initialize register stack
mov ar.rsc = r0
movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
mov ar.bspstore = r8
loadrs
 
# initialize memory stack to some sane value
# Initialize memory stack to some sane value
movl r12 = stack0 ;;
add r12 = -16, r12 /* allocate a scratch area on the stack */
 
# initialize gp (Global Pointer) register
# Initialize gp (Global Pointer) register
movl r20 = (VRN_KERNEL << VRN_SHIFT);;
or r20 = r20,r1;;
movl r1 = _hardcoded_load_address
/*
* Initialize hardcoded_* variables.
* Initialize hardcoded_* variables. Do only BSP
*/
movl r14 = _hardcoded_ktext_size
movl r15 = _hardcoded_kdata_size
movl r16 = _hardcoded_load_address ;;
addl r17 = @gprel(hardcoded_ktext_size), gp
addl r18 = @gprel(hardcoded_kdata_size), gp
addl r19 = @gprel(hardcoded_load_address), gp
addl r21 = @gprel(bootinfo), gp
(p3) movl r14 = _hardcoded_ktext_size
(p3) movl r15 = _hardcoded_kdata_size
(p3) movl r16 = _hardcoded_load_address ;;
(p3) addl r17 = @gprel(hardcoded_ktext_size), gp
(p3) addl r18 = @gprel(hardcoded_kdata_size), gp
(p3) addl r19 = @gprel(hardcoded_load_address), gp
(p3) addl r21 = @gprel(bootinfo), gp
;;
st8 [r17] = r14
st8 [r18] = r15
st8 [r19] = r16
st8 [r21] = r20
(p3) st8 [r17] = r14
(p3) st8 [r18] = r15
(p3) st8 [r19] = r16
(p3) st8 [r21] = r20
 
ssm (1 << 19) ;; /* Disable f32 - f127 */
srlz.i
srlz.d ;;
 
#ifdef CONFIG_SMP
(p2) movl r18 = main_ap ;;
(p2) mov b1 = r18 ;;
(p2) br.call.sptk.many b0 = b1
 
# Mark that BSP is on
mov r20 = 1 ;;
movl r21 = bsp_started ;;
st8 [r21] = r20 ;;
#endif
 
br.call.sptk.many b0 = arch_pre_main
 
movl r18 = main_bsp ;;
185,6 → 218,51
mov b1 = r18 ;;
br.call.sptk.many b0 = b1
 
 
0:
br 0b
 
#ifdef CONFIG_SMP
 
.align 4096
kernel_image_ap_start:
.auto
 
# Identify self(CPU) in OS structures by ID / EID
 
mov r9 = cr64
mov r10 = 1
movl r12 = 0xffffffff
movl r8 = cpu_by_id_eid_list
and r8 = r8, r12
shr r9 = r9, 16
add r8 = r8, r9
st1 [r8] = r10
# Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list)
kernel_image_ap_start_loop:
movl r11 = kernel_image_ap_start_loop
and r11 = r11, r12
mov b1 = r11
 
ld1 r20 = [r8] ;;
movl r21 = 3 ;;
cmp.eq p2, p3 = r20, r21 ;;
(p3) br.call.sptk.many b0 = b1
 
movl r11 = kernel_image_start
and r11 = r11, r12
mov b1 = r11
br.call.sptk.many b0 = b1
 
.align 16
.global bsp_started
bsp_started:
.space 8
 
.align 4096
.global cpu_by_id_eid_list
cpu_by_id_eid_list:
.space 65536
 
#endif /* CONFIG_SMP */
/branches/arm/kernel/arch/ia64/src/fpu_context.c
149,8 → 149,10
"stf.spill [%7] = f127, 0x80\n;;"
 
:
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])),
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])),
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
);
}
267,14 → 269,16
"ldf.fill f127 = [%7], 0x80\n;;"
 
:
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])),
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])),
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
);
}
 
void fpu_enable(void)
{
uint64_t a = 0 ;
uint64_t a = 0;
 
asm volatile (
"rsm %0 ;;"
/branches/arm/kernel/arch/ia64/src/ddi/ddi.c
1,5 → 1,6
/*
* Copyright (c) 2006 Jakub Jermar
* Copyright (c) 2008 Jakub vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
35,19 → 36,39
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <mm/slab.h>
#include <errno.h>
 
#define IO_MEMMAP_PAGES 16384
#define PORTS_PER_PAGE 4
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
* @param task Task.
* @param ioaddr Starting I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
if (!task->arch.iomap) {
uint8_t *map;
 
task->arch.iomap = malloc(sizeof(bitmap_t), 0);
map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0);
if(!map)
return ENOMEM;
bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES);
bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES);
}
uintptr_t iopage = ioaddr / PORTS_PER_PAGE;
size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
bitmap_set_range(task->arch.iomap, iopage, size / 4);
 
return 0;
}
 
/branches/arm/kernel/arch/ia64/src/proc/scheduler.c
47,14 → 47,17
{
}
 
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack is mapped in DTR. */
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack
* is mapped in DTR.
*/
void before_thread_runs_arch(void)
{
uintptr_t base;
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<(KERNEL_PAGE_WIDTH))) {
if ((uintptr_t) THREAD->kstack < base ||
(uintptr_t) THREAD->kstack > base + (1 << (KERNEL_PAGE_WIDTH))) {
/*
* Kernel stack of this thread is not mapped by DTR[TR_KERNEL].
* Use DTR[TR_KSTACK1] and DTR[TR_KSTACK2] to map it.
64,8 → 67,11
dtr_purge((uintptr_t) THREAD->kstack, PAGE_WIDTH+1);
/* insert DTR[TR_STACK1] and DTR[TR_STACK2] */
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, DTR_KSTACK2);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack,
KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack +
PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true,
DTR_KSTACK2);
}
/*
/branches/arm/kernel/arch/ia64/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-little
BFD_ARCH = ia64-elf64
TARGET = ia64-pc-linux-gnu
45,56 → 41,35
LFLAGS += -EL
AFLAGS += -mconstant-gp
 
DEFS += -D__64_BITS__ -D$(MACHINE)
BITS = 64
ENDIANESS = LE
 
## Compile with page hash table support.
#
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/ia64.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/ivt.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/vhpt.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/it.c
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/ia64.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/ivt.S \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/vhpt.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/smp/smp.c \
arch/$(KARCH)/src/drivers/it.c
 
ifeq ($(MACHINE),ski)
ARCH_SOURCES += arch/$(ARCH)/src/ski/ski.c
DEFS += -DSKI
# BFD = elf64-ia64-little
ARCH_SOURCES += arch/$(KARCH)/src/drivers/ski.c
BFD = binary
endif
 
ifeq ($(MACHINE),i460GX)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/ega.c
CONFIG_I8042 = y
DEFS += -DI460GX -DCONFIG_I8042
DEFS += -DI460GX
BFD = binary
endif
 
/branches/arm/kernel/arch/ppc32/src/ppc32.c
35,7 → 35,8
#include <config.h>
#include <arch.h>
#include <arch/boot/boot.h>
#include <arch/drivers/cuda.h>
#include <genarch/drivers/via-cuda/cuda.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
42,24 → 43,29
#include <userspace.h>
#include <proc/uarg.h>
#include <console/console.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <arch/drivers/pic.h>
#include <align.h>
#include <macros.h>
#include <string.h>
 
#define IRQ_COUNT 64
#define IRQ_COUNT 64
#define IRQ_CUDA 10
 
bootinfo_t bootinfo;
 
/** Performs ppc32-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Setup usermode */
init.cnt = bootinfo.taskmap.count;
uint32_t i;
for (i = 0; i < bootinfo.taskmap.count; i++) {
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo.taskmap.tasks[i].name);
}
}
 
75,36 → 81,43
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
 
#ifdef CONFIG_FB
/* Initialize framebuffer */
unsigned int visual;
switch (bootinfo.screen.bpp) {
case 8:
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel");
if (bootinfo.screen.addr) {
unsigned int visual;
switch (bootinfo.screen.bpp) {
case 8:
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel.");
}
fb_properties_t prop = {
.addr = bootinfo.screen.addr,
.offset = 0,
.x = bootinfo.screen.width,
.y = bootinfo.screen.height,
.scan = bootinfo.screen.scanline,
.visual = visual,
};
fb_init(&prop);
}
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual);
#endif
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
/* Initialize PIC */
pic_init(bootinfo.keyboard.addr, PAGE_SIZE);
/* Initialize I/O controller */
cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
/* Merge all zones to 1 big zone */
zone_merge_all();
}
120,6 → 133,35
 
void arch_post_smp_init(void)
{
if (bootinfo.macio.addr) {
/* Initialize PIC */
cir_t cir;
void *cir_arg;
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
 
#ifdef CONFIG_MAC_KBD
uintptr_t pa = bootinfo.macio.addr + 0x16000;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
size_t size = 2 * PAGE_SIZE;
cuda_t *cuda = (cuda_t *)
(hw_map(aligned_addr, offset + size) + offset);
/* Initialize I/O controller */
cuda_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
cuda_wire(cuda_instance, kbrd);
pic_enable_interrupt(IRQ_CUDA);
}
}
#endif
}
}
 
void calibrate_delay_loop(void)
128,11 → 170,13
 
void userspace(uspace_arg_t *kernel_uarg)
{
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry);
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_stack +
THREAD_STACK_SIZE - SP_DELTA,
(uintptr_t) kernel_uarg->uspace_entry);
/* Unreachable */
for (;;)
;
while (true);
}
 
/** Acquire console back for kernel
140,7 → 184,9
*/
void arch_grab_console(void)
{
cuda_grab();
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace
148,8 → 194,27
*/
void arch_release_console(void)
{
cuda_release();
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/arm/kernel/arch/ppc32/src/mm/tlb.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
35,12 → 35,22
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
#include <arch/interrupt.h>
#include <interrupt.h>
#include <mm/as.h>
#include <arch.h>
#include <print.h>
#include <macros.h>
#include <symtab.h>
 
static unsigned int seed = 10;
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
 
 
#define TLB_FLUSH \
"tlbie %0\n" \
"addi %0, %0, 0x1000\n"
 
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
65,7 → 75,7
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(as, badvaddr);
if ((pte) && (pte->p)) {
if ((pte) && (pte->present)) {
/*
* Mapping found in page tables.
* Immediately succeed.
87,7 → 97,7
*/
page_table_lock(as, lock);
pte = page_mapping_find(as, badvaddr);
ASSERT((pte) && (pte->p));
ASSERT((pte) && (pte->present));
*pfrc = 0;
return pte;
case AS_PF_DEFER:
96,11 → 106,10
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
panic("unexpected rc (%d)\n", rc);
panic("Unexpected rc (%d).", rc);
}
}
}
108,21 → 117,20
 
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
char *symbol;
char *sym2;
 
char *s = get_symtab_entry(istate->pc);
if (s)
symbol = s;
s = get_symtab_entry(istate->lr);
if (s)
sym2 = s;
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr,
symbol = symtab_fmt_name_lookup(istate->pc);
sym2 = symtab_fmt_name_lookup(istate->lr);
 
fault_if_from_uspace(istate,
"PHT Refill Exception on %p.", badvaddr);
panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
istate->pc, symbol, sym2);
}
 
 
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn)
static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
148,11 → 156,12
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) &&
(phte[base + i].api == api))) {
if ((phte[base + i].v)
&& (phte[base + i].vsid == vsid)
&& (phte[base + i].api == api)
&& (phte[base + i].h == 0)) {
found = true;
break;
}
159,86 → 168,25
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base2 + i].v) ||
((phte[base2 + i].vsid == vsid) &&
(phte[base2 + i].api == api))) {
if (!phte[base + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
}
}
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].pp = 2; // FIXME
}
 
 
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (vaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base + i].v) ||
((phte_physical[base + i].vsid == vsid) &&
(phte_physical[base + i].api == api))) {
found = true;
break;
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base2 + i].v) ||
((phte_physical[base2 + i].vsid == vsid) &&
(phte_physical[base2 + i].api == api))) {
if ((phte[base2 + i].v)
&& (phte[base2 + i].vsid == vsid)
&& (phte[base2 + i].api == api)
&& (phte[base2 + i].h == 1)) {
found = true;
base = base2;
h = 1;
247,26 → 195,37
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte[base2 + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
}
if (!found)
i = RANDI(seed) % 8;
}
phte_physical[base + i].v = 1;
phte_physical[base + i].vsid = vsid;
phte_physical[base + i].h = h;
phte_physical[base + i].api = api;
phte_physical[base + i].rpn = pfn;
phte_physical[base + i].r = 0;
phte_physical[base + i].c = 0;
phte_physical[base + i].pp = 2; // FIXME
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pte->pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
phte[base + i].pp = 2; // FIXME
}
 
 
/** Process Instruction/Data Storage Interrupt
/** Process Instruction/Data Storage Exception
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
* @param n Exception vector number.
* @param istate Interrupted register context.
*
*/
void pht_refill(int n, istate_t *istate)
285,12 → 244,9
lock = true;
}
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
if (n == VECTOR_DATA_STORAGE)
badvaddr = istate->dar;
else
badvaddr = istate->pc;
page_table_lock(as, lock);
310,12 → 266,12
page_table_unlock(as, lock);
return;
default:
panic("Unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
pte->a = 1; /* Record access to PTE */
pht_insert(badvaddr, pte->pfn);
pte->accessed = 1; /* Record access to PTE */
pht_insert(badvaddr, pte);
page_table_unlock(as, lock);
return;
326,22 → 282,19
}
 
 
/** Process Instruction/Data Storage Interrupt in Real Mode
/** Process Instruction/Data Storage Exception in Real Mode
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
* @param n Exception vector number.
* @param istate Interrupted register context.
*
*/
bool pht_real_refill(int n, istate_t *istate)
bool pht_refill_real(int n, istate_t *istate)
{
uintptr_t badvaddr;
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
if (n == VECTOR_DATA_STORAGE)
badvaddr = istate->dar;
else
badvaddr = istate->pc;
uint32_t physmem;
350,15 → 303,140
: "=r" (physmem)
);
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
return true;
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return false;
uint32_t page = (badvaddr >> 12) & 0xffff;
uint32_t api = (badvaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (badvaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((phte_real[base + i].v)
&& (phte_real[base + i].vsid == vsid)
&& (phte_real[base + i].api == api)
&& (phte_real[base + i].h == 0)) {
found = true;
break;
}
}
return false;
if (!found) {
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte_real[base + i].v) {
found = true;
break;
}
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((phte_real[base2 + i].v)
&& (phte_real[base2 + i].vsid == vsid)
&& (phte_real[base2 + i].api == api)
&& (phte_real[base2 + i].h == 1)) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte_real[base2 + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
}
if (!found) {
/* Use secondary hash to avoid collisions
with usual PHT refill handler. */
i = RANDI(seed_real) % 8;
base = base2;
h = 1;
}
}
phte_real[base + i].v = 1;
phte_real[base + i].vsid = vsid;
phte_real[base + i].h = h;
phte_real[base + i].api = api;
phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
phte_real[base + i].r = 0;
phte_real[base + i].c = 0;
phte_real[base + i].wimg = 0;
phte_real[base + i].pp = 2; // FIXME
return true;
}
 
 
/** Process ITLB/DTLB Miss Exception in Real Mode
*
*
*/
void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate)
{
uint32_t badvaddr = tlbmiss & 0xfffffffc;
uint32_t physmem;
asm volatile (
"mfsprg3 %0\n"
: "=r" (physmem)
);
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return; // FIXME
ptelo.rpn = KA2PA(badvaddr) >> 12;
ptelo.wimg = 0;
ptelo.pp = 2; // FIXME
uint32_t index = 0;
asm volatile (
"mtspr 981, %0\n"
"mtspr 982, %1\n"
"tlbld %2\n"
"tlbli %2\n"
: "=r" (index)
: "r" (ptehi),
"r" (ptelo)
);
}
 
 
void tlb_arch_init(void)
{
tlb_invalidate_all();
367,9 → 445,87
 
void tlb_invalidate_all(void)
{
uint32_t index;
asm volatile (
"tlbia\n"
"li %0, 0\n"
"sync\n"
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
"eieio\n"
"tlbsync\n"
"sync\n"
: "=r" (index)
);
}
 
393,7 → 549,7
}
 
 
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
// TODO
tlb_invalidate_all();
438,7 → 594,7
: "=r" (vsid)
: "r" (sr << 28)
);
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr,
printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
((vsid >> 30) & 1) ? " supervisor" : "",
((vsid >> 29) & 1) ? " user" : "");
/branches/arm/kernel/arch/ppc32/src/mm/frame.c
57,7 → 57,7
void frame_arch_init(void)
{
pfn_t minconf = 2;
count_t i;
size_t i;
pfn_t start, conf;
size_t size;
74,7 → 74,7
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE))
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE);
}
 
/* First is exception vector, second is 'implementation specific',
third and fourth is reserved, other contain real mode code */
frame_mark_unavailable(0, 8);
/branches/arm/kernel/arch/ppc32/src/mm/page.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
49,7 → 49,7
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%" PRIs " bytes)",
panic("Unable to map physical memory %p (%" PRIs " bytes).",
physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
/branches/arm/kernel/arch/ppc32/src/dummy.s
30,6 → 30,7
 
.global asm_delay_loop
.global sys_tls_set
.global cpu_halt
 
sys_tls_set:
b sys_tls_set
36,3 → 37,6
 
asm_delay_loop:
blr
 
cpu_halt:
b cpu_halt
/branches/arm/kernel/arch/ppc32/src/interrupt.c
60,7 → 60,6
int inum;
while ((inum = pic_get_pending()) != -1) {
bool ack = false;
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
69,11 → 68,17
if (irq->preack) {
/* Acknowledge the interrupt before processing */
pic_ack_interrupt(inum);
ack = true;
if (irq->cir)
irq->cir(irq->cir_arg, irq->inr);
}
irq->handler(irq, irq->arg);
irq->handler(irq);
if (!irq->preack) {
if (irq->cir)
irq->cir(irq->cir_arg, irq->inr);
}
spinlock_unlock(&irq->lock);
} else {
/*
83,9 → 88,6
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
if (!ack)
pic_ack_interrupt(inum);
}
}
 
92,8 → 94,8
 
static void exception_decrementer(int n, istate_t *istate)
{
start_decrementer();
clock();
start_decrementer();
}
 
 
/branches/arm/kernel/arch/ppc32/src/drivers/cuda.c
File deleted
/branches/arm/kernel/arch/ppc32/src/drivers/pic.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
38,53 → 38,61
#include <byteorder.h>
#include <bitops.h>
 
static volatile uint32_t *pic;
static volatile uint32_t *pic = NULL;
 
void pic_init(uintptr_t base, size_t size)
void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg)
{
pic = (uint32_t *) hw_map(base, size);
*cir = pic_ack_interrupt;
*cir_arg = NULL;
}
 
void pic_enable_interrupt(int intnum)
void pic_enable_interrupt(inr_t intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
if (pic) {
if (intnum < 32)
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
else
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
}
}
 
void pic_disable_interrupt(int intnum)
void pic_disable_interrupt(inr_t intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
if (pic) {
if (intnum < 32)
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
else
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
}
}
 
void pic_ack_interrupt(int intnum)
void pic_ack_interrupt(void *arg, inr_t intnum)
{
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
if (pic) {
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
}
}
 
/** Return number of pending interrupt */
int pic_get_pending(void)
{
int pending;
 
pending = pic[PIC_PENDING_LOW];
if (pending)
return fnzb32(pending);
if (pic) {
int pending;
pending = pic[PIC_PENDING_LOW];
if (pending)
return fnzb32(pending);
pending = pic[PIC_PENDING_HIGH];
if (pending)
return fnzb32(pending) + 32;
}
pending = pic[PIC_PENDING_HIGH];
if (pending)
return fnzb32(pending) + 32;
return -1;
}
 
/branches/arm/kernel/arch/ppc32/src/asm.S
34,6 → 34,7
.global iret
.global iret_syscall
.global memsetb
.global memsetw
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
66,9 → 67,9
mr sp, r4
 
# %r3 is defined to hold pcb_ptr - set it to 0
# %r6 is defined to hold pcb_ptr - set it to 0
 
xor r3, r3, r3
xor r6, r6, r6
# jump to userspace
131,8 → 132,8
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
rfi
 
197,14 → 198,17
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
 
rfi
 
memsetb:
b _memsetb
 
memsetw:
b _memsetw
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
/branches/arm/kernel/arch/ppc32/src/boot/boot.S
33,7 → 33,7
 
.global kernel_image_start
kernel_image_start:
 
# load temporal kernel stack
lis sp, kernel_stack@ha
52,7 → 52,7
beq bootinfo_end
addis r3, r3, 0x8000
 
lis r31, bootinfo@ha
addi r31, r31, bootinfo@l # r31 = bootinfo
/branches/arm/kernel/arch/ppc32/src/exception.S
60,7 → 60,7
2:
subi sp, sp, 160
subi sp, sp, 164
stw r0, 8(sp)
stw r2, 12(sp)
stw r3, 16(sp)
109,11 → 109,14
mfxer r12
stw r12, 148(sp)
mfsprg1 r12
mfdar r12
stw r12, 152(sp)
mfsprg1 r12
stw r12, 156(sp)
mfsprg2 r12
stw r12, 156(sp)
stw r12, 160(sp)
.endm
 
.org 0x100
137,16 → 140,7
exc_data_storage:
CONTEXT_STORE
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
b data_storage
 
.org 0x400
.global exc_instruction_storage
153,17 → 147,8
exc_instruction_storage:
CONTEXT_STORE
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
b instruction_storage
 
li r3, 3
b jump_to_kernel
 
.org 0x500
.global exc_external
exc_external:
223,7 → 208,7
.org 0xc00
.global exc_syscall
exc_syscall:
CONTEXT_STORE
CONTEXT_STORE
b jump_to_kernel_syscall
 
235,7 → 220,63
li r3, 12
b jump_to_kernel
 
.org 0x1000
.global exc_itlb_miss
exc_itlb_miss:
CONTEXT_STORE
b tlb_miss
 
.org 0x1100
.global exc_dtlb_miss_load
exc_dtlb_miss_load:
CONTEXT_STORE
b tlb_miss
 
.org 0x1200
.global exc_dtlb_miss_store
exc_dtlb_miss_store:
CONTEXT_STORE
b tlb_miss
 
.org 0x4000
data_storage:
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_refill_real
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
 
instruction_storage:
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_refill_real
cmpwi r3, 0
bne iret_real
li r3, 3
b jump_to_kernel
 
tlb_miss:
li r3, 16
mfspr r4, tlbmiss
mfspr r5, ptehi
mfspr r6, ptelo
mr r7, sp
addi r7, r7, 20
bl tlb_refill_real
b iret_real
 
jump_to_kernel:
lis r12, iret@ha
addi r12, r12, iret@l
272,7 → 313,6
rfi
 
iret_real:
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r3, 16(sp)
322,7 → 362,7
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
rfi
/branches/arm/kernel/arch/ppc32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ppc32/include/types.h
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
57,11 → 55,12
typedef uint32_t unative_t;
typedef int32_t native_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t */
#define PRIp "x"
#define PRIs "u"
#define PRIc "u"
#define PRIi "u"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
84,11 → 83,13
 
/** Page Table Entry. */
typedef struct {
unsigned p : 1; /**< Present bit. */
unsigned a : 1; /**< Accessed bit. */
unsigned g : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
unsigned present : 1; /**< Present bit. */
unsigned page_write_through : 1; /**< Write thought caching. */
unsigned page_cache_disable : 1; /**< No caching. */
unsigned accessed : 1; /**< Accessed bit. */
unsigned global : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
} pte_t;
 
#endif
/branches/arm/kernel/arch/ppc32/include/mm/page.h
102,25 → 102,25
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last-level PTEs. */
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->present != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12)
#define PTE_WRITABLE_ARCH(pte) 1
#define PTE_EXECUTABLE_ARCH(pte) 1
130,25 → 130,26
#include <mm/mm.h>
#include <arch/interrupt.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
return ((1 << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) |
((!p->present) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
(1 << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT) |
(p->g << PAGE_GLOBAL_SHIFT));
(p->global << PAGE_GLOBAL_SHIFT));
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
p->p = !(flags & PAGE_NOT_PRESENT);
p->g = (flags & PAGE_GLOBAL) != 0;
p->page_cache_disable = !(flags & PAGE_CACHEABLE);
p->present = !(flags & PAGE_NOT_PRESENT);
p->global = (flags & PAGE_GLOBAL) != 0;
p->valid = 1;
}
 
/branches/arm/kernel/arch/ppc32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
35,13 → 35,13
#ifndef KERN_ppc32_FRAME_H_
#define KERN_ppc32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
/branches/arm/kernel/arch/ppc32/include/mm/tlb.h
39,6 → 39,11
#include <arch/types.h>
#include <typedefs.h>
 
#define WIMG_GUARDED 0x01
#define WIMG_COHERENT 0x02
#define WIMG_NO_CACHE 0x04
#define WIMG_WRITETHRU 0x08
 
typedef struct {
unsigned v : 1; /**< Valid */
unsigned vsid : 24; /**< Virtual Segment ID */
53,9 → 58,27
unsigned pp : 2; /**< Page protection */
} phte_t;
 
typedef struct {
unsigned v : 1;
unsigned vsid : 24;
unsigned reserved0 : 1;
unsigned api : 6;
} ptehi_t;
 
typedef struct {
unsigned rpn : 20;
unsigned xpn : 3;
unsigned reserved0 : 1;
unsigned c : 1;
unsigned wimg : 4;
unsigned x : 1;
unsigned pp : 2;
} ptelo_t;
 
extern void pht_init(void);
extern void pht_refill(int n, istate_t *istate);
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void pht_init(void);
extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
 
#endif
 
/branches/arm/kernel/arch/ppc32/include/drivers/cuda.h
File deleted
/branches/arm/kernel/arch/ppc32/include/drivers/pic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
36,6 → 36,7
#define KERN_ppc32_PIC_H_
 
#include <arch/types.h>
#include <ddi/irq.h>
 
#define PIC_PENDING_LOW 8
#define PIC_PENDING_HIGH 4
44,11 → 45,11
#define PIC_ACK_LOW 10
#define PIC_ACK_HIGH 6
 
void pic_init(uintptr_t base, size_t size);
void pic_enable_interrupt(int intnum);
void pic_disable_interrupt(int intnum);
void pic_ack_interrupt(int intnum);
int pic_get_pending(void);
extern void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg);
extern void pic_enable_interrupt(inr_t intnum);
extern void pic_disable_interrupt(inr_t intnum);
extern void pic_ack_interrupt(void *arg, inr_t intnum);
extern int pic_get_pending(void);
 
#endif
 
/branches/arm/kernel/arch/ppc32/include/boot/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
35,21 → 35,24
#ifndef KERN_ppc32_BOOT_H_
#define KERN_ppc32_BOOT_H_
 
#define BOOT_OFFSET 0x8000
#define BOOT_OFFSET 0x8000
 
/* Temporary stack size for boot process */
#define TEMP_STACK_SIZE 0x1000
#define TEMP_STACK_SIZE 0x1000
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#ifndef __ASM__
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <arch/types.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
79,13 → 82,13
typedef struct {
uintptr_t addr;
unsigned int size;
} keyboard_t;
} macio_t;
 
typedef struct {
memmap_t memmap;
taskmap_t taskmap;
screen_t screen;
keyboard_t keyboard;
macio_t macio;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
/branches/arm/kernel/arch/ppc32/include/asm.h
36,6 → 36,7
#define KERN_ppc32_ASM_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
/** Enable interrupts.
149,6 → 150,36
 
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ppc32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
35,7 → 35,7
#ifndef KERN_ppc32_ARCH_H_
#define KERN_ppc32_ARCH_H_
 
#include <arch/drivers/cuda.h>
extern void arch_pre_main(void);
 
#endif
 
/branches/arm/kernel/arch/ppc32/include/asm/regname.h
211,6 → 211,9
#define dbat2l 541
#define dbat3u 542
#define dbat3l 543
#define tlbmiss 980
#define ptehi 981
#define ptelo 982
#define hid0 1008
 
/* MSR bits */
220,6 → 223,7
#define msr_ee (1 << 15)
 
/* HID0 bits */
#define hid0_sten (1 << 24)
#define hid0_ice (1 << 15)
#define hid0_dce (1 << 14)
#define hid0_icfi (1 << 11)
/branches/arm/kernel/arch/ppc32/include/barrier.h
55,6 → 55,7
"dcbst 0, %0\n"
"sync\n"
"icbi 0, %0\n"
"sync\n"
"isync\n"
:: "r" (addr)
);
76,7 → 77,10
asm volatile ("icbi 0, %0\n" :: "r" (addr + i));
}
 
asm volatile ("isync");
asm volatile (
"sync\n"
"isync\n"
);
}
 
#endif
/branches/arm/kernel/arch/ppc32/include/exception.h
75,6 → 75,7
uint32_t lr;
uint32_t ctr;
uint32_t xer;
uint32_t dar;
uint32_t r12;
uint32_t sp;
} istate_t;
/branches/arm/kernel/arch/ppc32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-powerpc
BFD_ARCH = powerpc:common
BFD = binary
43,46 → 39,24
AFLAGS += -a32
LFLAGS += -no-check-sections -N
 
DEFS += -D__32_BITS__
BITS = 32
ENDIANESS = BE
 
## Own configuration directives
#
 
CONFIG_FB = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/fpu_context.S \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/ppc32.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/exception.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/cuda.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/drivers/pic.c
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/debug/panic.s \
arch/$(KARCH)/src/fpu_context.S \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/ppc32.c \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/exception.S \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/drivers/pic.c
/branches/arm/kernel/arch/ppc32/_link.ld.in
1,11 → 1,11
/** PPC32 linker script
*
* umapped section:
* kernel text
* kernel data
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
* kernel text
* kernel data
*
*/
 
27,7 → 27,7
unmapped_kdata_start = .;
}
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
ktext_start = .;
*(K_TEXT_START);
*(.text);
37,22 → 37,22
*(K_DATA_START);
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
*(symtab.*); /* Symbol table, must be LAST symbol!*/
kdata_end = .;
}
}
/branches/arm/kernel/arch/arm32/include/machine.h
File deleted
/branches/arm/kernel/arch/arm32/include/console.h
File deleted
/branches/arm/kernel/arch/arm32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/arm32/include/boot.h
File deleted
/branches/arm/kernel/arch/arm32/include/debug/print.h
File deleted
/branches/arm/kernel/arch/arm32/include/types.h
53,8 → 53,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
64,10 → 62,11
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
#define PRIc "u" /**< Format for count_t. */
#define PRIi "u" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/arm32/include/mm/page.h
94,21 → 94,21
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i))
get_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i))
get_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i), (x))
set_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x))
set_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last-level PTE entries. */
#define PTE_VALID_ARCH(pte) \
193,9 → 193,8
static inline void set_ptl0_addr(pte_level0_t *pt)
{
asm volatile (
"mcr p15, 0, %0, c2, c0, 0 \n"
:
: "r"(pt)
"mcr p15, 0, %[pt], c2, c0, 0\n"
:: [pt] "r" (pt)
);
}
 
205,7 → 204,7
* @param pt Level 0 page table.
* @param i Index of the entry to return.
*/
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i)
static inline int get_pt_level0_flags(pte_level0_t *pt, size_t i)
{
pte_level0_t *p = &pt[i];
int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
220,7 → 219,7
* @param pt Level 1 page table.
* @param i Index of the entry to return.
*/
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i)
static inline int get_pt_level1_flags(pte_level1_t *pt, size_t i)
{
pte_level1_t *p = &pt[i];
 
245,7 → 244,7
* @param i index of the entry to be changed
* @param flags new flags
*/
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags)
static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags)
{
pte_level0_t *p = &pt[i];
 
273,7 → 272,7
* @param i Index of the entry to be changed.
* @param flags New flags.
*/
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags)
static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags)
{
pte_level1_t *p = &pt[i];
/branches/arm/kernel/arch/arm32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32mm
/** @addtogroup arm32mm
* @{
*/
/** @file
36,8 → 36,8
#ifndef KERN_arm32_FRAME_H_
#define KERN_arm32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4KB frames */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4KB frames */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
44,8 → 44,8
 
#include <arch/types.h>
 
#define BOOT_PAGE_TABLE_SIZE 0x4000
#define BOOT_PAGE_TABLE_ADDRESS 0x4000
#define BOOT_PAGE_TABLE_SIZE 0x4000
#define BOOT_PAGE_TABLE_ADDRESS 0x4000
 
#define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
/branches/arm/kernel/arch/arm32/include/mm/tlb.h
36,9 → 36,6
#ifndef KERN_arm32_TLB_H_
#define KERN_arm32_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/include/asm/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
37,26 → 37,9
#define KERN_arm32_ASM_BOOT_H_
 
/** Size of a temporary stack used for initial kernel start. */
#define TEMP_STACK_SIZE 0x100
#define TEMP_STACK_SIZE 0x100
 
#ifndef __ASM__
 
/** Kernel entry point.
*
* Implemented in assembly. Copies boot_bootinfo (declared as bootinfo in
* boot/arch/arm32/loader/main.c) to #bootinfo struct. Then jumps to
* #arch_pre_main and #main_bsp.
*
* @param entry Entry point address (not used).
* @param boot_bootinfo Struct holding information about loaded tasks.
* @param bootinfo_size Size of the bootinfo structure.
*/
extern void kernel_image_start(void *entry, void *boot_bootinfo,
unsigned int bootinfo_size);
 
#endif
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/arm32/include/drivers/qemu.h
File deleted
/branches/arm/kernel/arch/arm32/include/drivers/pl050.h
File deleted
/branches/arm/kernel/arch/arm32/include/drivers/gxemul.h
38,43 → 38,33
#ifndef KERN_arm32_GXEMUL_H_
#define KERN_arm32_GXEMUL_H_
 
#include <console/chardev.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
/** Timer frequency */
#define GXEMUL_TIMER_FREQ 100
#define GXEMUL_TIMER_FREQ 100
 
/** Struct containing mappings of gxemul HW devices into kernel part
* of virtual address space.
*/
typedef struct {
uintptr_t videoram;
uintptr_t kbd;
uintptr_t rtc;
uintptr_t rtc_freq;
uintptr_t rtc_ack;
uintptr_t irqc;
uintptr_t irqc_mask;
uintptr_t irqc_unmask;
} gxemul_hw_map_t;
#define GXEMUL_KBD_ADDRESS 0x10000000
#define GXEMUL_MP_ADDRESS 0x11000000
#define GXEMUL_FB_ADDRESS 0x12000000
#define GXEMUL_RTC_ADDRESS 0x15000000
#define GXEMUL_IRQC_ADDRESS 0x16000000
 
extern void gxemul_hw_map_init(void);
extern void gxemul_console_init(devno_t devno);
extern void gxemul_release_console(void);
extern void gxemul_grab_console(void);
extern void gxemul_timer_irq_start(void);
extern void gxemul_debug_putc(char ch);
extern void gxemul_cpu_halt(void);
extern void gxemul_irq_exception(int exc_no, istate_t *istate);
extern size_t gxemul_get_memory_size(void);
extern uintptr_t gxemul_get_fb_address(void);
extern void gxemul_fb_init(void);
extern void gxemul_frame_init(void);
extern void *gxemul_kbd;
extern void *gxemul_rtc;
extern void *gxemul_irqc;
 
#define GXEMUL_HALT_OFFSET 0x010
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_MP_MEMSIZE_OFFSET 0x090
#define GXEMUL_RTC_ACK_OFFSET 0x110
 
extern void gxemul_init(void);
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
36,6 → 36,26
#ifndef KERN_arm32_ARCH_H_
#define KERN_arm32_ARCH_H_
 
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <typedefs.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
uint32_t cnt;
utask_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
 
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo);
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/include/asm.h
26,10 → 26,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
/** @file
* @brief Declarations of functions implemented in assembly.
*/
 
36,6 → 36,7
#ifndef KERN_arm32_ASM_H_
#define KERN_arm32_ASM_H_
 
#include <typedefs.h>
#include <arch/types.h>
#include <arch/stack.h>
#include <config.h>
46,19 → 47,50
{
}
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
/** Return base address of current stack.
*
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t v;
asm volatile (
"and %0, sp, %1\n"
: "=r" (v)
: "r" (~(STACK_SIZE - 1))
"and %[v], sp, %[size]\n"
: [v] "=r" (v)
: [size] "r" (~(STACK_SIZE - 1))
);
return v;
}
/branches/arm/kernel/arch/arm32/include/regutils.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/**
57,7 → 57,10
static inline uint32_t nm## _status_reg_read(void) \
{ \
uint32_t retval; \
asm volatile("mrs %0, " #reg : "=r" (retval)); \
asm volatile( \
"mrs %[retval], " #reg \
: [retval] "=r" (retval) \
); \
return retval; \
}
 
64,7 → 67,10
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \
{ \
asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \
asm volatile( \
"msr " #reg "_" #field ", %[value]" \
:: [value] "r" (value) \
); \
}
 
 
/branches/arm/kernel/arch/arm32/include/atomic.h
26,10 → 26,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
/** @file
* @brief Atomic operations.
*/
 
42,26 → 42,26
* @param i Value to be added.
*
* @return Value after addition.
*
*/
static inline long atomic_add(atomic_t *val, int i)
{
int ret;
volatile long *mem = &(val->count);
 
asm volatile (
"1:\n"
"ldr r2, [%1] \n"
"add r3, r2, %2 \n"
"str r3, %0 \n"
"swp r3, r3, [%1] \n"
"cmp r3, r2 \n"
"bne 1b \n"
 
: "=m" (ret)
: "r" (mem), "r" (i)
"1:\n"
"ldr r2, [%[mem]]\n"
"add r3, r2, %[i]\n"
"str r3, %[ret]\n"
"swp r3, r3, [%[mem]]\n"
"cmp r3, r2\n"
"bne 1b\n"
: [ret] "=m" (ret)
: [mem] "r" (mem), [i] "r" (i)
: "r3", "r2"
);
 
return ret;
}
 
/branches/arm/kernel/arch/arm32/include/barrier.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
39,12 → 39,12
/*
* TODO: implement true ARM memory barriers for macros below.
*/
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
 
#define memory_barrier() asm volatile ("" ::: "memory")
#define read_barrier() asm volatile ("" ::: "memory")
#define write_barrier() asm volatile ("" ::: "memory")
#define memory_barrier() asm volatile ("" ::: "memory")
#define read_barrier() asm volatile ("" ::: "memory")
#define write_barrier() asm volatile ("" ::: "memory")
 
#define smc_coherence(a)
#define smc_coherence_block(a, l)
/branches/arm/kernel/arch/arm32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-littlearm
BFD_ARCH = arm
BFD = binary
39,68 → 35,28
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm
 
KERNEL_LOAD_ADDRESS = 0x80200000
 
ifeq ($(MACHINE), gxemul_testarm)
DMACHINE = MACHINE_GXEMUL_TESTARM
else ifeq ($(MACHINE), qemu_icp)
DMACHINE = MACHINE_QEMU_ICP
endif
 
ATSIGN = %
 
GCC_CFLAGS += -fno-zero-initialized-in-bss
 
DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE)
BITS = 32
ENDIANESS = LE
 
# Compile with framebuffer support
 
ifeq ($(CONFIG_FB), y)
DEFS += -DCONFIG_FB -DFB_INVERT_ENDIAN
endif
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
# no HW support for ASIDs
#CONFIG_ASID = y
#CONFIG_ASID_FIFO = y
CONFIG_PL050 = y
 
## Compile with support with software division and multiplication.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/arm32.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/dummy.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/debug/print.c \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/exception.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/page_fault.c
 
ifeq ($(MACHINE), gxemul_testarm)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c
else ifeq ($(MACHINE), qemu_icp)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/qemu.c \
arch/$(ARCH)/src/drivers/pl050.c
endif
 
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/arm32.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/dummy.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/exception.c \
arch/$(KARCH)/src/userspace.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/page_fault.c \
arch/$(KARCH)/src/drivers/gxemul.c
/branches/arm/kernel/arch/arm32/src/debug/print.c
File deleted
/branches/arm/kernel/arch/arm32/src/console.c
File deleted
/branches/arm/kernel/arch/arm32/src/mm/tlb.c
48,7 → 48,7
asm volatile (
"eor r1, r1\n"
"mcr p15, 0, r1, c8, c7, 0\n"
: : : "r1"
::: "r1"
);
}
 
68,9 → 68,8
static inline void invalidate_page(uintptr_t page)
{
asm volatile (
"mcr p15, 0, %0, c8, c7, 1"
:
: "r" (page)
"mcr p15, 0, %[page], c8, c7, 1\n"
:: [page] "r" (page)
);
}
 
81,7 → 80,7
* @param page Address of the first page whose entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
{
unsigned int i;
 
89,5 → 88,13
invalidate_page(page + i * PAGE_SIZE);
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/arm32/src/mm/page_fault.c
34,7 → 34,6
*/
#include <panic.h>
#include <arch/exception.h>
#include <arch/debug/print.h>
#include <arch/mm/page_fault.h>
#include <mm/as.h>
#include <genarch/mm/page_pt.h>
49,12 → 48,13
static inline fault_status_t read_fault_status_register(void)
{
fault_status_union_t fsu;
 
/* fault status is stored in CP15 register 5 */
asm volatile (
"mrc p15, 0, %0, c5, c0, 0"
: "=r"(fsu.dummy)
"mrc p15, 0, %[dummy], c5, c0, 0"
: [dummy] "=r" (fsu.dummy)
);
return fsu.fs;
}
 
61,17 → 61,18
/** Returns FAR (fault address register) content.
*
* @return FAR (fault address register) content (address that caused a page
* fault)
* fault)
*/
static inline uintptr_t read_fault_address_register(void)
{
uintptr_t ret;
 
/* fault adress is stored in CP15 register 6 */
asm volatile (
"mrc p15, 0, %0, c6, c0, 0"
: "=r"(ret)
"mrc p15, 0, %[ret], c6, c0, 0"
: [ret] "=r" (ret)
);
return ret;
}
 
80,29 → 81,26
* @param instr Instruction
*
* @return true when instruction is load/store, false otherwise
*
*/
static inline bool is_load_store_instruction(instruction_t instr)
{
/* load store immediate offset */
if (instr.type == 0x2) {
if (instr.type == 0x2)
return true;
}
 
/* load store register offset */
if (instr.type == 0x3 && instr.bit4 == 0) {
if ((instr.type == 0x3) && (instr.bit4 == 0))
return true;
}
 
/* load store multiple */
if (instr.type == 0x4) {
if (instr.type == 0x4)
return true;
}
 
/* oprocessor load/store */
if (instr.type == 0x6) {
if (instr.type == 0x6)
return true;
}
 
return false;
}
 
115,12 → 113,11
static inline bool is_swap_instruction(instruction_t instr)
{
/* swap, swapb instruction */
if (instr.type == 0x0 &&
(instr.opcode == 0x8 || instr.opcode == 0xa) &&
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) {
if ((instr.type == 0x0) &&
((instr.opcode == 0x8) || (instr.opcode == 0xa)) &&
(instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1))
return true;
}
 
return false;
}
 
142,8 → 139,8
 
/* undefined instructions */
if (instr.condition == 0xf) {
panic("page_fault - instruction doesn't access memory "
"(instr_code: %x, badvaddr:%x)", instr, badvaddr);
panic("page_fault - instruction does not access memory "
"(instr_code: %x, badvaddr:%x).", instr, badvaddr);
return PF_ACCESS_EXEC;
}
 
162,7 → 159,7
}
 
panic("page_fault - instruction doesn't access memory "
"(instr_code: %x, badvaddr:%x)", instr, badvaddr);
"(instr_code: %x, badvaddr:%x).", instr, badvaddr);
 
return PF_ACCESS_EXEC;
}
184,12 → 181,12
 
if (ret == AS_PF_FAULT) {
print_istate(istate);
dprintf("page fault - pc: %x, va: %x, status: %x(%x), "
printf("page fault - pc: %x, va: %x, status: %x(%x), "
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr,
access);
 
fault_if_from_uspace(istate, "Page fault: %#x", badvaddr);
panic("page fault\n");
fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
panic("Page fault.");
}
}
 
203,9 → 200,9
int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
 
if (ret == AS_PF_FAULT) {
dprintf("prefetch_abort\n");
printf("prefetch_abort\n");
print_istate(istate);
panic("page fault - prefetch_abort at address: %x\n",
panic("page fault - prefetch_abort at address: %x.",
istate->pc);
}
}
/branches/arm/kernel/arch/arm32/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32mm
/** @addtogroup arm32mm
* @{
*/
/** @file
35,9 → 35,8
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/machine.h>
#include <arch/drivers/gxemul.h>
#include <config.h>
#include <arch/debug/print.h>
 
/** Address of the last frame in the memory. */
uintptr_t last_frame = 0;
45,26 → 44,23
/** Creates memory zones. */
void frame_arch_init(void)
{
/* all memory as one zone */
zone_create(0, ADDR2PFN(machine_get_memory_size()),
last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
/* All memory as one zone */
zone_create(0, ADDR2PFN(last_frame),
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
last_frame = machine_get_memory_size();
 
/* blacklist boot page table */
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
 
/* Machine specific frame initialization */
machine_frame_init();
}
 
/** Frees the boot page table. */
void boot_page_table_free(void)
{
int i;
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) {
unsigned int i;
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++)
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS);
}
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/mm/page.c
51,19 → 51,15
*/
void page_arch_init(void)
{
int flags = PAGE_CACHEABLE;
page_mapping_operations = &pt_mapping_operations;
uintptr_t cur;
int flags;
 
page_mapping_operations = &pt_mapping_operations;
 
flags = PAGE_CACHEABLE;
 
/* PA2KA(identity) mapping for all frames until last_frame */
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
/* Kernel identity mapping */
for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
/* create mapping for exception table at high offset */
/* Create mapping for exception table at high offset */
#ifdef HIGH_EXCEPTION_VECTORS
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA);
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags);
70,9 → 66,9
#else
#error "Only high exception vector supported now"
#endif
 
as_switch(NULL, AS_KERNEL);
 
boot_page_table_free();
}
 
90,10 → 86,10
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) {
panic("Unable to map physical memory %p (%d bytes)",
panic("Unable to map physical memory %p (%d bytes).",
physaddr, size)
}
 
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
101,7 → 97,7
physaddr + PFN2ADDR(i),
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
}
 
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
/branches/arm/kernel/arch/arm32/src/arm32.c
34,36 → 34,37
*/
 
#include <arch.h>
#include <arch/boot.h>
#include <config.h>
#include <arch/console.h>
#include <ddi/device.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <arch/debug/print.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <config.h>
#include <interrupt.h>
#include <arch/regutils.h>
#include <arch/machine.h>
#include <userspace.h>
#include <macros.h>
#include <string.h>
 
/** Information about loaded tasks. */
bootinfo_t bootinfo;
 
/** Performs arm32 specific initialization before main_bsp() is called. */
void arch_pre_main(void)
/** Performs arm32-specific initialization before main_bsp() is called. */
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
{
unsigned int i;
 
init.cnt = bootinfo.cnt;
 
for (i = 0; i < bootinfo.cnt; ++i) {
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
init.cnt = bootinfo->cnt;
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) {
init.tasks[i].addr = bootinfo->tasks[i].addr;
init.tasks[i].size = bootinfo->tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo->tasks[i].name);
}
}
 
/** Performs arm32 specific initialization before mm is initialized. */
76,18 → 77,27
/** Performs arm32 specific initialization afterr mm is initialized. */
void arch_post_mm_init(void)
{
machine_hw_map_init();
 
gxemul_init();
/* Initialize exception dispatch table */
exception_init();
 
interrupt_init();
console_init(device_assign_devno());
 
#ifdef CONFIG_FB
machine_fb_init();
#endif
fb_properties_t prop = {
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&prop);
#else
#ifdef CONFIG_ARM_PRN
dsrlnout_init((ioport8_t *) gxemul_kbd);
#endif /* CONFIG_ARM_PRN */
#endif /* CONFIG_FB */
}
 
/** Performs arm32 specific tasks needed after cpu is initialized.
116,6 → 126,30
*/
void arch_post_smp_init(void)
{
#ifdef CONFIG_ARM_KBD
/*
* Initialize the GXemul keyboard port. Then initialize the serial line
* module and connect it to the GXemul keyboard.
*/
dsrlnin_instance_t *dsrlnin_instance
= dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
if (dsrlnin_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
dsrlnin_wire(dsrlnin_instance, srln);
}
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
}
 
 
149,7 → 183,8
/** Halts CPU. */
void cpu_halt(void)
{
machine_cpu_halt();
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
= 0;
}
 
/** Reboot. */
156,9 → 191,35
void arch_reboot()
{
/* not implemented */
for (;;)
;
while (1);
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
/** Acquire console back for kernel. */
void arch_grab_console(void)
{
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace. */
void arch_release_console(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/arm32/src/asm.S
30,6 → 30,7
.text
 
.global memsetb
.global memsetw
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
39,6 → 40,9
memsetb:
b _memsetb
 
memsetw:
b _memsetw
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
/branches/arm/kernel/arch/arm32/src/exception.c
34,13 → 34,12
*/
 
#include <arch/exception.h>
#include <arch/debug/print.h>
#include <arch/memstr.h>
#include <arch/regutils.h>
#include <interrupt.h>
#include <arch/machine.h>
#include <arch/mm/page_fault.h>
#include <arch/barrier.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <syscall/syscall.h>
 
63,57 → 62,60
*
* Temporary exception stack is used to save a few registers
* before stack switch takes place.
*
*/
inline static void setup_stack_and_save_regs()
{
asm volatile(
"ldr r13, =exc_stack \n"
"stmfd r13!, {r0} \n"
"mrs r0, spsr \n"
"and r0, r0, #0x1f \n"
"cmp r0, #0x10 \n"
"bne 1f \n"
 
asm volatile (
"ldr r13, =exc_stack\n"
"stmfd r13!, {r0}\n"
"mrs r0, spsr\n"
"and r0, r0, #0x1f\n"
"cmp r0, #0x10\n"
"bne 1f\n"
/* prev mode was usermode */
"ldmfd r13!, {r0} \n"
"ldr r13, =supervisor_sp \n"
"ldr r13, [r13] \n"
"stmfd r13!, {lr} \n"
"stmfd r13!, {r0-r12} \n"
"stmfd r13!, {r13, lr}^ \n"
"mrs r0, spsr \n"
"stmfd r13!, {r0} \n"
"b 2f \n"
 
"ldmfd r13!, {r0}\n"
"ldr r13, =supervisor_sp\n"
"ldr r13, [r13]\n"
"stmfd r13!, {lr}\n"
"stmfd r13!, {r0-r12}\n"
"stmfd r13!, {r13, lr}^\n"
"mrs r0, spsr\n"
"stmfd r13!, {r0}\n"
"b 2f\n"
/* mode was not usermode */
"1:\n"
"stmfd r13!, {r1, r2, r3} \n"
"mrs r1, cpsr \n"
"mov r2, lr \n"
"bic r1, r1, #0x1f \n"
"orr r1, r1, r0 \n"
"mrs r0, cpsr \n"
"msr cpsr_c, r1 \n"
 
"mov r3, r13 \n"
"stmfd r13!, {r2} \n"
"mov r2, lr \n"
"stmfd r13!, {r4-r12} \n"
"mov r1, r13 \n"
/* the following two lines are for debugging */
"mov sp, #0 \n"
"mov lr, #0 \n"
"msr cpsr_c, r0 \n"
 
"ldmfd r13!, {r4, r5, r6, r7} \n"
"stmfd r1!, {r4, r5, r6} \n"
"stmfd r1!, {r7} \n"
"stmfd r1!, {r2} \n"
"stmfd r1!, {r3} \n"
"mrs r0, spsr \n"
"stmfd r1!, {r0} \n"
"mov r13, r1 \n"
"2:\n"
"1:\n"
"stmfd r13!, {r1, r2, r3}\n"
"mrs r1, cpsr\n"
"mov r2, lr\n"
"bic r1, r1, #0x1f\n"
"orr r1, r1, r0\n"
"mrs r0, cpsr\n"
"msr cpsr_c, r1\n"
"mov r3, r13\n"
"stmfd r13!, {r2}\n"
"mov r2, lr\n"
"stmfd r13!, {r4-r12}\n"
"mov r1, r13\n"
/* the following two lines are for debugging */
"mov sp, #0\n"
"mov lr, #0\n"
"msr cpsr_c, r0\n"
"ldmfd r13!, {r4, r5, r6, r7}\n"
"stmfd r1!, {r4, r5, r6}\n"
"stmfd r1!, {r7}\n"
"stmfd r1!, {r2}\n"
"stmfd r1!, {r3}\n"
"mrs r0, spsr\n"
"stmfd r1!, {r0}\n"
"mov r13, r1\n"
"2:\n"
);
}
 
189,10 → 191,13
}
 
/** Calls exception dispatch routine. */
#define CALL_EXC_DISPATCH(exception) \
asm("mov r0, %0" : : "i" (exception)); \
asm("mov r1, r13"); \
asm("bl exc_dispatch");
#define CALL_EXC_DISPATCH(exception) \
asm volatile ( \
"mov r0, %[exc]\n" \
"mov r1, r13\n" \
"bl exc_dispatch\n" \
:: [exc] "i" (exception) \
);\
 
/** General exception handler.
*
201,9 → 206,9
*
* @param exception Exception number.
*/
#define PROCESS_EXCEPTION(exception) \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
#define PROCESS_EXCEPTION(exception) \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
load_regs();
 
/** Updates specified exception vector to jump to given handler.
254,7 → 259,10
/** Low-level Prefetch Abort Exception handler. */
static void prefetch_abort_exception_entry(void)
{
asm("sub lr, lr, #4");
asm volatile (
"sub lr, lr, #4"
);
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
}
 
261,7 → 269,10
/** Low-level Data Abort Exception handler. */
static void data_abort_exception_entry(void)
{
asm("sub lr, lr, #8");
asm volatile (
"sub lr, lr, #8"
);
PROCESS_EXCEPTION(EXC_DATA_ABORT);
}
 
273,7 → 284,10
*/
static void irq_exception_entry(void)
{
asm("sub lr, lr, #4");
asm volatile (
"sub lr, lr, #4"
);
setup_stack_and_save_regs();
switch_to_irq_servicing_mode();
293,6 → 307,12
istate->r3, istate->r4, istate->r5, istate->r6);
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
299,7 → 319,23
*/
static void irq_exception(int exc_no, istate_t *istate)
{
machine_irq_exception(exc_no, istate);
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Fills exception vectors with appropriate exception handlers. */
323,7 → 359,7
install_handler((unsigned) irq_exception_entry,
(unsigned *) EXC_IRQ_VEC);
install_handler((unsigned)fiq_exception_entry,
install_handler((unsigned) fiq_exception_entry,
(unsigned *) EXC_FIQ_VEC);
}
 
333,17 → 369,23
{
uint32_t control_reg;
asm volatile("mrc p15, 0, %0, c1, c1" : "=r" (control_reg));
asm volatile (
"mrc p15, 0, %[control_reg], c1, c1"
: [control_reg] "=r" (control_reg)
);
/* switch on the high vectors bit */
control_reg |= CP15_R1_HIGH_VECTORS_BIT;
asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg));
asm volatile (
"mcr p15, 0, %[control_reg], c1, c1"
:: [control_reg] "r" (control_reg)
);
}
#endif
 
/** Initializes exception handling.
*
*
* Installs low-level exception handlers and then registers
* exceptions and their handlers to kernel exception dispatcher.
*/
367,18 → 409,18
*/
void print_istate(istate_t *istate)
{
dprintf("istate dump:\n");
 
dprintf(" r0: %x r1: %x r2: %x r3: %x\n",
printf("istate dump:\n");
printf(" r0: %x r1: %x r2: %x r3: %x\n",
istate->r0, istate->r1, istate->r2, istate->r3);
dprintf(" r4: %x r5: %x r6: %x r7: %x\n",
printf(" r4: %x r5: %x r6: %x r7: %x\n",
istate->r4, istate->r5, istate->r6, istate->r7);
dprintf(" r8: %x r8: %x r10: %x r11: %x\n",
printf(" r8: %x r8: %x r10: %x r11: %x\n",
istate->r8, istate->r9, istate->r10, istate->r11);
dprintf(" r12: %x sp: %x lr: %x spsr: %x\n",
printf(" r12: %x sp: %x lr: %x spsr: %x\n",
istate->r12, istate->sp, istate->lr, istate->spsr);
 
dprintf(" pc: %x\n", istate->pc);
printf(" pc: %x\n", istate->pc);
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/panic.S
31,5 → 31,5
.global panic_printf
 
panic_printf:
bl debug_printf
bl printf
bl cpu_halt
/branches/arm/kernel/arch/arm32/src/interrupt.c
35,13 → 35,16
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <ddi/irq.h>
#include <arch/machine.h>
#include <ddi/device.h>
#include <interrupt.h>
 
/** Initial size of a table holding interrupt handlers. */
#define IRQ_COUNT 8
 
static irq_t gxemul_timer_irq;
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
49,7 → 52,7
ipl_t interrupts_disable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
return ipl;
62,9 → 65,9
ipl_t interrupts_enable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
 
return ipl;
}
 
88,6 → 91,41
return current_status_reg_read();
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initialize basic tables for exception dispatching
* and starts the timer.
*/
94,7 → 132,16
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
machine_timer_irq_start();
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
irq_register(&gxemul_timer_irq);
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/drivers/qemu.c
File deleted
/branches/arm/kernel/arch/arm32/src/drivers/pl050.c
File deleted
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c
33,374 → 33,19
* @brief GXemul drivers.
*/
 
#include <interrupt.h>
#include <ipc/irq.h>
#include <console/chardev.h>
#include <arch/drivers/gxemul.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <print.h>
#include <ddi/device.h>
#include <mm/page.h>
#include <arch/machine.h>
#include <arch/debug/print.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
 
/* Addresses of devices. */
#define GXEMUL_VIDEORAM 0x10000000
#define GXEMUL_KBD 0x10000000
#define GXEMUL_HALT_OFFSET 0x10
#define GXEMUL_RTC 0x15000000
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_RTC_ACK_OFFSET 0x110
#define GXEMUL_IRQC 0x16000000
#define GXEMUL_IRQC_MASK_OFFSET 0x4
#define GXEMUL_IRQC_UNMASK_OFFSET 0x8
#define GXEMUL_MP 0x11000000
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090
#define GXEMUL_FB 0x12000000
void *gxemul_kbd;
void *gxemul_rtc;
void *gxemul_irqc;
 
/* IRQs */
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
static gxemul_hw_map_t gxemul_hw_map;
static chardev_t console;
static irq_t gxemul_console_irq;
static irq_t gxemul_timer_irq;
 
static bool hw_map_init_called = false;
 
static void gxemul_kbd_enable(chardev_t *dev);
static void gxemul_kbd_disable(chardev_t *dev);
static void gxemul_write(chardev_t *dev, const char ch);
static char gxemul_do_read(chardev_t *dev);
 
static chardev_operations_t gxemul_ops = {
.resume = gxemul_kbd_enable,
.suspend = gxemul_kbd_disable,
.write = gxemul_write,
.read = gxemul_do_read,
};
 
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
void gxemul_init(void)
{
return *((uint32_t *) gxemul_hw_map.irqc);
gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
}
 
 
/** Masks interrupt.
*
* @param irq interrupt number
*/
static inline void gxemul_irqc_mask(uint32_t irq)
{
*((uint32_t *) gxemul_hw_map.irqc_mask) = irq;
}
 
 
/** Unmasks interrupt.
*
* @param irq interrupt number
*/
static inline void gxemul_irqc_unmask(uint32_t irq)
{
*((uint32_t *) gxemul_hw_map.irqc_unmask) = irq;
}
 
/** Initializes the gxemul testarm frame buffer */
void gxemul_fb_init(void)
{
fb_init(gxemul_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8);
}
 
/** Initializes #gxemul_hw_map. */
void gxemul_hw_map_init(void)
{
gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE);
gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE);
gxemul_hw_map.rtc = hw_map(GXEMUL_RTC, PAGE_SIZE);
gxemul_hw_map.irqc = hw_map(GXEMUL_IRQC, PAGE_SIZE);
 
gxemul_hw_map.rtc_freq = gxemul_hw_map.rtc + GXEMUL_RTC_FREQ_OFFSET;
gxemul_hw_map.rtc_ack = gxemul_hw_map.rtc + GXEMUL_RTC_ACK_OFFSET;
gxemul_hw_map.irqc_mask = gxemul_hw_map.irqc + GXEMUL_IRQC_MASK_OFFSET;
gxemul_hw_map.irqc_unmask = gxemul_hw_map.irqc +
GXEMUL_IRQC_UNMASK_OFFSET;
 
hw_map_init_called = true;
}
 
 
/** Putchar that works with gxemul.
*
* @param dev Not used.
* @param ch Characted to be printed.
*/
static void gxemul_write(chardev_t *dev, const char ch)
{
*((char *) gxemul_hw_map.videoram) = ch;
}
 
/** Enables gxemul keyboard (interrupt unmasked).
*
* @param dev Not used.
*
* Called from getc().
*/
static void gxemul_kbd_enable(chardev_t *dev)
{
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
}
 
/** Disables gxemul keyboard (interrupt masked).
*
* @param dev not used
*
* Called from getc().
*/
static void gxemul_kbd_disable(chardev_t *dev)
{
gxemul_irqc_mask(GXEMUL_KBD_IRQ);
}
 
/** Read character using polling, assume interrupts disabled.
*
* @param dev Not used.
*/
static char gxemul_do_read(chardev_t *dev)
{
char ch;
 
while (1) {
ch = *((volatile char *) gxemul_hw_map.kbd);
if (ch) {
if (ch == '\r')
return '\n';
if (ch == 0x7f)
return '\b';
return ch;
}
}
}
 
/** Process keyboard interrupt.
*
* @param irq IRQ information.
* @param arg Not used.
*/
static void gxemul_irq_handler(irq_t *irq, void *arg, ...)
{
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) {
ipc_irq_send_notif(irq);
} else {
char ch = 0;
ch = *((char *) gxemul_hw_map.kbd);
if (ch == '\r') {
ch = '\n';
}
if (ch == 0x7f) {
ch = '\b';
}
chardev_push_character(&console, ch);
}
}
 
static irq_ownership_t gxemul_claim(void)
{
return IRQ_ACCEPT;
}
 
 
/** Acquire console back for kernel. */
void gxemul_grab_console(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&gxemul_console_irq.lock);
gxemul_console_irq.notif_cfg.notify = false;
spinlock_unlock(&gxemul_console_irq.lock);
interrupts_restore(ipl);
}
 
/** Return console to userspace. */
void gxemul_release_console(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&gxemul_console_irq.lock);
if (gxemul_console_irq.notif_cfg.answerbox) {
gxemul_console_irq.notif_cfg.notify = true;
}
spinlock_unlock(&gxemul_console_irq.lock);
interrupts_restore(ipl);
}
 
/** Initializes console object representing gxemul console.
*
* @param devno device number.
*/
void gxemul_console_init(devno_t devno)
{
chardev_initialize("gxemul_console", &console, &gxemul_ops);
stdin = &console;
stdout = &console;
irq_initialize(&gxemul_console_irq);
gxemul_console_irq.devno = devno;
gxemul_console_irq.inr = GXEMUL_KBD_IRQ;
gxemul_console_irq.claim = gxemul_claim;
gxemul_console_irq.handler = gxemul_irq_handler;
irq_register(&gxemul_console_irq);
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd);
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency;
}
 
static irq_ownership_t gxemul_timer_claim(void)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
/* acknowledge tick */
*((uint32_t*) gxemul_hw_map.rtc_ack) = 0;
}
 
/** Initializes and registers timer interrupt handler. */
static void gxemul_timer_irq_init(void)
{
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
 
irq_register(&gxemul_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void gxemul_timer_irq_start(void)
{
gxemul_timer_irq_init();
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
size_t gxemul_get_memory_size(void)
{
return *((int *) (GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
}
 
/** Prints a character.
*
* @param ch Character to be printed.
*/
void gxemul_debug_putc(char ch)
{
char *addr = 0;
if (!hw_map_init_called) {
addr = (char *) GXEMUL_KBD;
} else {
addr = (char *) gxemul_hw_map.videoram;
}
 
*(addr) = ch;
}
 
/** Stops gxemul. */
void gxemul_cpu_halt(void)
{
char * addr = 0;
if (!hw_map_init_called) {
addr = (char *) GXEMUL_KBD;
} else {
addr = (char *) gxemul_hw_map.videoram;
}
*(addr + GXEMUL_HALT_OFFSET) = '\0';
}
 
/** Gxemul specific interrupt exception handler.
*
* Determines sources of the interrupt from interrupt controller and
* calls high-level handlers for them.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void gxemul_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
dprintf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t gxemul_get_fb_address(void)
{
return (uintptr_t) GXEMUL_FB;
}
 
/*
* GXEMUL specific frame initialization
*/
void gxemul_frame_init(void)
{
}
/** @}
*/
/branches/arm/kernel/arch/arm32/src/cpu/cpu.c
36,7 → 36,7
#include <arch/cpu.h>
#include <cpu.h>
#include <arch.h>
#include <print.h>
#include <print.h>
 
/** Number of indexes left out in the #imp_data array */
#define IMP_DATA_START_OFFSET 0x40
82,10 → 82,10
{
uint32_t ident;
asm volatile (
"mrc p15, 0, %0, c0, c0, 0\n"
: "=r" (ident)
"mrc p15, 0, %[ident], c0, c0, 0\n"
: [ident] "=r" (ident)
);
 
cpu->imp_num = ident >> 24;
cpu->variant_num = (ident << 8) >> 28;
cpu->arch_num = (ident << 12) >> 28;
/branches/arm/kernel/arch/arm32/src/userspace.c
90,12 → 90,11
 
/* set user mode, set registers, jump */
asm volatile (
"mov sp, %0 \n"
"msr spsr_c, %1 \n"
"ldmfd sp!, {r0-r12, sp, lr}^ \n"
"mov sp, %[ustate]\n"
"msr spsr_c, %[user_mode]\n"
"ldmfd sp!, {r0-r12, sp, lr}^\n"
"ldmfd sp!, {pc}^\n"
:
: "r" (&ustate), "r" (user_mode)
:: [ustate] "r" (&ustate), [user_mode] "r" (user_mode)
);
 
/* unreachable */
/branches/arm/kernel/arch/arm32/src/start.S
40,30 → 40,12
mrs r3, cpsr
bic r3, r3, #0x1f
orr r3, r3, #0x13
msr cpsr_c, r3
msr cpsr_c, r3
ldr sp, =temp_stack
 
cmp r2, #0
beq bootinfo_end
 
ldr r3, =bootinfo
 
bootinfo_loop:
ldr r4, [r1]
str r4, [r3]
 
add r1, r1, #4
add r3, r3, #4
add r2, r2, #-4
 
cmp r2, #0
bne bootinfo_loop
bootinfo_end:
 
bl arch_pre_main
 
bl main_bsp
 
.space TEMP_STACK_SIZE
74,4 → 56,3
 
supervisor_sp:
.space 4
 
/branches/arm/kernel/arch/arm32/_link.ld.in
1,15 → 1,16
/*
* ARM linker script
*
* ARM linker script
*
* kernel text
* kernel data
*
*
*/
 
#define KERNEL_LOAD_ADDRESS 0x80200000
 
OUTPUT_ARCH(arm)
ENTRY(kernel_image_start)
ENTRY(kernel_image_start)
 
 
SECTIONS {
. = KERNEL_LOAD_ADDRESS;
.text : {
19,29 → 20,29
}
.data : {
kdata_start = .;
*(.data); /* initialized data */
*(.data); /* initialized data */
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(KERNEL_LOAD_ADDRESS);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
*(.rodata*);
*(.sdata);
*(.reginfo);
symbol_table = .;
*(symtab.*);
*(symtab.*);
}
.sbss : {
*(.sbss);
*(.scommon);
}
 
kdata_end = .;
 
/DISCARD/ : {
*(.mdebug*);
*(.pdr);
48,5 → 49,4
*(.comment);
*(.note);
}
 
}
/branches/arm/kernel/arch/amd64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/amd64/include/types.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
57,11 → 55,12
typedef uint64_t unative_t;
typedef int64_t native_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t */
#define PRIp "llx"
#define PRIs "llu"
#define PRIc "llu"
#define PRIi "llu"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
/branches/arm/kernel/arch/amd64/include/proc/task.h
40,7 → 40,7
 
typedef struct {
/** I/O Permission bitmap Generation counter. */
count_t iomapver;
size_t iomapver;
/** I/O Permission bitmap. */
bitmap_t iomap;
} task_arch_t;
/branches/arm/kernel/arch/amd64/include/mm/page.h
112,33 → 112,33
#define SET_PTL0_ADDRESS_ARCH(ptl0) \
(write_cr3((uintptr_t) (ptl0)))
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
set_pt_addr((pte_t *) (ptl0), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl0), (size_t) (i), a)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) \
set_pt_addr((pte_t *) (ptl1), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl1), (size_t) (i), a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) \
set_pt_addr((pte_t *) (ptl2), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl2), (size_t) (i), a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
set_pt_addr((pte_t *) (ptl3), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl3), (size_t) (i), a)
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
get_pt_flags((pte_t *) (ptl1), (index_t) (i))
get_pt_flags((pte_t *) (ptl1), (size_t) (i))
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
get_pt_flags((pte_t *) (ptl2), (index_t) (i))
get_pt_flags((pte_t *) (ptl2), (size_t) (i))
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) \
set_pt_flags((pte_t *) (ptl1), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl1), (size_t) (i), (x))
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) \
set_pt_flags((pte_t *) (ptl2), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl2), (size_t) (i), (x))
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last-level PTE entries. */
#define PTE_VALID_ARCH(p) \
176,7 → 176,7
*/
#define PFERR_CODE_ID (1 << 4)
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
189,7 → 189,7
p->global << PAGE_GLOBAL_SHIFT);
}
 
static inline void set_pt_addr(pte_t *pt, index_t i, uintptr_t a)
static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a)
{
pte_t *p = &pt[i];
 
197,7 → 197,7
p->addr_32_51 = a >> 32;
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
/branches/arm/kernel/arch/amd64/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64mm
/** @addtogroup amd64mm
* @{
*/
/** @file
39,8 → 39,8
#include <arch/types.h>
#endif /* __ASM__ */
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifndef __ASM__
extern uintptr_t last_frame;
/branches/arm/kernel/arch/amd64/include/mm/tlb.h
35,9 → 35,6
#ifndef KERN_amd64_TLB_H_
#define KERN_amd64_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
/branches/arm/kernel/arch/amd64/include/cpu.h
35,9 → 35,9
#ifndef KERN_amd64_CPU_H_
#define KERN_amd64_CPU_H_
 
#define RFLAGS_IF (1 << 9)
#define RFLAGS_DF (1 << 10)
#define RFLAGS_RF (1 << 16)
#define RFLAGS_IF (1 << 9)
#define RFLAGS_DF (1 << 10)
#define RFLAGS_RF (1 << 16)
 
#define EFER_MSR_NUM 0xc0000080
#define AMD_SCE_FLAG 0
62,17 → 62,15
int family;
int model;
int stepping;
struct tss *tss;
tss_t *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
size_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
 
struct star_msr {
};
 
struct lstar_msr {
};
 
extern void set_efer_flag(int flag);
/branches/arm/kernel/arch/amd64/include/atomic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
41,17 → 41,29
 
static inline void atomic_inc(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock incq %0\n" : "+m" (val->count));
asm volatile (
"lock incq %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("incq %0\n" : "+m" (val->count));
asm volatile (
"incq %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
static inline void atomic_dec(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock decq %0\n" : "+m" (val->count));
asm volatile (
"lock decq %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("decq %0\n" : "+m" (val->count));
asm volatile (
"decq %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
58,12 → 70,12
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
 
asm volatile (
"lock xaddq %1, %0\n"
: "+m" (val->count), "+r" (r)
"lock xaddq %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r" (r)
);
 
return r;
}
 
72,23 → 84,23
long r = -1;
asm volatile (
"lock xaddq %1, %0\n"
: "+m" (val->count), "+r" (r)
"lock xaddq %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r" (r)
);
return r;
}
 
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
 
static inline uint64_t test_and_set(atomic_t *val) {
uint64_t v;
asm volatile (
"movq $1, %0\n"
"xchgq %0, %1\n"
: "=r" (v), "+m" (val->count)
"movq $1, %[v]\n"
"xchgq %[v], %[count]\n"
: [v] "=r" (v), [count] "+m" (val->count)
);
return v;
99,22 → 111,20
static inline void atomic_lock_arch(atomic_t *val)
{
uint64_t tmp;
 
preemption_disable();
asm volatile (
"0:\n"
#ifdef CONFIG_HT
"pause\n"
#endif
"mov %0, %1\n"
"testq %1, %1\n"
"mov %[count], %[tmp]\n"
"testq %[tmp], %[tmp]\n"
"jnz 0b\n" /* lightweight looping on locked spinlock */
"incq %1\n" /* now use the atomic operation */
"xchgq %0, %1\n"
"testq %1, %1\n"
"incq %[tmp]\n" /* now use the atomic operation */
"xchgq %[count], %[tmp]\n"
"testq %[tmp], %[tmp]\n"
"jnz 0b\n"
: "+m" (val->count), "=&r" (tmp)
: [count] "+m" (val->count), [tmp] "=&r" (tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
/branches/arm/kernel/arch/amd64/include/cpuid.h
35,14 → 35,15
#ifndef KERN_amd64_CPUID_H_
#define KERN_amd64_CPUID_H_
 
#define AMD_CPUID_EXTENDED 0x80000001
#define AMD_EXT_NOEXECUTE 20
#define AMD_EXT_LONG_MODE 29
#define AMD_CPUID_EXTENDED 0x80000001
#define AMD_EXT_NOEXECUTE 20
#define AMD_EXT_LONG_MODE 29
 
#define INTEL_CPUID_STANDARD 0x00000001
#define INTEL_CPUID_EXTENDED 0x80000000
#define INTEL_SSE2 26
#define INTEL_FXSAVE 24
#define INTEL_CPUID_LEVEL 0x00000000
#define INTEL_CPUID_STANDARD 0x00000001
#define INTEL_CPUID_EXTENDED 0x80000000
#define INTEL_SSE2 26
#define INTEL_FXSAVE 24
 
#ifndef __ASM__
 
/branches/arm/kernel/arch/amd64/include/pm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
36,63 → 36,60
#define KERN_amd64_PM_H_
 
#ifndef __ASM__
# include <arch/types.h>
# include <arch/context.h>
#include <arch/types.h>
#include <arch/context.h>
#endif
 
#define IDT_ITEMS 64
#define GDT_ITEMS 8
#define IDT_ITEMS 64
#define GDT_ITEMS 8
 
 
#define NULL_DES 0
/* Warning: Do not reorder next items, unless you look into syscall.c!!! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* EndOfWarning */
#define TSS_DES 6
#define NULL_DES 0
/* Warning: Do not reorder the following items, unless you look into syscall.c! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* End of warning */
#define TSS_DES 6
 
 
 
#ifdef CONFIG_FB
 
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
#undef GDT_ITEMS
#define GDT_ITEMS 9
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
 
#endif /*CONFIG_FB*/
#undef GDT_ITEMS
#define GDT_ITEMS 9
 
#endif /* CONFIG_FB */
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
#define PL_KERNEL 0
#define PL_USER 3
 
#define PL_KERNEL 0
#define PL_USER 3
#define AR_PRESENT ( 1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_READABLE (1 << 1)
#define AR_TSS (0x09)
#define AR_INTERRUPT (0x0e)
#define AR_TRAP (0x0f)
 
#define AR_PRESENT (1<<7)
#define AR_DATA (2<<3)
#define AR_CODE (3<<3)
#define AR_WRITABLE (1<<1)
#define AR_READABLE (1<<1)
#define AR_TSS (0x9)
#define AR_INTERRUPT (0xe)
#define AR_TRAP (0xf)
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
 
#define DPL_KERNEL (PL_KERNEL<<5)
#define DPL_USER (PL_USER<<5)
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */
#define IO_PORTS (64 * 1024)
 
#define IO_PORTS (64*1024)
 
#ifndef __ASM__
 
struct descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
103,10 → 100,9
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
} __attribute__ ((packed)) descriptor_t;
 
struct tss_descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
121,10 → 117,9
unsigned base_24_31: 8;
unsigned base_32_63 : 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct tss_descriptor tss_descriptor_t;
} __attribute__ ((packed)) tss_descriptor_t;
 
struct idescriptor {
typedef struct {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned ist:3;
135,22 → 130,19
unsigned offset_16_31: 16;
unsigned offset_32_63: 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
} __attribute__ ((packed)) idescriptor_t;
 
struct ptr_16_64 {
typedef struct {
uint16_t limit;
uint64_t base;
} __attribute__ ((packed));
typedef struct ptr_16_64 ptr_16_64_t;
} __attribute__ ((packed)) ptr_16_64_t;
 
struct ptr_16_32 {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
} __attribute__ ((packed)) ptr_16_32_t;
 
struct tss {
typedef struct {
uint32_t reserve1;
uint64_t rsp0;
uint64_t rsp1;
167,8 → 159,7
uint16_t reserve4;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
} __attribute__ ((packed)) tss_t;
 
extern tss_t *tss_p;
 
/branches/arm/kernel/arch/amd64/include/asm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
36,6 → 36,8
#define KERN_amd64_ASM_H_
 
#include <config.h>
#include <arch/types.h>
#include <typedefs.h>
 
extern void asm_delay_loop(uint32_t t);
extern void asm_fake_loop(uint32_t t);
45,12 → 47,17
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t v;
asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1)));
asm volatile (
"andq %%rsp, %[v]\n"
: [v] "=r" (v)
: "0" (~((uint64_t) STACK_SIZE-1))
);
return v;
}
62,7 → 69,11
 
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
asm volatile (
"0:\n"
" hlt\n"
" jmp 0b\n"
);
}
 
 
72,15 → 83,63
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint8_t inb(uint16_t port)
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t val;
asm volatile (
"inb %w[port], %b[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port));
/** Word from port
*
* Get word from port
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t val;
asm volatile (
"inw %w[port], %w[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
/** Double word from port
*
* Get double word from port
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t val;
asm volatile (
"inl %w[port], %[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
/** Byte to port
*
* Output byte to port
87,12 → 146,48
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outb(uint16_t port, uint8_t val)
static inline void pio_write_8(ioport8_t *port, uint8_t val)
{
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port));
asm volatile (
"outb %b[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Word to port
*
* Output word to port
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void pio_write_16(ioport16_t *port, uint16_t val)
{
asm volatile (
"outw %w[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Double word to port
*
* Output double word to port
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void pio_write_32(ioport32_t *port, uint32_t val)
{
asm volatile (
"outl %[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Swap Hidden part of GS register with visible one */
static inline void swapgs(void)
{
105,15 → 200,18
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_enable(void) {
ipl_t v;
__asm__ volatile (
asm volatile (
"pushfq\n"
"popq %0\n"
"popq %[v]\n"
"sti\n"
: "=r" (v)
: [v] "=r" (v)
);
return v;
}
 
123,15 → 221,18
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_disable(void) {
ipl_t v;
__asm__ volatile (
asm volatile (
"pushfq\n"
"popq %0\n"
"popq %[v]\n"
"cli\n"
: "=r" (v)
);
: [v] "=r" (v)
);
return v;
}
 
140,13 → 241,14
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*
*/
static inline void interrupts_restore(ipl_t ipl) {
__asm__ volatile (
"pushq %0\n"
asm volatile (
"pushq %[ipl]\n"
"popfq\n"
: : "r" (ipl)
);
:: [ipl] "r" (ipl)
);
}
 
/** Return interrupt priority level.
154,14 → 256,17
* Return EFLAFS.
*
* @return Current interrupt priority level.
*
*/
static inline ipl_t interrupts_read(void) {
ipl_t v;
__asm__ volatile (
asm volatile (
"pushfq\n"
"popq %0\n"
: "=r" (v)
"popq %[v]\n"
: [v] "=r" (v)
);
return v;
}
 
168,21 → 273,25
/** Write to MSR */
static inline void write_msr(uint32_t msr, uint64_t value)
{
__asm__ volatile (
"wrmsr;" : : "c" (msr),
"a" ((uint32_t)(value)),
"d" ((uint32_t)(value >> 32))
);
asm volatile (
"wrmsr\n"
:: "c" (msr),
"a" ((uint32_t) (value)),
"d" ((uint32_t) (value >> 32))
);
}
 
static inline unative_t read_msr(uint32_t msr)
{
uint32_t ax, dx;
 
__asm__ volatile (
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr)
);
return ((uint64_t)dx << 32) | ax;
asm volatile (
"rdmsr\n"
: "=a" (ax), "=d" (dx)
: "c" (msr)
);
return ((uint64_t) dx << 32) | ax;
}
 
 
189,29 → 298,29
/** Enable local APIC
*
* Enable local APIC in MSR.
*
*/
static inline void enable_l_apic_in_msr()
{
__asm__ volatile (
asm volatile (
"movl $0x1b, %%ecx\n"
"rdmsr\n"
"orl $(1<<11),%%eax\n"
"orl $(1 << 11),%%eax\n"
"orl $(0xfee00000),%%eax\n"
"wrmsr\n"
:
:
:"%eax","%ecx","%edx"
);
::: "%eax","%ecx","%edx"
);
}
 
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
__asm__ volatile (
"mov %%rip, %0"
: "=r" (ip)
);
asm volatile (
"mov %%rip, %[ip]"
: [ip] "=r" (ip)
);
return ip;
}
 
218,59 → 327,84
/** Invalidate TLB Entry.
*
* @param addr Address on a page whose TLB entry is to be invalidated.
*
*/
static inline void invlpg(uintptr_t addr)
{
__asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr)));
asm volatile (
"invlpg %[addr]\n"
:: [addr] "m" (*((unative_t *) addr))
);
}
 
/** Load GDTR register from memory.
*
* @param gdtr_reg Address of memory from where to load GDTR.
*
*/
static inline void gdtr_load(struct ptr_16_64 *gdtr_reg)
static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
{
__asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg));
asm volatile (
"lgdtq %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Store GDTR register to memory.
*
* @param gdtr_reg Address of memory to where to load GDTR.
*
*/
static inline void gdtr_store(struct ptr_16_64 *gdtr_reg)
static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
{
__asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg));
asm volatile (
"sgdtq %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Load IDTR register from memory.
*
* @param idtr_reg Address of memory from where to load IDTR.
*
*/
static inline void idtr_load(struct ptr_16_64 *idtr_reg)
static inline void idtr_load(ptr_16_64_t *idtr_reg)
{
__asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg));
asm volatile (
"lidtq %[idtr_reg]\n"
:: [idtr_reg] "m" (*idtr_reg));
}
 
/** Load TR from descriptor table.
*
* @param sel Selector specifying descriptor of TSS segment.
*
*/
static inline void tr_load(uint16_t sel)
{
__asm__ volatile ("ltr %0" : : "r" (sel));
asm volatile (
"ltr %[sel]"
:: [sel] "r" (sel)
);
}
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
{ \
unative_t res; \
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \
return res; \
}
{ \
unative_t res; \
asm volatile ( \
"movq %%" #reg ", %[res]" \
: [res] "=r" (res) \
); \
return res; \
}
 
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
{ \
__asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \
}
{ \
asm volatile ( \
"movq %[regn], %%" #reg \
:: [regn] "r" (regn) \
); \
}
 
GEN_READ_REG(cr0)
GEN_READ_REG(cr2)
/branches/arm/kernel/arch/amd64/include/boot/boot.h
42,8 → 42,17
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
#ifndef __ASM__
 
#ifdef CONFIG_SMP
 
/* This is only a symbol so the type is dummy. Obtain the value using &. */
extern int _hardcoded_unmapped_size;
 
#endif /* CONFIG_SMP */
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/arm/kernel/arch/amd64/include/arch.h
35,6 → 35,10
#ifndef KERN_amd64_ARCH_H_
#define KERN_amd64_ARCH_H_
 
#include <genarch/multiboot/multiboot.h>
 
extern void arch_pre_main(uint32_t, const multiboot_info_t *);
 
#endif
 
/** @}
/branches/arm/kernel/arch/amd64/include/interrupt.h
71,7 → 71,6
/** This is passed to interrupt handlers */
typedef struct {
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
80,11 → 79,6
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rbp;
uint64_t error_word;
uint64_t rip;
uint64_t cs;
/branches/arm/kernel/arch/amd64/include/drivers/i8042.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers/i8254.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers/ega.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers/vesa.h
File deleted
/branches/arm/kernel/arch/amd64/include/drivers/i8259.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers
0,0 → 1,0
link ../../ia32/include/drivers
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/syscall.h
35,8 → 35,6
#ifndef KERN_amd64_SYSCALL_H_
#define KERN_amd64_SYSCALL_H_
 
#include <arch/types.h>
 
extern void syscall_setup_cpu(void);
 
#endif
/branches/arm/kernel/arch/amd64/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-x86-64
BFD_ARCH = i386:x86-64
BFD = binary
45,83 → 41,51
ICC_CFLAGS += $(CMN1)
SUNCC_CFLAGS += -m64 -xmodel=kernel
 
DEFS += -DMACHINE=$(MACHINE) -D__64_BITS__
BITS = 64
ENDIANESS = LE
 
## Accepted CPUs
#
 
ifeq ($(MACHINE),opteron)
ifeq ($(PROCESSOR),opteron)
CMN2 := -march=opteron
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xtarget=opteron
DEFS += -DFENCES=p4
endif
 
## Own configuration directives
#
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with i8042 support.
#
 
CONFIG_I8042 = y
DEFS += -DCONFIG_I8042
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
 
ifeq ($(CONFIG_SIMICS_FIX),y)
DEFS += -DCONFIG_SIMICS_FIX
endif
 
ARCH_SOURCES = \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/delay.S \
arch/$(ARCH)/src/amd64.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/asm_utils.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/task.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/debugger.c
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/boot/memmap.c \
arch/$(KARCH)/src/pm.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/vesa.c \
arch/$(KARCH)/src/drivers/i8254.c \
arch/$(KARCH)/src/drivers/i8259.c \
arch/$(KARCH)/src/delay.S \
arch/$(KARCH)/src/amd64.c \
arch/$(KARCH)/src/bios/bios.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/asm_utils.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/proc/task.c \
arch/$(KARCH)/src/proc/thread.c \
arch/$(KARCH)/src/userspace.c \
arch/$(KARCH)/src/syscall.c \
arch/$(KARCH)/src/debugger.c
 
ifeq ($(CONFIG_SMP),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/smp/ap.S \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c
arch/$(KARCH)/src/smp/ap.S \
arch/$(KARCH)/src/smp/apic.c \
arch/$(KARCH)/src/smp/ipi.c \
arch/$(KARCH)/src/smp/mps.c \
arch/$(KARCH)/src/smp/smp.c
endif
/branches/arm/kernel/arch/amd64/src/ddi/ddi.c
56,16 → 56,16
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
 
size_t bits;
bits = ioaddr + size;
if (bits > IO_PORTS)
return ENOENT;
 
if (task->arch.iomap.bits < bits) {
bitmap_t oldiomap;
uint8_t *newmap;
/*
* The I/O permission bitmap is too small and needs to be grown.
*/
77,17 → 77,17
bitmap_initialize(&oldiomap, task->arch.iomap.map,
task->arch.iomap.bits);
bitmap_initialize(&task->arch.iomap, newmap, bits);
 
/*
* Mark the new range inaccessible.
*/
bitmap_set_range(&task->arch.iomap, oldiomap.bits,
bits - oldiomap.bits);
 
/*
* In case there really existed smaller iomap,
* copy its contents and deallocate it.
*/
*/
if (oldiomap.bits) {
bitmap_copy(&task->arch.iomap, &oldiomap,
oldiomap.bits);
94,17 → 94,17
free(oldiomap.map);
}
}
 
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
 
bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
/*
* Increment I/O Permission bitmap generation counter.
*/
task->arch.iomapver++;
 
return 0;
}
 
117,12 → 117,12
*/
void io_perm_bitmap_install(void)
{
count_t bits;
size_t bits;
ptr_16_64_t cpugdtr;
descriptor_t *gdt_p;
tss_descriptor_t *tss_desc;
count_t ver;
 
size_t ver;
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
140,7 → 140,7
bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
}
spinlock_unlock(&TASK->lock);
 
/*
* Second, adjust TSS segment limit.
* Take the extra ending byte will all bits set into account.
151,10 → 151,10
gdtr_load(&cpugdtr);
/*
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
tss_desc->type = AR_TSS;
tr_load(gdtselector(TSS_DES));
/branches/arm/kernel/arch/amd64/src/interrupt.c
43,7 → 43,6
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <arch/asm.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
52,6 → 51,7
#include <arch/ddi/ddi.h>
#include <interrupt.h>
#include <ddi/irq.h>
#include <symtab.h>
 
/*
* Interrupt and exception dispatching.
64,10 → 64,8
void decode_istate(int n, istate_t *istate)
{
char *symbol;
/* uint64_t *x = &istate->stack[0]; */
 
if (!(symbol = get_symtab_entry(istate->rip)))
symbol = "";
symbol = symtab_fmt_name_lookup(istate->rip);
 
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n", n, __func__);
printf("%%rip: %#llx (%s)\n", istate->rip, symbol);
80,12 → 78,6
istate->rdi, istate->r8);
printf("%%r9=%#llx, %%r10=%#llx, %%r11=%#llx\n", istate->r9,
istate->r10, istate->r11);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%r12=%#llx, %%r13=%#llx, %%r14=%#llx\n", istate->r12,
istate->r13, istate->r14);
printf("%%r15=%#llx, %%rbx=%#llx, %%rbp=%#llx\n", istate->r15,
istate->rbx, &istate->rbp);
#endif
printf("%%rsp=%#llx\n", &istate->stack[0]);
}
 
94,15 → 86,15
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
panic("No eoi_function.");
 
}
 
static void null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n);
decode_istate(n, istate);
panic("unserviced interrupt\n");
panic("Unserviced interrupt.");
}
 
/** General Protection Fault. */
109,7 → 101,7
static void gp_fault(int n, istate_t *istate)
{
if (TASK) {
count_t ver;
size_t ver;
 
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
126,35 → 118,37
io_perm_bitmap_install();
return;
}
fault_if_from_uspace(istate, "general protection fault");
fault_if_from_uspace(istate, "General protection fault.");
}
 
decode_istate(n, istate);
panic("general protection fault\n");
panic("General protection fault.");
}
 
static void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
fault_if_from_uspace(istate, "Stack fault.");
decode_istate(n, istate);
panic("stack fault\n");
panic("Stack fault.");
}
 
static void nm_fault(int n, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "fpu fault");
panic("fpu fault");
fault_if_from_uspace(istate, "FPU fault.");
panic("FPU fault.");
#endif
}
 
#ifdef CONFIG_SMP
static void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
#endif
 
/** Handler of IRQ exceptions */
static void irq_interrupt(int n, istate_t *istate)
177,7 → 171,7
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
221,7 → 215,7
if (enable_irqs_function)
enable_irqs_function(irqmask);
else
panic("no enable_irqs_function\n");
panic("No enable_irqs_function.");
}
 
void trap_virtual_disable_irqs(uint16_t irqmask)
229,7 → 223,7
if (disable_irqs_function)
disable_irqs_function(irqmask);
else
panic("no disable_irqs_function\n");
panic("No disable_irqs_function.");
}
 
/** @}
/branches/arm/kernel/arch/amd64/src/amd64.c
39,11 → 39,15
#include <config.h>
 
#include <proc/thread.h>
#include <arch/drivers/ega.h>
#include <genarch/multiboot/multiboot.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <arch/drivers/vesa.h>
#include <genarch/kbd/i8042.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/drivers/i8254.h>
#include <arch/drivers/i8259.h>
#include <arch/boot/boot.h>
 
#ifdef CONFIG_SMP
#include <arch/smp/apic.h>
61,9 → 65,8
#include <syscall/syscall.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <sysinfo/sysinfo.h>
 
 
/** Disable I/O on non-privileged levels
*
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register
70,15 → 73,13
*/
static void clean_IOPL_NT_flags(void)
{
asm (
asm volatile (
"pushfq\n"
"pop %%rax\n"
"and $~(0x7000), %%rax\n"
"pushq %%rax\n"
"popfq\n"
:
:
: "%rax"
::: "%rax"
);
}
 
88,16 → 89,31
*/
static void clean_AM_flag(void)
{
asm (
asm volatile (
"mov %%cr0, %%rax\n"
"and $~(0x40000), %%rax\n"
"mov %%rax, %%cr0\n"
:
:
: "%rax"
::: "%rax"
);
}
 
/** Perform amd64-specific initialization before main_bsp() is called.
*
* @param signature Should contain the multiboot signature.
* @param mi Pointer to the multiboot information structure.
*/
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi)
{
/* Parse multiboot information obtained from the bootloader. */
multiboot_info_parse(signature, mi);
#ifdef CONFIG_SMP
/* Copy AP bootstrap routines below 1 MB. */
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
(size_t) &_hardcoded_unmapped_size);
#endif
}
 
void arch_pre_mm_init(void)
{
/* Enable no-execute pages */
133,13 → 149,17
/* hard clock */
i8254_init();
#ifdef CONFIG_FB
if (vesa_present())
vesa_init();
else
#endif
ega_init(); /* video */
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
#else
{}
#endif
/* Enable debugger */
debugger_init();
172,8 → 192,33
 
void arch_post_smp_init(void)
{
/* keyboard controller */
i8042_init(device_assign_devno(), IRQ_KBD, device_assign_devno(), IRQ_MOUSE);
#ifdef CONFIG_PC_KBD
/*
* Initialize the i8042 controller. Then initialize the keyboard
* module and connect it to i8042. Enable keyboard interrupts.
*/
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
if (i8042_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
i8042_wire(i8042_instance, kbrd);
trap_virtual_enable_irqs(1 << IRQ_KBD);
}
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) I8042_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
}
 
void calibrate_delay_loop(void)
208,15 → 253,45
*/
void arch_grab_console(void)
{
i8042_grab();
#ifdef CONFIG_FB
if (vesa_present())
vesa_redraw();
else
#endif
#ifdef CONFIG_EGA
ega_redraw();
#else
{}
#endif
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
i8042_release();
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
void arch_reboot(void)
{
#ifdef CONFIG_PC_KBD
i8042_cpu_reset((i8042_t *) I8042_BASE);
#endif
}
 
/** @}
*/
/branches/arm/kernel/arch/amd64/src/pm.c
137,8 → 137,8
 
void gdt_tss_setlimit(descriptor_t *d, uint32_t limit)
{
struct tss_descriptor *td = (tss_descriptor_t *) d;
 
tss_descriptor_t *td = (tss_descriptor_t *) d;
td->limit_0_15 = limit & 0xffff;
td->limit_16_19 = (limit >> 16) & 0xf;
}
185,14 → 185,14
*/
void pm_init(void)
{
descriptor_t *gdt_p = (struct descriptor *) gdtr.base;
descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
tss_descriptor_t *tss_desc;
 
/*
* Each CPU has its private GDT and TSS.
* All CPUs share one IDT.
*/
 
if (config.cpu_active == 1) {
idt_init();
/*
200,20 → 200,19
* the heap hasn't been initialized so far.
*/
tss_p = &tss;
}
else {
} else {
/* We are going to use malloc, which may return
* non boot-mapped pointer, initialize the CR3 register
* ahead of page_init */
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 
tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC);
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
if (!tss_p)
panic("could not allocate TSS\n");
panic("Cannot allocate TSS.");
}
 
tss_initialize(tss_p);
 
tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
tss_desc->present = 1;
tss_desc->type = AR_TSS;
221,7 → 220,7
gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
 
gdtr_load(&gdtr);
idtr_load(&idtr);
/*
231,24 → 230,5
tr_load(gdtselector(TSS_DES));
}
 
/* Reboot the machine by initiating
* a triple fault
*/
void arch_reboot(void)
{
preemption_disable();
ipl_t ipl = interrupts_disable();
memsetb(idt, sizeof(idt), 0);
idtr_load(&idtr);
interrupts_restore(ipl);
asm volatile (
"int $0x03\n"
"cli\n"
"hlt\n"
);
}
 
/** @}
*/
/branches/arm/kernel/arch/amd64/src/debugger.c
35,7 → 35,6
#include <arch/debugger.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <interrupt.h>
44,6 → 43,7
#include <debug.h>
#include <func.h>
#include <smp/ipi.h>
#include <symtab.h>
 
typedef struct {
uintptr_t address; /**< Breakpoint address */
54,6 → 54,8
static bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
 
#ifdef CONFIG_KCONSOLE
 
static int cmd_print_breakpoints(cmd_arg_t *argv);
static cmd_info_t bkpts_info = {
.name = "bkpts",
62,8 → 64,6
.argc = 0,
};
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
static int cmd_del_breakpoint(cmd_arg_t *argv);
static cmd_arg_t del_argv = {
.type = ARG_TYPE_INT
99,44 → 99,8
.argv = &addw_argv
};
 
#endif
#endif /* CONFIG_KCONSOLE */
 
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
{
unsigned int i;
char *symbol;
 
#ifdef __32_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ---------- ---------\n");
#endif
 
#ifdef __64_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ------------------ ---------\n");
#endif
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
 
#ifdef __32_BITS__
printf("%-2u %-5d %#10zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
#ifdef __64_BITS__
printf("%-2u %-5d %#18zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
}
return 1;
}
 
/* Setup DR register according to table */
static void setup_dr(int curidx)
{
237,16 → 201,16
 
/* Send IPI */
#ifdef CONFIG_SMP
// ipi_broadcast(VECTOR_DEBUG_IPI);
// ipi_broadcast(VECTOR_DEBUG_IPI);
#endif
 
return curidx;
}
 
#ifdef amd64
# define getip(x) ((x)->rip)
#ifdef __64_BITS__
#define getip(x) ((x)->rip)
#else
# define getip(x) ((x)->eip)
#define getip(x) ((x)->eip)
#endif
 
static void handle_exception(int slot, istate_t *istate)
265,12 → 229,15
*((unative_t *) breakpoints[slot].address));
}
}
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate),
get_symtab_entry(getip(istate)));
printf("***Type 'exit' to exit kconsole.\n");
atomic_set(&haltstate,1);
kconsole((void *) "debug");
atomic_set(&haltstate,0);
 
printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
symtab_fmt_name_lookup(getip(istate)));
 
#ifdef CONFIG_KCONSOLE
atomic_set(&haltstate, 1);
kconsole("debug", "Debug console ready.\n", false);
atomic_set(&haltstate, 0);
#endif
}
 
void breakpoint_del(int slot)
299,42 → 266,8
#endif
}
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
unative_t bpno = argv->intval;
if (bpno > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
breakpoint_del(argv->intval);
return 1;
}
 
/** Add new breakpoint to table */
static int cmd_add_breakpoint(cmd_arg_t *argv)
{
int flags;
int id;
 
if (argv == &add_argv) {
flags = BKPOINT_INSTR;
} else { /* addwatchp */
flags = BKPOINT_WRITE;
}
printf("Adding breakpoint on address: %p\n", argv->intval);
id = breakpoint_add((void *)argv->intval, flags, -1);
if (id < 0)
printf("Add breakpoint failed.\n");
else
printf("Added breakpoint %d.\n", id);
return 1;
}
#endif
 
static void debug_exception(int n __attribute__((unused)), istate_t *istate)
{
unative_t dr6;
341,7 → 274,7
int i;
/* Set RF to restart the instruction */
#ifdef amd64
#ifdef __64_BITS__
istate->rflags |= RFLAGS_RF;
#else
istate->eflags |= EFLAGS_RF;
379,24 → 312,24
 
for (i = 0; i < BKPOINTS_MAX; i++)
breakpoints[i].address = NULL;
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&bkpts_info);
if (!cmd_register(&bkpts_info))
panic("could not register command %s\n", bkpts_info.name);
printf("Cannot register command %s\n", bkpts_info.name);
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
panic("could not register command %s\n", delbkpt_info.name);
printf("Cannot register command %s\n", delbkpt_info.name);
 
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
printf("Cannot register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addwatchp_info);
if (!cmd_register(&addwatchp_info))
panic("could not register command %s\n", addwatchp_info.name);
#endif
printf("Cannot register command %s\n", addwatchp_info.name);
#endif /* CONFIG_KCONSOLE */
exc_register(VECTOR_DEBUG, "debugger", debug_exception);
#ifdef CONFIG_SMP
404,5 → 337,77
#endif
}
 
#ifdef CONFIG_KCONSOLE
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
{
unsigned int i;
char *symbol;
 
#ifdef __32_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ---------- ---------\n");
#endif
 
#ifdef __64_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ------------------ ---------\n");
#endif
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = symtab_fmt_name_lookup(
breakpoints[i].address);
 
#ifdef __32_BITS__
printf("%-2u %-5d %#10zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
#ifdef __64_BITS__
printf("%-2u %-5d %#18zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
}
return 1;
}
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
unative_t bpno = argv->intval;
if (bpno > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
breakpoint_del(argv->intval);
return 1;
}
 
/** Add new breakpoint to table */
static int cmd_add_breakpoint(cmd_arg_t *argv)
{
int flags;
int id;
 
if (argv == &add_argv) {
flags = BKPOINT_INSTR;
} else { /* addwatchp */
flags = BKPOINT_WRITE;
}
printf("Adding breakpoint on address: %p\n", argv->intval);
id = breakpoint_add((void *)argv->intval, flags, -1);
if (id < 0)
printf("Add breakpoint failed.\n");
else
printf("Added breakpoint %d.\n", id);
return 1;
}
#endif /* CONFIG_KCONSOLE */
 
/** @}
*/
/branches/arm/kernel/arch/amd64/src/boot/vesa_ret.inc
0,0 → 1,19
.code32
vesa_init_protected:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
#
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment.
#
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
/branches/arm/kernel/arch/amd64/src/boot/boot.S
1,4 → 1,4
 
#
# Copyright (c) 2005 Ondrej Palkovsky
# Copyright (c) 2006 Martin Decky
# Copyright (c) 2008 Jakub Jermar
37,7 → 37,7
#include <arch/cpuid.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
.section K_TEXT_START, "ax"
 
.code32
46,7 → 46,7
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long multiboot_header
.long unmapped_ktext_start
.long 0
55,15 → 55,19
 
multiboot_image_start:
cld
movl $START_STACK, %esp # initialize stack pointer
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register
 
movl $START_STACK, %esp # initialize stack pointer
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ds # kernel data + stack
movw %cx, %ss
#
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
# when _visible_ part of GS does not point to user-mode segment.
#
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
71,17 → 75,19
jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, grub_eax # save parameters from GRUB
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
#
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
# the Default operand size must not be 1 when entering long mode.
#
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
ja extended_cpuid_supported
movl $extended_cpuid_msg, %esi
jmp error_halt
90,11 → 96,11
movl $(AMD_CPUID_EXTENDED), %eax
cpuid
bt $(AMD_EXT_LONG_MODE), %edx
jc long_mode_supported
jc long_mode_supported
movl $long_mode_msg, %esi
jmp error_halt
 
long_mode_supported:
bt $(AMD_EXT_NOEXECUTE), %edx
108,7 → 114,7
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $(INTEL_FXSAVE), %edx
jc fx_supported
jc fx_supported
movl $fx_msg, %esi
jmp error_halt
116,59 → 122,43
fx_supported:
bt $(INTEL_SSE2), %edx
jc sse2_supported
jc sse2_supported
movl $sse2_msg, %esi
jmp error_halt
sse2_supported:
#ifdef CONFIG_FB
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
rep movsb
 
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
vesa_meeting_point:
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
#include "vesa_prot.inc"
 
#
# Enable 64-bit page translation entries - CR4.PAE = 1.
# Paging is not enabled until after long mode is enabled
# Paging is not enabled until after long mode is enabled.
#
movl %cr4, %eax
btsl $5, %eax
movl %eax, %cr4
 
# Set up paging tables
# set up paging tables
leal ptl_0, %eax
movl %eax, %cr3
# Enable long mode
# enable long mode
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # Read EFER
btsl $AMD_LME_FLAG, %eax # Set LME = 1
wrmsr # Write EFER
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # read EFER
btsl $AMD_LME_FLAG, %eax # set LME = 1
wrmsr # write EFER
# Enable paging to activate long mode (set CR0.PG = 1)
# enable paging to activate long mode (set CR0.PG = 1)
movl %cr0, %eax
btsl $31, %eax
movl %eax, %cr0
# At this point we are in compatibility mode
# at this point we are in compatibility mode
jmpl $gdtselector(KTEXT_DES), $start64
 
175,362 → 165,29
.code64
start64:
movq $(PA2KA(START_STACK)), %rsp
movl grub_eax, %eax
movl grub_ebx, %ebx
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
je valid_boot
xorl %ecx, %ecx # no memory size or map available
movl %ecx, e820counter
jmp invalid_boot
valid_boot:
movl (%ebx), %eax # ebx = physical address of struct multiboot_info
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid)
jc mods_valid
xorq %rcx, %rcx
movq %rcx, init
jmp mods_end
mods_valid:
xorq %rcx, %rcx
movl 20(%ebx), %ecx # mbi->mods_count
movq %rcx, init
cmpl $0, %ecx
je mods_end
movl 24(%ebx), %esi # mbi->mods_addr
movq $init, %rdi
mods_loop:
xorq %rdx, %rdx
movl 0(%esi), %edx # mods->mod_start
movq $0xffff800000000000, %r10
addq %r10, %rdx
movq %rdx, 8(%rdi)
xorq %rdx, %rdx
movl 4(%esi), %edx
subl 0(%esi), %edx # mods->mod_end - mods->mod_start
movq %rdx, 16(%rdi)
addl $16, %esi
addq $16, %rdi
loop mods_loop
mods_end:
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid)
jc mmap_valid
xorl %edx, %edx
jmp mmap_invalid
mmap_valid:
movl 44(%ebx), %ecx # mbi->mmap_length
movl 48(%ebx), %esi # mbi->mmap_addr
movq $e820table, %rdi
xorl %edx, %edx
mmap_loop:
cmpl $0, %ecx
jle mmap_end
movl 4(%esi), %eax # mmap->base_addr_low
movl %eax, (%rdi)
movl 8(%esi), %eax # mmap->base_addr_high
movl %eax, 4(%rdi)
movl 12(%esi), %eax # mmap->length_low
movl %eax, 8(%rdi)
movl 16(%esi), %eax # mmap->length_high
movl %eax, 12(%rdi)
movl 20(%esi), %eax # mmap->type
movl %eax, 16(%rdi)
movl (%esi), %eax # mmap->size
addl $0x4, %eax
addl %eax, %esi
subl %eax, %ecx
addq $MEMMAP_E820_RECORD_SIZE, %rdi
incl %edx
jmp mmap_loop
mmap_end:
mmap_invalid:
movl %edx, e820counter
invalid_boot:
# call arch_pre_main(grub_eax, grub_ebx)
xorq %rdi, %rdi
movl grub_eax, %edi
xorq %rsi, %rsi
movl grub_ebx, %esi
call arch_pre_main
#ifdef CONFIG_SMP
call main_bsp
# copy AP bootstrap routines below 1 MB
# not reached
movq $BOOT_OFFSET, %rsi
movq $AP_BOOT_OFFSET, %rdi
movq $_hardcoded_unmapped_size, %rcx
rep movsb
#endif
call main_bsp # never returns
cli
hlt
hlt0:
hlt
jmp hlt0
 
#ifdef CONFIG_FB
.code32
vesa_init:
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP == 24
#define CONFIG_VESA_BPP_VARIANT 32
#endif
 
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
 
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz 0f
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz 0f
mov $CONFIG_VESA_WIDTH, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
 
#ifdef CONFIG_VESA_BPP_VARIANT
jz 2f
mov $CONFIG_VESA_BPP_VARIANT, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
#endif
jnz 1b
2:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
 
#if CONFIG_VESA_BPP == 8
# Set 3:2:3 VGA palette
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # Test if VGA compatible registers are present
jnc vga_compat
# Try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
jmp vga_not_compat
vga_compat:
# Try VGA registers to set palette
movw $0x3c6, %dx # Set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # First index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # Data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
#endif
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
8:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp 9f
9:
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
0:# No prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz 1f
jz 2b # Force relative jump
 
1:
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
vga323:
#include "vga323.pal"
.code32
vesa_init_protect:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
.align 4
e_vesa_init:
#endif
 
# Print string from %esi to EGA display (in red) and halt
error_halt:
movl $0xb8000, %edi # base of EGA text mode memory
movl $0xb8000, %edi # base of EGA text mode memory
xorl %eax, %eax
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
538,7 → 195,7
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
547,7 → 204,9
cmp $1920, %ax
jbe cursor_ok
movw $1920, %ax # sanity check for the cursor on the last line
movw $1920, %ax # sanity check for the cursor on the last line
cursor_ok:
movw %ax, %bx
554,7 → 213,7
shl $1, %eax
addl %eax, %edi
movw $0x0c00, %ax # black background, light red foreground
movw $0x0c00, %ax # black background, light red foreground
ploop:
lodsb
561,11 → 220,11
cmp $0, %al
je ploop_end
stosw
inc %bx
inc %bx
jmp ploop
ploop_end:
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
573,7 → 232,7
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
580,17 → 239,20
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
hlt1:
hlt
jmp hlt1
 
#include "vesa_real.inc"
 
.section K_INI_PTLS, "aw", @progbits
 
#
# Macro for generating initial page table contents.
# @param cnt Number of entries to generat. Must be multiple of 8.
# @param g Number of GB that will be added to the mapping.
# @param cnt Number of entries to generat. Must be multiple of 8.
# @param g Number of GB that will be added to the mapping.
#
.macro ptl2gen cnt g
.if \cnt
642,7 → 304,7
# Mapping of [0; 1G) at -2G
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
.fill 1, 8, 0
 
.align 4096
.global ptl_0
ptl_0:
/branches/arm/kernel/arch/amd64/src/boot/vesa_real.inc
0,0 → 1,0
link ../../../ia32/src/boot/vesa_real.inc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/src/boot/vesa_prot.inc
0,0 → 1,0
link ../../../ia32/src/boot/vesa_prot.inc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/src/boot/memmap.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64mm
/** @addtogroup amd64mm
* @{
*/
/** @file
/branches/arm/kernel/arch/amd64/src/fpu_context.c
39,9 → 39,9
void fpu_context_save(fpu_context_t *fctx)
{
asm volatile (
"fxsave %0"
: "=m"(*fctx)
);
"fxsave %[fctx]\n"
: [fctx] "=m" (*fctx)
);
}
 
/** Restore FPU (mmx,sse) context using fxrstor instruction */
48,9 → 48,9
void fpu_context_restore(fpu_context_t *fctx)
{
asm volatile (
"fxrstor %0"
: "=m"(*fctx)
);
"fxrstor %[fctx]\n"
: [fctx] "=m" (*fctx)
);
}
 
void fpu_init()
57,7 → 57,7
{
/* TODO: Zero all SSE, MMX etc. registers */
asm volatile (
"fninit;"
"fninit\n"
);
}
 
/branches/arm/kernel/arch/amd64/src/cpu/cpu.c
77,21 → 77,19
void cpu_setup_fpu(void)
{
asm volatile (
"movq %%cr0, %%rax;"
"btsq $1, %%rax;" /* cr0.mp */
"btrq $2, %%rax;" /* cr0.em */
"movq %%rax, %%cr0;"
 
"movq %%cr4, %%rax;"
"bts $9, %%rax;" /* cr4.osfxsr */
"movq %%rax, %%cr4;"
:
:
:"%rax"
);
"movq %%cr0, %%rax\n"
"btsq $1, %%rax\n" /* cr0.mp */
"btrq $2, %%rax\n" /* cr0.em */
"movq %%rax, %%cr0\n"
"movq %%cr4, %%rax\n"
"bts $9, %%rax\n" /* cr4.osfxsr */
"movq %%rax, %%cr4\n"
::: "%rax"
);
}
 
/** Set the TS flag to 1.
/** Set the TS flag to 1.
*
* If a thread accesses coprocessor, exception is run, which
* does a lazy fpu context switch.
99,26 → 97,22
*/
void fpu_disable(void)
{
asm volatile (
"mov %%cr0,%%rax;"
"bts $3,%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
asm volatile (
"mov %%cr0, %%rax\n"
"bts $3, %%rax\n"
"mov %%rax, %%cr0\n"
::: "%rax"
);
}
 
void fpu_enable(void)
{
asm volatile (
"mov %%cr0,%%rax;"
"btr $3,%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
asm volatile (
"mov %%cr0, %%rax\n"
"btr $3, %%rax\n"
"mov %%rax, %%cr0\n"
::: "%rax"
);
}
 
void cpu_arch_init(void)
/branches/arm/kernel/arch/amd64/src/userspace.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
47,36 → 47,33
*/
void userspace(uspace_arg_t *kernel_uarg)
{
ipl_t ipl;
ipl_t ipl = interrupts_disable();
ipl = interrupts_disable();
 
/* Clear CF,PF,AF,ZF,SF,DF,OF */
/* Clear CF, PF, AF, ZF, SF, DF, OF */
ipl &= ~(0xcd4);
 
asm volatile (""
"pushq %0\n"
"pushq %1\n"
"pushq %2\n"
"pushq %3\n"
"pushq %4\n"
"movq %5, %%rax\n"
/* %rdi is defined to hold pcb_ptr - set it to 0 */
"xorq %%rdi, %%rdi\n"
"iretq\n"
: :
"i" (gdtselector(UDATA_DES) | PL_USER),
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
"r" (ipl),
"i" (gdtselector(UTEXT_DES) | PL_USER),
"r" (kernel_uarg->uspace_entry),
"r" (kernel_uarg->uspace_uarg)
: "rax"
);
asm volatile (
"pushq %[udata_des]\n"
"pushq %[stack_size]\n"
"pushq %[ipl]\n"
"pushq %[utext_des]\n"
"pushq %[entry]\n"
"movq %[uarg], %%rax\n"
/* %rdi is defined to hold pcb_ptr - set it to 0 */
"xorq %%rdi, %%rdi\n"
"iretq\n"
:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
[stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
[ipl] "r" (ipl),
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
[entry] "r" (kernel_uarg->uspace_entry),
[uarg] "r" (kernel_uarg->uspace_uarg)
: "rax"
);
/* Unreachable */
for(;;)
;
while (1);
}
 
/** @}
/branches/arm/kernel/arch/amd64/src/mm/page.c
180,7 → 180,7
page = read_cr2();
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page table entry.\n");
panic("Reserved bit set in page table entry.");
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
190,11 → 190,11
access = PF_ACCESS_READ;
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
fault_if_from_uspace(istate, "Page fault: %#x.", page);
 
decode_istate(n, istate);
printf("Page fault address: %llx\n", page);
panic("page fault\n");
printf("Page fault address: %llx.\n", page);
panic("Page fault.");
}
}
 
202,7 → 202,7
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
panic("Unable to map physical memory %p (%d bytes).", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
/branches/arm/kernel/arch/amd64/src/proc/scheduler.c
39,7 → 39,6
#include <arch.h>
#include <arch/context.h> /* SP_DELTA */
#include <arch/asm.h>
#include <arch/debugger.h>
#include <print.h>
#include <arch/pm.h>
#include <arch/ddi/ddi.h>
68,13 → 67,6
 
/* TLS support - set FS to thread local storage */
write_msr(AMD_MSR_FS, THREAD->arch.tls);
 
#ifdef CONFIG_DEBUG_AS_WATCHPOINT
/* Set watchpoint on AS to ensure that nobody sets it to zero */
if (CPU->id < BKPOINTS_MAX)
breakpoint_add(&((the_t *) THREAD->kstack)->as,
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, CPU->id);
#endif
}
 
void after_thread_ran_arch(void)
/branches/arm/kernel/arch/amd64/src/asm_utils.S
26,23 → 26,17
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#define IREGISTER_SPACE 120
#define IREGISTER_SPACE 72
 
#define IOFFSET_RAX 0x0
#define IOFFSET_RBX 0x8
#define IOFFSET_RCX 0x10
#define IOFFSET_RDX 0x18
#define IOFFSET_RSI 0x20
#define IOFFSET_RDI 0x28
#define IOFFSET_R8 0x30
#define IOFFSET_R9 0x38
#define IOFFSET_R10 0x40
#define IOFFSET_R11 0x48
#define IOFFSET_R12 0x50
#define IOFFSET_R13 0x58
#define IOFFSET_R14 0x60
#define IOFFSET_R15 0x68
#define IOFFSET_RBP 0x70
#define IOFFSET_RAX 0x0
#define IOFFSET_RCX 0x8
#define IOFFSET_RDX 0x10
#define IOFFSET_RSI 0x18
#define IOFFSET_RDI 0x20
#define IOFFSET_R8 0x28
#define IOFFSET_R9 0x30
#define IOFFSET_R10 0x38
#define IOFFSET_R11 0x40
 
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
# and 1 means interrupt with error word
173,7 → 167,7
rdmsr
ret
 
# Push all general purpose registers on stack except %rbp, %rsp
# Push all volatile general purpose registers on stack
.macro save_all_gpr
movq %rax, IOFFSET_RAX(%rsp)
movq %rcx, IOFFSET_RCX(%rsp)
184,14 → 178,6
movq %r9, IOFFSET_R9(%rsp)
movq %r10, IOFFSET_R10(%rsp)
movq %r11, IOFFSET_R11(%rsp)
#ifdef CONFIG_DEBUG_ALLREGS
movq %rbx, IOFFSET_RBX(%rsp)
movq %rbp, IOFFSET_RBP(%rsp)
movq %r12, IOFFSET_R12(%rsp)
movq %r13, IOFFSET_R13(%rsp)
movq %r14, IOFFSET_R14(%rsp)
movq %r15, IOFFSET_R15(%rsp)
#endif
.endm
 
.macro restore_all_gpr
204,21 → 190,9
movq IOFFSET_R9(%rsp), %r9
movq IOFFSET_R10(%rsp), %r10
movq IOFFSET_R11(%rsp), %r11
#ifdef CONFIG_DEBUG_ALLREGS
movq IOFFSET_RBX(%rsp), %rbx
movq IOFFSET_RBP(%rsp), %rbp
movq IOFFSET_R12(%rsp), %r12
movq IOFFSET_R13(%rsp), %r13
movq IOFFSET_R14(%rsp), %r14
movq IOFFSET_R15(%rsp), %r15
#endif
.endm
 
#ifdef CONFIG_DEBUG_ALLREGS
# define INTERRUPT_ALIGN 256
#else
# define INTERRUPT_ALIGN 128
#endif
#define INTERRUPT_ALIGN 128
## Declare interrupt handlers
#
/branches/arm/kernel/arch/amd64/_link.ld.in
43,8 → 43,6
QUAD(unmapped_kdata_end - unmapped_kdata_start);
*(COMMON); /* global variables */
 
*(.eh_frame);
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
52,6 → 50,10
 
kdata_end = .;
}
 
/DISCARD/ : {
*(*);
}
#ifdef CONFIG_SMP
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
/branches/arm/kernel/arch/ia32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ia32/include/types.h
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
57,10 → 55,11
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
#define PRIc "u" /**< Format for count_t. */
#define PRIi "u" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/ia32/include/smp/smp.h
39,10 → 39,10
 
/** SMP config opertaions interface. */
struct smp_config_operations {
count_t (* cpu_count)(void); /**< Return number of detected processors. */
bool (* cpu_enabled)(index_t i); /**< Check whether the processor of index i is enabled. */
bool (*cpu_bootstrap)(index_t i); /**< Check whether the processor of index i is BSP. */
uint8_t (*cpu_apic_id)(index_t i); /**< Return APIC ID of the processor of index i. */
size_t (* cpu_count)(void); /**< Return number of detected processors. */
bool (* cpu_enabled)(size_t i); /**< Check whether the processor of index i is enabled. */
bool (*cpu_bootstrap)(size_t i); /**< Check whether the processor of index i is BSP. */
uint8_t (*cpu_apic_id)(size_t i); /**< Return APIC ID of the processor of index i. */
int (*irq_to_pin)(unsigned int irq); /**< Return mapping between irq and APIC pin. */
};
 
/branches/arm/kernel/arch/ia32/include/proc/task.h
40,7 → 40,7
 
typedef struct {
/** I/O Permission bitmap Generation counter. */
count_t iomapver;
size_t iomapver;
/** I/O Permission bitmap. */
bitmap_t iomap;
} task_arch_t;
/branches/arm/kernel/arch/ia32/include/mm/page.h
95,21 → 95,21
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last level entries. */
#define PTE_VALID_ARCH(p) \
145,7 → 145,7
/** When bit on this position is 1, a reserved bit was set in page directory. */
#define PFERR_CODE_RSVD (1 << 3)
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
158,7 → 158,7
p->global << PAGE_GLOBAL_SHIFT);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
/branches/arm/kernel/arch/ia32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32mm
/** @addtogroup ia32mm
* @{
*/
/** @file
35,8 → 35,8
#ifndef KERN_ia32_FRAME_H_
#define KERN_ia32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
/branches/arm/kernel/arch/ia32/include/mm/tlb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32mm
/** @addtogroup ia32mm
* @{
*/
/** @file
35,9 → 35,6
#ifndef KERN_ia32_TLB_H_
#define KERN_ia32_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/mm/as.h
42,7 → 42,7
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000)
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff)
 
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
 
typedef struct {
} as_arch_t;
/branches/arm/kernel/arch/ia32/include/cpu.h
35,25 → 35,33
#ifndef KERN_ia32_CPU_H_
#define KERN_ia32_CPU_H_
 
#define EFLAGS_IF (1 << 9)
#define EFLAGS_RF (1 << 16)
 
#define CR4_OSFXSR_MASK (1<<9)
 
/* Support for SYSENTER and SYSEXIT */
#define IA32_MSR_SYSENTER_CS 0x174
#define IA32_MSR_SYSENTER_ESP 0x175
#define IA32_MSR_SYSENTER_EIP 0x176
 
#ifndef __ASM__
 
#include <arch/pm.h>
#include <arch/asm.h>
 
#define EFLAGS_IF (1 << 9)
#define EFLAGS_RF (1 << 16)
 
typedef struct {
int vendor;
int family;
int model;
int stepping;
struct tss *tss;
unsigned int vendor;
unsigned int family;
unsigned int model;
unsigned int stepping;
tss_t *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
size_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
 
#endif
 
#define CR4_OSFXSR_MASK (1<<9)
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/atomic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
41,17 → 41,29
 
static inline void atomic_inc(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock incl %0\n" : "+m" (val->count));
asm volatile (
"lock incl %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("incl %0\n" : "+m" (val->count));
asm volatile (
"incl %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
static inline void atomic_dec(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock decl %0\n" : "+m" (val->count));
asm volatile (
"lock decl %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("decl %0\n" : "+m" (val->count));
asm volatile (
"decl %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
58,12 → 70,12
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
 
asm volatile (
"lock xaddl %1, %0\n"
: "+m" (val->count), "+r" (r)
"lock xaddl %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r" (r)
);
 
return r;
}
 
72,23 → 84,23
long r = -1;
asm volatile (
"lock xaddl %1, %0\n"
: "+m" (val->count), "+r"(r)
"lock xaddl %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r"(r)
);
return r;
}
 
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
 
static inline uint32_t test_and_set(atomic_t *val) {
uint32_t v;
asm volatile (
"movl $1, %0\n"
"xchgl %0, %1\n"
: "=r" (v),"+m" (val->count)
"movl $1, %[v]\n"
"xchgl %[v], %[count]\n"
: [v] "=r" (v), [count] "+m" (val->count)
);
return v;
98,22 → 110,20
static inline void atomic_lock_arch(atomic_t *val)
{
uint32_t tmp;
 
preemption_disable();
asm volatile (
"0:\n"
#ifdef CONFIG_HT
"pause\n" /* Pentium 4's HT love this instruction */
#endif
"mov %0, %1\n"
"testl %1, %1\n"
"pause\n" /* Pentium 4's HT love this instruction */
"mov %[count], %[tmp]\n"
"testl %[tmp], %[tmp]\n"
"jnz 0b\n" /* lightweight looping on locked spinlock */
"incl %1\n" /* now use the atomic operation */
"xchgl %0, %1\n"
"testl %1, %1\n"
"incl %[tmp]\n" /* now use the atomic operation */
"xchgl %[count], %[tmp]\n"
"testl %[tmp], %[tmp]\n"
"jnz 0b\n"
: "+m" (val->count), "=&r"(tmp)
: [count] "+m" (val->count), [tmp] "=&r" (tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
/branches/arm/kernel/arch/ia32/include/cpuid.h
35,6 → 35,13
#ifndef KERN_ia32_CPUID_H_
#define KERN_ia32_CPUID_H_
 
#define INTEL_CPUID_LEVEL 0x00000000
#define INTEL_CPUID_STANDARD 0x00000001
#define INTEL_PSE 3
#define INTEL_SEP 11
 
#ifndef __ASM__
 
#include <arch/types.h>
 
typedef struct {
74,21 → 81,21
uint32_t val, ret;
asm volatile (
"pushf\n" /* read flags */
"popl %0\n"
"movl %0, %1\n"
"pushf\n" /* read flags */
"popl %[ret]\n"
"movl %[ret], %[val]\n"
"btcl $21, %1\n" /* swap the ID bit */
"btcl $21, %[val]\n" /* swap the ID bit */
"pushl %1\n" /* propagate the change into flags */
"pushl %[val]\n" /* propagate the change into flags */
"popf\n"
"pushf\n"
"popl %1\n"
"popl %[val]\n"
"andl $(1 << 21), %0\n" /* interrested only in ID bit */
"andl $(1 << 21), %1\n"
"xorl %1, %0\n"
: "=r" (ret), "=r" (val)
"andl $(1 << 21), %[ret]\n" /* interrested only in ID bit */
"andl $(1 << 21), %[val]\n"
"xorl %[val], %[ret]\n"
: [ret] "=r" (ret), [val] "=r" (val)
);
return ret;
98,11 → 105,13
{
asm volatile (
"cpuid\n"
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), "=c" (info->cpuid_ecx), "=d" (info->cpuid_edx)
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx),
"=c" (info->cpuid_ecx), "=d" (info->cpuid_edx)
: "a" (cmd)
);
}
 
#endif /* !def __ASM__ */
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/pm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,61 → 35,59
#ifndef KERN_ia32_PM_H_
#define KERN_ia32_PM_H_
 
#define IDT_ITEMS 64
#define GDT_ITEMS 7
#define IDT_ITEMS 64
#define GDT_ITEMS 7
 
#define VESA_INIT_SEGMENT 0x8000
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#ifdef CONFIG_FB
 
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#define KTEXT32_DES KTEXT_DES
 
#undef GDT_ITEMS
#define GDT_ITEMS 8
#define GDT_ITEMS 8
 
#endif /* CONFIG_FB */
 
#define gdtselector(des) ((des) << 3)
 
#define selector(des) ((des) << 3)
#define PL_KERNEL 0
#define PL_USER 3
 
#define PL_KERNEL 0
#define PL_USER 3
#define AR_PRESENT (1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_INTERRUPT (0x0e)
#define AR_TSS (0x09)
 
#define AR_PRESENT (1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_INTERRUPT (0xe)
#define AR_TSS (0x9)
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
 
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
#define IO_PORTS (64 * 1024)
 
#define IO_PORTS (64 * 1024)
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/context.h>
 
struct ptr_16_32 {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
} __attribute__ ((packed)) ptr_16_32_t;
 
struct descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
100,19 → 98,17
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
} __attribute__ ((packed)) descriptor_t;
 
struct idescriptor {
typedef struct {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned unused: 8;
unsigned access: 8;
unsigned offset_16_31: 16;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
} __attribute__ ((packed)) idescriptor_t;
 
struct tss {
typedef struct {
uint16_t link;
unsigned : 16;
uint32_t esp0;
152,13 → 148,12
unsigned : 16;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
} __attribute__ ((packed)) tss_t;
 
extern ptr_16_32_t gdtr;
extern ptr_16_32_t bootstrap_gdtr;
extern ptr_16_32_t protected_ap_gdtr;
extern struct tss *tss_p;
extern tss_t *tss_p;
 
extern descriptor_t gdt[];
 
/branches/arm/kernel/arch/ia32/include/drivers/i8042.h
File deleted
/branches/arm/kernel/arch/ia32/include/drivers/ega.h
File deleted
/branches/arm/kernel/arch/ia32/include/drivers/i8254.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
/branches/arm/kernel/arch/ia32/include/drivers/vesa.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
36,6 → 36,7
#define KERN_ia32_VESA_H_
 
extern int vesa_present(void);
extern void vesa_redraw(void);
extern void vesa_init(void);
 
#endif
/branches/arm/kernel/arch/ia32/include/drivers/i8259.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
38,13 → 38,13
#include <arch/types.h>
#include <arch/interrupt.h>
 
#define PIC_PIC0PORT1 0x20
#define PIC_PIC0PORT2 0x21
#define PIC_PIC1PORT1 0xa0
#define PIC_PIC1PORT2 0xa1
#define PIC_PIC0PORT1 ((ioport8_t *) 0x20)
#define PIC_PIC0PORT2 ((ioport8_t *) 0x21)
#define PIC_PIC1PORT1 ((ioport8_t *) 0xa0)
#define PIC_PIC1PORT2 ((ioport8_t *) 0xa1)
 
#define PIC_NEEDICW4 (1<<0)
#define PIC_ICW1 (1<<4)
#define PIC_NEEDICW4 (1 << 0)
#define PIC_ICW1 (1 << 4)
 
extern void i8259_init(void);
extern void pic_enable_irqs(uint16_t irqmask);
/branches/arm/kernel/arch/ia32/include/asm.h
27,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
38,6 → 38,7
 
#include <arch/pm.h>
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
extern uint32_t interrupt_handler_size;
55,11 → 56,16
 
/** Halt CPU
*
* Halt the current CPU until interrupt event.
* Halt the current CPU.
*
*/
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
asm volatile (
"0:\n"
" hlt\n"
" jmp 0b\n"
);
}
 
static inline void cpu_sleep(void)
68,16 → 74,22
}
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
{ \
unative_t res; \
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
return res; \
}
{ \
unative_t res; \
asm volatile ( \
"movl %%" #reg ", %[res]" \
: [res] "=r" (res) \
); \
return res; \
}
 
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
{ \
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \
}
{ \
asm volatile ( \
"movl %[regn], %%" #reg \
:: [regn] "r" (regn) \
); \
}
 
GEN_READ_REG(cr0)
GEN_READ_REG(cr2)
104,10 → 116,14
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outb(uint16_t port, uint8_t val)
static inline void pio_write_8(ioport8_t *port, uint8_t val)
{
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) );
asm volatile (
"outb %b[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Word to port
116,10 → 132,14
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outw(uint16_t port, uint16_t val)
static inline void pio_write_16(ioport16_t *port, uint16_t val)
{
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) );
asm volatile (
"outw %w[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Double word to port
128,10 → 148,14
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outl(uint16_t port, uint32_t val)
static inline void pio_write_32(ioport32_t *port, uint32_t val)
{
asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) );
asm volatile (
"outl %[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Byte from port
140,12 → 164,18
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint8_t inb(uint16_t port)
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t val;
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) );
asm volatile (
"inb %w[port], %b[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
155,12 → 185,18
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint16_t inw(uint16_t port)
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t val;
asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) );
asm volatile (
"inw %w[port], %w[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
170,12 → 206,18
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint32_t inl(uint16_t port)
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t val;
asm volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) );
asm volatile (
"inl %w[port], %[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
185,16 → 227,19
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_enable(void)
{
ipl_t v;
asm volatile (
"pushf\n\t"
"popl %0\n\t"
"pushf\n"
"popl %[v]\n"
"sti\n"
: "=r" (v)
: [v] "=r" (v)
);
return v;
}
 
204,16 → 249,19
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_disable(void)
{
ipl_t v;
asm volatile (
"pushf\n\t"
"popl %0\n\t"
"pushf\n"
"popl %[v]\n"
"cli\n"
: "=r" (v)
: [v] "=r" (v)
);
return v;
}
 
222,13 → 270,14
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*
*/
static inline void interrupts_restore(ipl_t ipl)
{
asm volatile (
"pushl %0\n\t"
"pushl %[ipl]\n"
"popf\n"
: : "r" (ipl)
:: [ipl] "r" (ipl)
);
}
 
235,23 → 284,51
/** Return interrupt priority level.
*
* @return EFLAFS.
*
*/
static inline ipl_t interrupts_read(void)
{
ipl_t v;
asm volatile (
"pushf\n\t"
"popl %0\n"
: "=r" (v)
"pushf\n"
"popl %[v]\n"
: [v] "=r" (v)
);
return v;
}
 
/** Write to MSR */
static inline void write_msr(uint32_t msr, uint64_t value)
{
asm volatile (
"wrmsr"
:: "c" (msr), "a" ((uint32_t) (value)),
"d" ((uint32_t) (value >> 32))
);
}
 
static inline uint64_t read_msr(uint32_t msr)
{
uint32_t ax, dx;
asm volatile (
"rdmsr"
: "=a" (ax), "=d" (dx)
: "c" (msr)
);
return ((uint64_t) dx << 32) | ax;
}
 
 
/** Return base address of current stack
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*
*/
static inline uintptr_t get_stack_base(void)
{
258,8 → 335,8
uintptr_t v;
asm volatile (
"andl %%esp, %0\n"
: "=r" (v)
"andl %%esp, %[v]\n"
: [v] "=r" (v)
: "0" (~(STACK_SIZE - 1))
);
270,11 → 347,12
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
asm volatile (
"mov %%eip, %0"
: "=r" (ip)
);
"mov %%eip, %[ip]"
: [ip] "=r" (ip)
);
return ip;
}
 
281,46 → 359,66
/** Invalidate TLB Entry.
*
* @param addr Address on a page whose TLB entry is to be invalidated.
*
*/
static inline void invlpg(uintptr_t addr)
{
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
asm volatile (
"invlpg %[addr]\n"
:: [addr] "m" (*(unative_t *) addr)
);
}
 
/** Load GDTR register from memory.
*
* @param gdtr_reg Address of memory from where to load GDTR.
*
*/
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
{
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
asm volatile (
"lgdtl %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Store GDTR register to memory.
*
* @param gdtr_reg Address of memory to where to load GDTR.
*
*/
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
{
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
asm volatile (
"sgdtl %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Load IDTR register from memory.
*
* @param idtr_reg Address of memory from where to load IDTR.
*
*/
static inline void idtr_load(ptr_16_32_t *idtr_reg)
{
asm volatile ("lidtl %0\n" : : "m" (*idtr_reg));
asm volatile (
"lidtl %[idtr_reg]\n"
:: [idtr_reg] "m" (*idtr_reg)
);
}
 
/** Load TR from descriptor table.
*
* @param sel Selector specifying descriptor of TSS segment.
*
*/
static inline void tr_load(uint16_t sel)
{
asm volatile ("ltr %0" : : "r" (sel));
asm volatile (
"ltr %[sel]"
:: [sel] "r" (sel)
);
}
 
#endif
/branches/arm/kernel/arch/ia32/include/boot/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,15 → 35,24
#ifndef KERN_ia32_BOOT_H_
#define KERN_ia32_BOOT_H_
 
#define BOOT_OFFSET 0x108000
#define AP_BOOT_OFFSET 0x8000
#define BOOT_STACK_SIZE 0x400
#define BOOT_OFFSET 0x108000
#define AP_BOOT_OFFSET 0x8000
#define BOOT_STACK_SIZE 0x400
 
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
#ifndef __ASM__
 
#ifdef CONFIG_SMP
 
/* This is only a symbol so the type is dummy. Obtain the value using &. */
extern int _hardcoded_unmapped_size;
 
#endif /* CONFIG_SMP */
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/boot/memmap.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,24 → 35,29
#ifndef KERN_ia32_MEMMAP_H_
#define KERN_ia32_MEMMAP_H_
 
/* E820h memory range types - other values*/
/* Free memory */
#define MEMMAP_MEMORY_AVAILABLE 1
/* Not available for OS */
#define MEMMAP_MEMORY_RESERVED 2
/* OS may use it after reading ACPI table */
#define MEMMAP_MEMORY_ACPI 3
/* Unusable, required to be saved and restored across an NVS sleep */
#define MEMMAP_MEMORY_NVS 4
/* Corrupted memory */
#define MEMMAP_MEMORY_UNUSABLE 5
/* E820h memory range types */
 
/* size of one entry */
#define MEMMAP_E820_RECORD_SIZE 20
/* maximum entries */
#define MEMMAP_E820_MAX_RECORDS 32
/* Free memory */
#define MEMMAP_MEMORY_AVAILABLE 1
 
/* Not available for OS */
#define MEMMAP_MEMORY_RESERVED 2
 
/* OS may use it after reading ACPI table */
#define MEMMAP_MEMORY_ACPI 3
 
/* Unusable, required to be saved and restored across an NVS sleep */
#define MEMMAP_MEMORY_NVS 4
 
/* Corrupted memory */
#define MEMMAP_MEMORY_UNUSABLE 5
 
/* Size of one entry */
#define MEMMAP_E820_RECORD_SIZE 20
 
/* Maximum entries */
#define MEMMAP_E820_MAX_RECORDS 32
 
#ifndef __ASM__
 
#include <arch/types.h>
/branches/arm/kernel/arch/ia32/include/arch.h
1,5 → 1,5
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,6 → 35,10
#ifndef KERN_ia32_ARCH_H_
#define KERN_ia32_ARCH_H_
 
#include <genarch/multiboot/multiboot.h>
 
extern void arch_pre_main(uint32_t, const multiboot_info_t *);
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/barrier.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
46,8 → 46,8
* Provisions are made to prevent compiler from reordering instructions itself.
*/
 
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
 
static inline void cpuid_serialization(void)
{
58,30 → 58,30
);
}
 
#ifdef CONFIG_FENCES_P4
# define memory_barrier() asm volatile ("mfence\n" ::: "memory")
# define read_barrier() asm volatile ("lfence\n" ::: "memory")
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() asm volatile ("sfence\n" ::: "memory")
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#elif CONFIG_FENCES_P3
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() asm volatile ("sfence\n" ::: "memory")
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#if defined(CONFIG_FENCES_P4)
#define memory_barrier() asm volatile ("mfence\n" ::: "memory")
#define read_barrier() asm volatile ("lfence\n" ::: "memory")
#ifdef CONFIG_WEAK_MEMORY
#define write_barrier() asm volatile ("sfence\n" ::: "memory")
#else
#define write_barrier() asm volatile ("" ::: "memory");
#endif
#elif defined(CONFIG_FENCES_P3)
#define memory_barrier() cpuid_serialization()
#define read_barrier() cpuid_serialization()
#ifdef CONFIG_WEAK_MEMORY
#define write_barrier() asm volatile ("sfence\n" ::: "memory")
#else
#define write_barrier() asm volatile ("" ::: "memory");
#endif
#else
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() cpuid_serialization()
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#define memory_barrier() cpuid_serialization()
#define read_barrier() cpuid_serialization()
#ifdef CONFIG_WEAK_MEMORY
#define write_barrier() cpuid_serialization()
#else
#define write_barrier() asm volatile ("" ::: "memory");
#endif
#endif
 
/*
90,8 → 90,8
* queueing in the store buffer drain to the memory (even though it would be
* sufficient for them to drain to the D-cache).
*/
#define smc_coherence(a) write_barrier()
#define smc_coherence_block(a, l) write_barrier()
#define smc_coherence(a) write_barrier()
#define smc_coherence_block(a, l) write_barrier()
 
#endif
 
/branches/arm/kernel/arch/ia32/include/interrupt.h
72,10 → 72,6
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;
uint32_t ebx;
 
uint32_t gs;
uint32_t fs;
/branches/arm/kernel/arch/ia32/include/fpu_context.h
37,7 → 37,6
 
#include <arch/types.h>
 
#define ARCH_HAS_FPU
#define FPU_CONTEXT_ALIGN 16
 
void fpu_fxsr(void);
/branches/arm/kernel/arch/ia32/include/syscall.h
0,0 → 1,0
link ../../amd64/include/syscall.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/ia32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-i386
BFD_ARCH = i386
BFD = binary
39,7 → 35,8
TARGET = i686-pc-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686
 
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__
BITS = 32
ENDIANESS = LE
 
CMN1 = -m32
GCC_CFLAGS += $(CMN1)
49,115 → 46,61
## Accepted CPUs
#
 
ifeq ($(MACHINE),athlon-xp)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-3dnow
ifeq ($(PROCESSOR),athlon_xp)
CMN2 = -march=athlon-xp
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=ssea
DEFS += -DCONFIG_FENCES_P3
CONFIG_SMP = n
CONFIG_HT = n
endif
ifeq ($(MACHINE),athlon-mp)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-3dnow
ifeq ($(PROCESSOR),athlon_mp)
CMN2 = -march=athlon-mp
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += xarch=ssea
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),pentium3)
FPU_NO_CFLAGS = -mno-mmx -mno-sse
ifeq ($(PROCESSOR),pentium3)
CMN2 = -march=pentium3
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=sse
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),core)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3
ifeq ($(PROCESSOR),pentium4)
CMN2 = -march=pentium4
SUNCC_CFLAGS += -xarch=sse2
endif
ifeq ($(PROCESSOR),core)
CMN2 = -march=prescott
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=sse3
DEFS += -DCONFIG_FENCES_P4
endif
ifeq ($(MACHINE),pentium4)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2
GCC_CFLAGS += -march=pentium4
ICC_CFLAGS += -march=pentium4
SUNCC_CFLAGS += -xarch=sse2
DEFS += -DCONFIG_FENCES_P4
endif
 
## Own configuration directives
#
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with i8042 controller support
#
 
CONFIG_I8042 = y
DEFS += -DCONFIG_I8042
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
ifeq ($(CONFIG_SIMICS_FIX),y)
DEFS += -DCONFIG_SIMICS_FIX
endif
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/delay.s \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/task.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/smp/ap.S \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c \
arch/$(ARCH)/src/atomic.S \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/ia32.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/debugger.c
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/debug/panic.s \
arch/$(KARCH)/src/delay.s \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/proc/task.c \
arch/$(KARCH)/src/proc/thread.c \
arch/$(KARCH)/src/bios/bios.c \
arch/$(KARCH)/src/smp/ap.S \
arch/$(KARCH)/src/smp/apic.c \
arch/$(KARCH)/src/smp/mps.c \
arch/$(KARCH)/src/smp/smp.c \
arch/$(KARCH)/src/atomic.S \
arch/$(KARCH)/src/smp/ipi.c \
arch/$(KARCH)/src/ia32.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/pm.c \
arch/$(KARCH)/src/userspace.c \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/i8254.c \
arch/$(KARCH)/src/drivers/i8259.c \
arch/$(KARCH)/src/drivers/vesa.c \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/boot/memmap.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/debugger.c \
arch/$(KARCH)/src/syscall.c
/branches/arm/kernel/arch/ia32/src/smp/mps.c
86,10 → 86,10
/*
* Implementation of IA-32 SMP configuration interface.
*/
static count_t get_cpu_count(void);
static bool is_cpu_enabled(index_t i);
static bool is_bsp(index_t i);
static uint8_t get_cpu_apic_id(index_t i);
static size_t get_cpu_count(void);
static bool is_cpu_enabled(size_t i);
static bool is_bsp(size_t i);
static uint8_t get_cpu_apic_id(size_t i);
static int mps_irq_to_pin(unsigned int irq);
 
struct smp_config_operations mps_config_operations = {
100,24 → 100,24
.irq_to_pin = mps_irq_to_pin
};
 
count_t get_cpu_count(void)
size_t get_cpu_count(void)
{
return processor_entry_cnt;
}
 
bool is_cpu_enabled(index_t i)
bool is_cpu_enabled(size_t i)
{
ASSERT(i < processor_entry_cnt);
return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01);
}
 
bool is_bsp(index_t i)
bool is_bsp(size_t i)
{
ASSERT(i < processor_entry_cnt);
return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02);
}
 
uint8_t get_cpu_apic_id(index_t i)
uint8_t get_cpu_apic_id(size_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].l_apic_id;
/branches/arm/kernel/arch/ia32/src/smp/apic.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
132,12 → 132,12
#endif
}
 
static irq_ownership_t l_apic_timer_claim(void)
static irq_ownership_t l_apic_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
static void l_apic_timer_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...)
static void l_apic_timer_irq_handler(irq_t *irq)
{
/*
* Holding a spinlock could prevent clock() from preempting
/branches/arm/kernel/arch/ia32/src/smp/smp.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
75,12 → 75,12
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
FRAME_ATOMIC | FRAME_KA);
if (!l_apic_address)
panic("cannot allocate address for l_apic\n");
panic("Cannot allocate address for l_apic.");
 
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
FRAME_ATOMIC | FRAME_KA);
if (!io_apic_address)
panic("cannot allocate address for io_apic\n");
panic("Cannot allocate address for io_apic.");
 
if (config.cpu_count > 1) {
page_mapping_insert(AS_KERNEL, l_apic_address,
122,8 → 122,8
* Save 0xa to address 0xf of the CMOS RAM.
* BIOS will not do the POST after the INIT signal.
*/
outb(0x70, 0xf);
outb(0x71, 0xa);
pio_write_8((ioport8_t *)0x70, 0xf);
pio_write_8((ioport8_t *)0x71, 0xa);
 
pic_disable_irqs(0xffff);
apic_init();
131,8 → 131,8
uint8_t apic = l_apic_id();
 
for (i = 0; i < ops->cpu_count(); i++) {
struct descriptor *gdt_new;
descriptor_t *gdt_new;
/*
* Skip processors marked unusable.
*/
154,14 → 154,19
/*
* Prepare new GDT for CPU in question.
*/
gdt_new = (struct descriptor *) malloc(GDT_ITEMS *
sizeof(struct descriptor), FRAME_ATOMIC | FRAME_LOW_4_GiB);
/* XXX Flag FRAME_LOW_4_GiB was removed temporarily,
* it needs to be replaced by a generic fuctionality of
* the memory subsystem
*/
gdt_new = (descriptor_t *) malloc(GDT_ITEMS *
sizeof(descriptor_t), FRAME_ATOMIC);
if (!gdt_new)
panic("couldn't allocate memory for GDT\n");
panic("Cannot allocate memory for GDT.");
 
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0);
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t));
memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0);
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(descriptor_t);
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
gdtr.base = (uintptr_t) gdt_new;
 
/branches/arm/kernel/arch/ia32/src/ddi/ddi.c
57,7 → 57,7
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
size_t bits;
 
bits = ioaddr + size;
if (bits > IO_PORTS)
99,7 → 99,7
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
 
/*
* Increment I/O Permission bitmap generation counter.
118,10 → 118,10
*/
void io_perm_bitmap_install(void)
{
count_t bits;
size_t bits;
ptr_16_32_t cpugdtr;
descriptor_t *gdt_p;
count_t ver;
size_t ver;
 
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
156,7 → 156,7
* type must be changed to describe inactive TSS.
*/
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
tr_load(selector(TSS_DES));
tr_load(gdtselector(TSS_DES));
/*
* Update the generation count so that faults caused by
/branches/arm/kernel/arch/ia32/src/mm/tlb.c
59,7 → 59,7
* @param page Address of the first page whose entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
{
unsigned int i;
 
67,5 → 67,13
invlpg(page + i * PAGE_SIZE);
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/ia32/src/mm/frame.c
54,26 → 54,57
static void init_e820_memory(pfn_t minconf)
{
unsigned int i;
pfn_t start, conf;
size_t size;
 
for (i = 0; i < e820counter; i++) {
uint64_t base = e820table[i].base_address;
uint64_t size = e820table[i].size;
#ifdef __32_BITS__
/* Ignore physical memory above 4 GB */
if ((base >> 32) != 0)
continue;
/* Clip regions above 4 GB */
if (((base + size) >> 32) != 0)
size = 0xffffffff - base;
#endif
pfn_t pfn;
size_t count;
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE));
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE));
/* To be safe, make available zone possibly smaller */
pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE));
count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE));
if ((minconf < start) || (minconf >= start + size))
conf = start;
pfn_t conf;
if ((minconf < pfn) || (minconf >= pfn + count))
conf = pfn;
else
conf = minconf;
zone_create(start, size, conf, 0);
zone_create(pfn, count, conf, ZONE_AVAILABLE);
if (last_frame < ALIGN_UP(e820table[i].base_address +
e820table[i].size, FRAME_SIZE))
last_frame =
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
}
// XXX this has to be removed
if (last_frame < ALIGN_UP(base + size, FRAME_SIZE))
last_frame = ALIGN_UP(base + size, FRAME_SIZE);
}
if (e820table[i].type == MEMMAP_MEMORY_RESERVED) {
/* To be safe, make reserved zone possibly larger */
pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE));
count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE));
zone_create(pfn, count, 0, ZONE_RESERVED);
}
if (e820table[i].type == MEMMAP_MEMORY_ACPI) {
/* To be safe, make firmware zone possibly larger */
pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE));
count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE));
zone_create(pfn, count, 0, ZONE_FIRMWARE);
}
}
}
 
113,16 → 144,14
if (config.cpu_active == 1) {
minconf = 1;
#ifdef CONFIG_SMP
minconf = max(minconf,
ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size +
hardcoded_unmapped_kdata_size));
#endif
#ifdef CONFIG_SIMICS_FIX
minconf = max(minconf, ADDR2PFN(0x10000));
#endif
init_e820_memory(minconf);
 
/* Reserve frame 0 (BIOS data) */
frame_mark_unavailable(0, 1);
131,12 → 160,7
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH,
(hardcoded_unmapped_ktext_size +
hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
#ifdef CONFIG_SIMICS_FIX
/* Don't know why, but these addresses help */
frame_mark_unavailable(0xd000 >> FRAME_WIDTH, 3);
#endif
#endif
}
}
 
/branches/arm/kernel/arch/ia32/src/mm/page.c
53,7 → 53,7
{
uintptr_t cur;
int flags;
 
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
66,12 → 66,12
flags |= PAGE_GLOBAL;
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
 
exc_register(14, "page_fault", (iroutine) page_fault);
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
} else
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 
paging_on();
}
 
79,7 → 79,7
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
panic("Unable to map physical memory %p (%d bytes).", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
101,8 → 101,8
page = read_cr2();
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page directory.\n");
 
panic("Reserved bit set in page directory.");
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
else
109,11 → 109,11
access = PF_ACCESS_READ;
if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault: %#x", page);
fault_if_from_uspace(istate, "Page fault: %#x.", page);
decode_istate(istate);
printf("page fault address: %#lx\n", page);
panic("page fault\n");
panic("Page fault.");
}
}
 
/branches/arm/kernel/arch/ia32/src/interrupt.c
44,7 → 44,6
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <synch/spinlock.h>
52,6 → 51,7
#include <ipc/sysipc.h>
#include <interrupt.h>
#include <ddi/irq.h>
#include <symtab.h>
 
/*
* Interrupt and exception dispatching.
63,10 → 63,9
 
void decode_istate(istate_t *istate)
{
char *symbol = get_symtab_entry(istate->eip);
char *symbol;
 
if (!symbol)
symbol = "";
symbol = symtab_fmt_name_lookup(istate->eip);
 
if (CPU)
printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id);
77,9 → 76,6
printf("ERROR_WORD=%#lx\n", istate->error_word);
printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags);
printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%esi=%#lx, %%edi=%#lx, %%ebp=%#lx, %%ebx=%#lx\n", istate->esi, istate->edi, istate->ebp, istate->ebx);
#endif
printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
printf(" %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
}
89,16 → 85,16
if (eoi_function)
eoi_function();
else
panic("no eoi_function\n");
panic("No eoi_function.");
 
}
 
static void null_interrupt(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n);
 
decode_istate(istate);
panic("unserviced interrupt: %d\n", n);
panic("Unserviced interrupt: %d.", n);
}
 
/** General Protection Fault. */
105,7 → 101,7
static void gp_fault(int n __attribute__((unused)), istate_t *istate)
{
if (TASK) {
count_t ver;
size_t ver;
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
122,19 → 118,19
io_perm_bitmap_install();
return;
}
fault_if_from_uspace(istate, "general protection fault");
fault_if_from_uspace(istate, "General protection fault.");
}
 
decode_istate(istate);
panic("general protection fault\n");
panic("General protection fault.");
}
 
static void ss_fault(int n __attribute__((unused)), istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
fault_if_from_uspace(istate, "Stack fault.");
 
decode_istate(istate);
panic("stack fault\n");
panic("Stack fault.");
}
 
static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate)
141,15 → 137,15
{
uint32_t mxcsr;
asm (
"stmxcsr %0;\n"
: "=m" (mxcsr)
"stmxcsr %[mxcsr]\n"
: [mxcsr] "=m" (mxcsr)
);
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx",
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.",
(unative_t) mxcsr);
 
decode_istate(istate);
printf("MXCSR: %#lx\n", mxcsr);
panic("SIMD FP exception(19)\n");
panic("SIMD FP exception(19).");
}
 
static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
157,8 → 153,8
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "fpu fault");
panic("fpu fault");
fault_if_from_uspace(istate, "FPU fault.");
panic("FPU fault.");
#endif
}
 
191,7 → 187,7
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
233,7 → 229,7
if (enable_irqs_function)
enable_irqs_function(irqmask);
else
panic("no enable_irqs_function\n");
panic("No enable_irqs_function.");
}
 
void trap_virtual_disable_irqs(uint16_t irqmask)
241,7 → 237,7
if (disable_irqs_function)
disable_irqs_function(irqmask);
else
panic("no disable_irqs_function\n");
panic("No disable_irqs_function.");
}
 
/** @}
/branches/arm/kernel/arch/ia32/src/atomic.S
42,9 → 42,7
movl 12(%esp),%ebx
 
0:
#ifdef CONFIG_HT
pause # Pentium 4's with HT love this instruction
#endif
movl (%ebx),%eax
testl %eax,%eax
jnz 0b # lightweight looping while it is locked
/branches/arm/kernel/arch/ia32/src/ia32.c
1,5 → 1,7
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2009 Jiri Svoboda
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
38,9 → 40,12
 
#include <arch/pm.h>
 
#include <arch/drivers/ega.h>
#include <genarch/multiboot/multiboot.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <arch/drivers/vesa.h>
#include <genarch/kbd/i8042.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/drivers/i8254.h>
#include <arch/drivers/i8259.h>
 
60,12 → 65,30
#include <proc/thread.h>
#include <syscall/syscall.h>
#include <console/console.h>
#include <ddi/device.h>
#include <sysinfo/sysinfo.h>
#include <arch/boot/boot.h>
 
#ifdef CONFIG_SMP
#include <arch/smp/apic.h>
#endif
 
/** Perform ia32-specific initialization before main_bsp() is called.
*
* @param signature Should contain the multiboot signature.
* @param mi Pointer to the multiboot information structure.
*/
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi)
{
/* Parse multiboot information obtained from the bootloader. */
multiboot_info_parse(signature, mi);
#ifdef CONFIG_SMP
/* Copy AP bootstrap routines below 1 MB. */
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
(size_t) &_hardcoded_unmapped_size);
#endif
}
 
void arch_pre_mm_init(void)
{
pm_init();
87,13 → 110,17
/* hard clock */
i8254_init();
 
#ifdef CONFIG_FB
if (vesa_present())
if (vesa_present())
vesa_init();
else
#endif
ega_init(); /* video */
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
#else
{}
#endif
/* Enable debugger */
debugger_init();
123,10 → 150,33
 
void arch_post_smp_init(void)
{
devno_t kbd = device_assign_devno();
devno_t mouse = device_assign_devno();
/* keyboard controller */
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
#ifdef CONFIG_PC_KBD
/*
* Initialize the i8042 controller. Then initialize the keyboard
* module and connect it to i8042. Enable keyboard interrupts.
*/
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
if (i8042_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
i8042_wire(i8042_instance, kbrd);
trap_virtual_enable_irqs(1 << IRQ_KBD);
}
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) I8042_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
}
 
void calibrate_delay_loop(void)
159,15 → 209,45
*/
void arch_grab_console(void)
{
i8042_grab();
#ifdef CONFIG_FB
if (vesa_present())
vesa_redraw();
else
#endif
#ifdef CONFIG_EGA
ega_redraw();
#else
{}
#endif
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
i8042_release();
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
void arch_reboot(void)
{
#ifdef CONFIG_PC_KBD
i8042_cpu_reset((i8042_t *) I8042_BASE);
#endif
}
 
/** @}
*/
/branches/arm/kernel/arch/ia32/src/pm.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
112,7 → 112,7
 
void tss_initialize(tss_t *t)
{
memsetb(t, sizeof(struct tss), 0);
memsetb(t, sizeof(tss_t), 0);
}
 
/*
127,7 → 127,7
d = &idt[i];
 
d->unused = 0;
d->selector = selector(KTEXT_DES);
d->selector = gdtselector(KTEXT_DES);
 
d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */
 
154,7 → 154,7
"and $0xffff8fff, %%eax\n"
"push %%eax\n"
"popfl\n"
: : : "eax"
::: "eax"
);
}
 
165,7 → 165,7
"mov %%cr0, %%eax\n"
"and $0xfffbffff, %%eax\n"
"mov %%eax, %%cr0\n"
: : : "eax"
::: "eax"
);
}
 
198,7 → 198,7
else {
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
if (!tss_p)
panic("could not allocate TSS\n");
panic("Cannot allocate TSS.");
}
 
tss_initialize(tss_p);
214,7 → 214,7
* As of this moment, the current CPU has its own GDT pointing
* to its own TSS. We just need to load the TR register.
*/
tr_load(selector(TSS_DES));
tr_load(gdtselector(TSS_DES));
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */
clean_AM_flag(); /* Disable alignment check */
232,28 → 232,5
gdtr_load(&cpugdtr);
}
 
/* Reboot the machine by initiating
* a triple fault
*/
void arch_reboot(void)
{
preemption_disable();
ipl_t ipl = interrupts_disable();
memsetb(idt, sizeof(idt), 0);
ptr_16_32_t idtr;
idtr.limit = sizeof(idt);
idtr.base = (uintptr_t) idt;
idtr_load(&idtr);
interrupts_restore(ipl);
asm volatile (
"int $0x03\n"
"cli\n"
"hlt\n"
);
}
 
/** @}
*/
/branches/arm/kernel/arch/ia32/src/boot/boot.S
31,6 → 31,7
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
#include <arch/cpuid.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
42,40 → 43,41
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long multiboot_header
.long unmapped_ktext_start
.long 0
.long 0
.long multiboot_image_start
 
multiboot_image_start:
cld
movl $START_STACK, %esp # initialize stack pointer
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
 
movw $selector(KDATA_DES), %cx
movl $START_STACK, %esp # initialize stack pointer
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ds # kernel data + stack
movw %cx, %ss
jmpl $selector(KTEXT_DES), $multiboot_meeting_point
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, grub_eax # save parameters from GRUB
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
xorl %eax, %eax
cpuid
cmp $0x0, %eax # any function > 0?
movl $(INTEL_CPUID_LEVEL), %eax
cpuid
cmp $0x0, %eax # any function > 0?
jbe pse_unsupported
movl $0x1, %eax # Basic function code 1
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $3, %edx # Test if PSE is supported
bt $(INTEL_PSE), %edx
jc pse_supported
 
pse_unsupported:
movl $pse_msg, %esi
jmp error_halt
82,138 → 84,31
pse_supported:
#ifdef CONFIG_FB
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
rep movsb
 
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
bt $(INTEL_SEP), %edx
jc sep_supported
vesa_meeting_point:
movl $sep_msg, %esi
jmp error_halt
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
sep_supported:
 
#include "vesa_prot.inc"
 
# map kernel and turn paging on
call map_kernel
call map_kernel # map kernel and turn paging on
# call arch_pre_main(grub_eax, grub_ebx)
pushl grub_ebx
pushl grub_eax
call arch_pre_main
movl grub_eax, %eax
movl grub_ebx, %ebx
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
je valid_boot
xorl %ecx, %ecx # no memory map available
movl %ecx, e820counter
jmp invalid_boot
valid_boot:
movl (%ebx), %eax # ebx = physical address of struct multiboot_info
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid)
jc mods_valid
xorl %ecx, %ecx
movl %ecx, init
jmp mods_end
mods_valid:
movl 20(%ebx), %ecx # mbi->mods_count
movl %ecx, init
cmpl $0, %ecx
je mods_end
movl 24(%ebx), %esi # mbi->mods_addr
movl $init, %edi
mods_loop:
movl 0(%esi), %edx # mods->mod_start
addl $0x80000000, %edx
movl %edx, 4(%edi)
movl 4(%esi), %edx
subl 0(%esi), %edx # mods->mod_end - mods->mod_start
movl %edx, 8(%edi)
addl $16, %esi
addl $8 , %edi
loop mods_loop
mods_end:
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid)
jc mmap_valid
xorl %edx, %edx
jmp mmap_invalid
mmap_valid:
movl 44(%ebx), %ecx # mbi->mmap_length
movl 48(%ebx), %esi # mbi->mmap_addr
movl $e820table, %edi
xorl %edx, %edx
mmap_loop:
cmpl $0, %ecx
jle mmap_end
movl 4(%esi), %eax # mmap->base_addr_low
movl %eax, (%edi)
movl 8(%esi), %eax # mmap->base_addr_high
movl %eax, 4(%edi)
movl 12(%esi), %eax # mmap->length_low
movl %eax, 8(%edi)
movl 16(%esi), %eax # mmap->length_high
movl %eax, 12(%edi)
movl 20(%esi), %eax # mmap->type
movl %eax, 16(%edi)
movl (%esi), %eax # mmap->size
addl $0x4, %eax
addl %eax, %esi
subl %eax, %ecx
addl $MEMMAP_E820_RECORD_SIZE, %edi
incl %edx
jmp mmap_loop
mmap_end:
mmap_invalid:
movl %edx, e820counter
invalid_boot:
call main_bsp
#ifdef CONFIG_SMP
# copy AP bootstrap routines below 1 MB
movl $BOOT_OFFSET, %esi
movl $AP_BOOT_OFFSET, %edi
movl $_hardcoded_unmapped_size, %ecx
rep movsb
#endif
 
call main_bsp # never returns
 
# not reached
cli
hlt
hlt0:
hlt
jmp hlt0
 
.global map_kernel
map_kernel:
222,8 → 117,8
# For simplicity, we map the entire 4G space.
#
movl %cr4, %ecx
orl $(1 << 4), %ecx # turn PSE on
andl $(~(1 << 5)), %ecx # turn PAE off
orl $(1 << 4), %ecx # turn PSE on
andl $(~(1 << 5)), %ecx # turn PAE off
movl %ecx, %cr4
movl $(page_directory + 0), %esi
230,30 → 125,31
movl $(page_directory + 2048), %edi
xorl %ecx, %ecx
xorl %ebx, %ebx
0:
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
addl $(4 * 1024 * 1024), %ebx
 
incl %ecx
cmpl $512, %ecx
jl 0b
 
floop:
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
addl $(4 * 1024 * 1024), %ebx
incl %ecx
cmpl $512, %ecx
jl floop
movl %esi, %cr3
movl %cr0, %ebx
orl $(1 << 31), %ebx # turn paging on
orl $(1 << 31), %ebx # turn paging on
movl %ebx, %cr0
ret
 
# Print string from %esi to EGA display (in red) and halt
error_halt:
movl $0xb8000, %edi # base of EGA text mode memory
movl $0xb8000, %edi # base of EGA text mode memory
xorl %eax, %eax
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
261,7 → 157,7
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
270,7 → 166,9
cmp $1920, %ax
jbe cursor_ok
movw $1920, %ax # sanity check for the cursor on the last line
movw $1920, %ax # sanity check for the cursor on the last line
cursor_ok:
movw %ax, %bx
277,7 → 175,7
shl $1, %eax
addl %eax, %edi
movw $0x0c00, %ax # black background, light red foreground
movw $0x0c00, %ax # black background, light red foreground
ploop:
lodsb
284,11 → 182,11
cmp $0, %al
je ploop_end
stosw
inc %bx
inc %bx
jmp ploop
ploop_end:
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
296,7 → 194,7
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
303,240 → 201,14
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
hlt1:
hlt
jmp hlt1
 
#ifdef CONFIG_FB
vesa_init:
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl %esp, %eax
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
pushl %eax
#define VESA_INFO_SIZE 1024
#include "vesa_real.inc"
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
#if CONFIG_VESA_BPP == 24
#define CONFIG_VESA_BPP_VARIANT 32
#endif
 
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
 
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz 0f
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz 0f
mov $CONFIG_VESA_WIDTH, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
 
#ifdef CONFIG_VESA_BPP_VARIANT
jz 2f
mov $CONFIG_VESA_BPP_VARIANT, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
#endif
jnz 1b
 
2:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
 
#if CONFIG_VESA_BPP == 8
# Set 3:2:3 VGA palette
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # Test if VGA compatible registers are present
jnc vga_compat
# Try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
jmp vga_not_compat
vga_compat:
# Try VGA registers to set palette
movw $0x3c6, %dx # Set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # First index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # Data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
#endif
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
8:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp 9f
9:
ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
 
0:# No prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz 1f
jz 2b # Force relative jump
1:
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
vga323:
#include "vga323.pal"
 
.code32
vesa_init_protect:
movw $selector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ss
movl $START_STACK, %esp # initialize stack pointer
 
jmpl $selector(KTEXT_DES), $vesa_meeting_point
 
.align 4
e_vesa_init:
#endif
 
.section K_DATA_START, "aw", @progbits
 
.align 4096
551,3 → 223,6
 
pse_msg:
.asciz "Page Size Extension not supported. System halted."
 
sep_msg:
.asciz "SYSENTER/SYSEXIT not supported. System halted."
/branches/arm/kernel/arch/ia32/src/boot/vesa_real.inc
0,0 → 1,373
#ifdef CONFIG_FB
 
#include <macros.h>
 
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_RED_MASK_OFFSET 31
#define VESA_MODE_RED_POS_OFFSET 32
#define VESA_MODE_GREEN_MASK_OFFSET 33
#define VESA_MODE_GREEN_POS_OFFSET 34
#define VESA_MODE_BLUE_MASK_OFFSET 35
#define VESA_MODE_BLUE_POS_OFFSET 36
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
.code32
vesa_init:
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl %esp, %eax
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
pushl %eax
# parse default mode string
mov $default_mode - vesa_init, %di
xor %eax, %eax
xor %ebx, %ebx
mov $8, %ecx
parse_width:
mov (%di), %al
# check for digit
cmp $'0', %al
jb parse_width_done
cmp $'9', %al
ja parse_width_done
sub $'0', %al
# multiply default_width by 10 and add digit
mov default_width - vesa_init, %bx
lea (%ebx, %ebx, 4), %ebx
shl $1, %ebx
add %ax, %bx
mov %bx, default_width - vesa_init
inc %di
loop parse_width
parse_width_done:
mov (%di), %al
cmp $0, %al
jz parse_done
inc %di
mov $8, %ecx
parse_height:
mov (%di), %al
# check for digit
cmp $'0', %al
jb parse_height_done
cmp $'9', %al
ja parse_height_done
sub $'0', %al
# multiply default_height by 10 and add digit
mov default_height - vesa_init, %bx
lea (%ebx, %ebx, 4), %ebx
shl $1, %ebx
add %ax, %bx
mov %bx, default_height - vesa_init
inc %di
loop parse_height
parse_height_done:
mov (%di), %al
cmp $0, %al
jz parse_done
inc %di
mov $4, %ecx
parse_bpp:
mov (%di), %al
# check for digit
cmp $'0', %al
jb parse_bpp_done
cmp $'9', %al
ja parse_bpp_done
sub $'0', %al
# multiply default_bpp by 10 and add digit
mov default_bpp - vesa_init, %bx
lea (%ebx, %ebx, 4), %ebx
shl $1, %ebx
add %ax, %bx
mov %bx, default_bpp - vesa_init
inc %di
loop parse_bpp
parse_bpp_done:
parse_done:
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz no_mode
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
next_mode:
# try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
je no_mode
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jne no_mode
# check for proper attributes (supported, color, graphics, linear framebuffer)
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
and $0x99, %ax
cmp $0x99, %ax
jne next_mode
# check for proper resolution
mov default_width - vesa_init, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jne next_mode
mov default_height - vesa_init, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jne next_mode
# check for proper bpp
mov default_bpp - vesa_init, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
je set_mode
mov $24, %al
cmp default_bpp - vesa_init, %al
jne next_mode
# for 24 bpp modes accept also 32 bit bpp
mov $32, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jne next_mode
set_mode:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz no_mode
# set 3:2:3 VGA palette
mov VESA_MODE_BPP_OFFSET(%di), %al
cmp $8, %al
jnz vga_not_set
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # test if VGA compatible registers are present
jnc vga_compat
# try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
cmp $0x00, %ah
je vga_not_compat
vga_compat:
# try VGA registers to set palette
movw $0x3c6, %dx # set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # first index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
vga_not_set:
# store mode parameters
# eax = bpp[8] scanline[16]
# ebx = width[16] height[16]
# edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
# esi = blue_mask[8] blue_pos[8]
# edi = linear frame buffer
mov VESA_MODE_BPP_OFFSET(%di), %al
xor %ah, %ah
shl $16, %eax
mov VESA_MODE_SCANLINE_OFFSET(%di), %ax
mov VESA_MODE_WIDTH_OFFSET(%di), %bx
shl $16, %ebx
mov VESA_MODE_HEIGHT_OFFSET(%di), %bx
mov VESA_MODE_BLUE_MASK_OFFSET(%di), %dl
shl $8, %edx
mov VESA_MODE_BLUE_POS_OFFSET(%di), %dl
mov %edx, %esi
mov VESA_MODE_RED_MASK_OFFSET(%di), %dl
shl $8, %edx
mov VESA_MODE_RED_POS_OFFSET(%di), %dl
shl $8, %edx
mov VESA_MODE_GREEN_MASK_OFFSET(%di), %dl
shl $8, %edx
mov VESA_MODE_GREEN_POS_OFFSET(%di), %dl
mov VESA_MODE_PHADDR_OFFSET(%di), %edi
vesa_leave_real:
mov %cr0, %ecx
or $1, %ecx
mov %ecx, %cr0
jmp vesa_leave_real2
vesa_leave_real2:
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
no_mode:
# no prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz text_mode
jz set_mode # force relative jump
text_mode:
# reset to EGA text mode (because of problems with VESA)
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi
xor %ax, %ax
jz vesa_leave_real # force relative jump
 
vga323:
#include "vga323.pal"
 
default_width:
.word 0
 
default_height:
.word 0
 
default_bpp:
.byte 0
 
default_mode:
.ascii STRING(CONFIG_VESA_MODE)
.ascii "-"
.asciz STRING(CONFIG_VESA_BPP)
.fill 24
 
#include "vesa_ret.inc"
 
.align 4
e_vesa_init:
#endif
/branches/arm/kernel/arch/ia32/src/boot/vesa_prot.inc
0,0 → 1,107
#ifdef CONFIG_FB
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
#define MBINFO_BIT_CMDLINE 2
#define MBINFO_OFFSET_CMDLINE 16
 
# copy real mode VESA initialization code
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
rep movsb
# check for GRUB command line
mov grub_eax, %eax
cmp $MULTIBOOT_LOADER_MAGIC, %eax
jne no_cmdline
mov grub_ebx, %ebx
mov (%ebx), %eax
bt $MBINFO_BIT_CMDLINE, %eax
jnc no_cmdline
# skip the kernel path in command line
mov MBINFO_OFFSET_CMDLINE(%ebx), %esi
skip_loop:
lodsb
cmp $0, %al
je no_cmdline
cmp $' ', %al
je skip_loop_done
jmp skip_loop
skip_loop_done:
space_loop:
mov (%esi), %al
cmp $0, %al
je no_cmdline
cmp $' ', %al
jne space_loop_done
inc %esi
jmp space_loop
space_loop_done:
# copy at most 23 characters from command line
mov $VESA_INIT_SEGMENT << 4, %edi
add $default_mode - vesa_init, %edi
mov $23, %ecx
cmd_loop:
lodsb
stosb
cmp $0, %al
je cmd_loop_done
loop cmd_loop
cmd_loop_done:
# zero termination
xor %eax, %eax
stosb
no_cmdline:
# jump to the real mode
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
vesa_meeting_point:
# returned back to protected mode
mov %ax, KA2PA(vesa_scanline)
shr $16, %eax
mov %ax, KA2PA(vesa_bpp)
mov %bx, KA2PA(vesa_height)
shr $16, %ebx
mov %bx, KA2PA(vesa_width)
mov %dl, KA2PA(vesa_green_pos)
shr $8, %edx
mov %dl, KA2PA(vesa_green_mask)
shr $8, %edx
mov %dl, KA2PA(vesa_red_pos)
shr $8, %edx
mov %dl, KA2PA(vesa_red_mask)
mov %esi, %edx
mov %dl, KA2PA(vesa_blue_pos)
shr $8, %edx
mov %dl, KA2PA(vesa_blue_mask)
mov %edi, KA2PA(vesa_ph_addr)
#endif
/branches/arm/kernel/arch/ia32/src/boot/vesa_ret.inc
0,0 → 1,12
.code32
vesa_init_protected:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ss
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point
/branches/arm/kernel/arch/ia32/src/boot/vga323.pal
1,256 → 1,256
.byte 0x3f, 0x3f, 0x3f, 0x00
.byte 0x36, 0x3f, 0x3f, 0x00
.byte 0x2d, 0x3f, 0x3f, 0x00
.byte 0x24, 0x3f, 0x3f, 0x00
.byte 0x1b, 0x3f, 0x3f, 0x00
.byte 0x12, 0x3f, 0x3f, 0x00
.byte 0x09, 0x3f, 0x3f, 0x00
.byte 0x00, 0x3f, 0x3f, 0x00
.byte 0x3f, 0x2a, 0x3f, 0x00
.byte 0x36, 0x2a, 0x3f, 0x00
.byte 0x2d, 0x2a, 0x3f, 0x00
.byte 0x24, 0x2a, 0x3f, 0x00
.byte 0x1b, 0x2a, 0x3f, 0x00
.byte 0x12, 0x2a, 0x3f, 0x00
.byte 0x09, 0x2a, 0x3f, 0x00
.byte 0x00, 0x2a, 0x3f, 0x00
.byte 0x3f, 0x15, 0x3f, 0x00
.byte 0x36, 0x15, 0x3f, 0x00
.byte 0x2d, 0x15, 0x3f, 0x00
.byte 0x24, 0x15, 0x3f, 0x00
.byte 0x1b, 0x15, 0x3f, 0x00
.byte 0x12, 0x15, 0x3f, 0x00
.byte 0x09, 0x15, 0x3f, 0x00
.byte 0x00, 0x15, 0x3f, 0x00
.byte 0x3f, 0x00, 0x3f, 0x00
.byte 0x36, 0x00, 0x3f, 0x00
.byte 0x2d, 0x00, 0x3f, 0x00
.byte 0x24, 0x00, 0x3f, 0x00
.byte 0x1b, 0x00, 0x3f, 0x00
.byte 0x12, 0x00, 0x3f, 0x00
.byte 0x09, 0x00, 0x3f, 0x00
.byte 0x00, 0x00, 0x3f, 0x00
.byte 0x3f, 0x3f, 0x36, 0x00
.byte 0x36, 0x3f, 0x36, 0x00
.byte 0x2d, 0x3f, 0x36, 0x00
.byte 0x24, 0x3f, 0x36, 0x00
.byte 0x1b, 0x3f, 0x36, 0x00
.byte 0x12, 0x3f, 0x36, 0x00
.byte 0x09, 0x3f, 0x36, 0x00
.byte 0x00, 0x3f, 0x36, 0x00
.byte 0x3f, 0x2a, 0x36, 0x00
.byte 0x36, 0x2a, 0x36, 0x00
.byte 0x2d, 0x2a, 0x36, 0x00
.byte 0x24, 0x2a, 0x36, 0x00
.byte 0x1b, 0x2a, 0x36, 0x00
.byte 0x12, 0x2a, 0x36, 0x00
.byte 0x09, 0x2a, 0x36, 0x00
.byte 0x00, 0x2a, 0x36, 0x00
.byte 0x3f, 0x15, 0x36, 0x00
.byte 0x36, 0x15, 0x36, 0x00
.byte 0x2d, 0x15, 0x36, 0x00
.byte 0x24, 0x15, 0x36, 0x00
.byte 0x1b, 0x15, 0x36, 0x00
.byte 0x12, 0x15, 0x36, 0x00
.byte 0x09, 0x15, 0x36, 0x00
.byte 0x00, 0x15, 0x36, 0x00
.byte 0x3f, 0x00, 0x36, 0x00
.byte 0x36, 0x00, 0x36, 0x00
.byte 0x2d, 0x00, 0x36, 0x00
.byte 0x24, 0x00, 0x36, 0x00
.byte 0x1b, 0x00, 0x36, 0x00
.byte 0x12, 0x00, 0x36, 0x00
.byte 0x09, 0x00, 0x36, 0x00
.byte 0x00, 0x00, 0x36, 0x00
.byte 0x3f, 0x3f, 0x2d, 0x00
.byte 0x36, 0x3f, 0x2d, 0x00
.byte 0x2d, 0x3f, 0x2d, 0x00
.byte 0x24, 0x3f, 0x2d, 0x00
.byte 0x1b, 0x3f, 0x2d, 0x00
.byte 0x12, 0x3f, 0x2d, 0x00
.byte 0x09, 0x3f, 0x2d, 0x00
.byte 0x00, 0x3f, 0x2d, 0x00
.byte 0x3f, 0x2a, 0x2d, 0x00
.byte 0x36, 0x2a, 0x2d, 0x00
.byte 0x2d, 0x2a, 0x2d, 0x00
.byte 0x24, 0x2a, 0x2d, 0x00
.byte 0x1b, 0x2a, 0x2d, 0x00
.byte 0x12, 0x2a, 0x2d, 0x00
.byte 0x09, 0x2a, 0x2d, 0x00
.byte 0x00, 0x2a, 0x2d, 0x00
.byte 0x3f, 0x15, 0x2d, 0x00
.byte 0x36, 0x15, 0x2d, 0x00
.byte 0x2d, 0x15, 0x2d, 0x00
.byte 0x24, 0x15, 0x2d, 0x00
.byte 0x1b, 0x15, 0x2d, 0x00
.byte 0x12, 0x15, 0x2d, 0x00
.byte 0x09, 0x15, 0x2d, 0x00
.byte 0x00, 0x15, 0x2d, 0x00
.byte 0x3f, 0x00, 0x2d, 0x00
.byte 0x36, 0x00, 0x2d, 0x00
.byte 0x2d, 0x00, 0x2d, 0x00
.byte 0x24, 0x00, 0x2d, 0x00
.byte 0x1b, 0x00, 0x2d, 0x00
.byte 0x12, 0x00, 0x2d, 0x00
.byte 0x09, 0x00, 0x2d, 0x00
.byte 0x00, 0x00, 0x2d, 0x00
.byte 0x3f, 0x3f, 0x24, 0x00
.byte 0x36, 0x3f, 0x24, 0x00
.byte 0x2d, 0x3f, 0x24, 0x00
.byte 0x24, 0x3f, 0x24, 0x00
.byte 0x1b, 0x3f, 0x24, 0x00
.byte 0x12, 0x3f, 0x24, 0x00
.byte 0x09, 0x3f, 0x24, 0x00
.byte 0x00, 0x3f, 0x24, 0x00
.byte 0x3f, 0x2a, 0x24, 0x00
.byte 0x36, 0x2a, 0x24, 0x00
.byte 0x2d, 0x2a, 0x24, 0x00
.byte 0x24, 0x2a, 0x24, 0x00
.byte 0x1b, 0x2a, 0x24, 0x00
.byte 0x12, 0x2a, 0x24, 0x00
.byte 0x09, 0x2a, 0x24, 0x00
.byte 0x00, 0x2a, 0x24, 0x00
.byte 0x3f, 0x15, 0x24, 0x00
.byte 0x36, 0x15, 0x24, 0x00
.byte 0x2d, 0x15, 0x24, 0x00
.byte 0x24, 0x15, 0x24, 0x00
.byte 0x1b, 0x15, 0x24, 0x00
.byte 0x12, 0x15, 0x24, 0x00
.byte 0x09, 0x15, 0x24, 0x00
.byte 0x00, 0x15, 0x24, 0x00
.byte 0x3f, 0x00, 0x24, 0x00
.byte 0x36, 0x00, 0x24, 0x00
.byte 0x2d, 0x00, 0x24, 0x00
.byte 0x24, 0x00, 0x24, 0x00
.byte 0x1b, 0x00, 0x24, 0x00
.byte 0x12, 0x00, 0x24, 0x00
.byte 0x09, 0x00, 0x24, 0x00
.byte 0x00, 0x00, 0x24, 0x00
.byte 0x3f, 0x3f, 0x1b, 0x00
.byte 0x36, 0x3f, 0x1b, 0x00
.byte 0x2d, 0x3f, 0x1b, 0x00
.byte 0x24, 0x3f, 0x1b, 0x00
.byte 0x1b, 0x3f, 0x1b, 0x00
.byte 0x12, 0x3f, 0x1b, 0x00
.byte 0x09, 0x3f, 0x1b, 0x00
.byte 0x00, 0x3f, 0x1b, 0x00
.byte 0x3f, 0x2a, 0x1b, 0x00
.byte 0x36, 0x2a, 0x1b, 0x00
.byte 0x2d, 0x2a, 0x1b, 0x00
.byte 0x24, 0x2a, 0x1b, 0x00
.byte 0x1b, 0x2a, 0x1b, 0x00
.byte 0x12, 0x2a, 0x1b, 0x00
.byte 0x09, 0x2a, 0x1b, 0x00
.byte 0x00, 0x2a, 0x1b, 0x00
.byte 0x3f, 0x15, 0x1b, 0x00
.byte 0x36, 0x15, 0x1b, 0x00
.byte 0x2d, 0x15, 0x1b, 0x00
.byte 0x24, 0x15, 0x1b, 0x00
.byte 0x1b, 0x15, 0x1b, 0x00
.byte 0x12, 0x15, 0x1b, 0x00
.byte 0x09, 0x15, 0x1b, 0x00
.byte 0x00, 0x15, 0x1b, 0x00
.byte 0x3f, 0x00, 0x1b, 0x00
.byte 0x36, 0x00, 0x1b, 0x00
.byte 0x2d, 0x00, 0x1b, 0x00
.byte 0x24, 0x00, 0x1b, 0x00
.byte 0x1b, 0x00, 0x1b, 0x00
.byte 0x12, 0x00, 0x1b, 0x00
.byte 0x09, 0x00, 0x1b, 0x00
.byte 0x00, 0x00, 0x1b, 0x00
.byte 0x3f, 0x3f, 0x12, 0x00
.byte 0x36, 0x3f, 0x12, 0x00
.byte 0x2d, 0x3f, 0x12, 0x00
.byte 0x24, 0x3f, 0x12, 0x00
.byte 0x1b, 0x3f, 0x12, 0x00
.byte 0x12, 0x3f, 0x12, 0x00
.byte 0x09, 0x3f, 0x12, 0x00
.byte 0x00, 0x3f, 0x12, 0x00
.byte 0x3f, 0x2a, 0x12, 0x00
.byte 0x36, 0x2a, 0x12, 0x00
.byte 0x2d, 0x2a, 0x12, 0x00
.byte 0x24, 0x2a, 0x12, 0x00
.byte 0x1b, 0x2a, 0x12, 0x00
.byte 0x12, 0x2a, 0x12, 0x00
.byte 0x09, 0x2a, 0x12, 0x00
.byte 0x00, 0x2a, 0x12, 0x00
.byte 0x3f, 0x15, 0x12, 0x00
.byte 0x36, 0x15, 0x12, 0x00
.byte 0x2d, 0x15, 0x12, 0x00
.byte 0x24, 0x15, 0x12, 0x00
.byte 0x1b, 0x15, 0x12, 0x00
.byte 0x12, 0x15, 0x12, 0x00
.byte 0x09, 0x15, 0x12, 0x00
.byte 0x00, 0x15, 0x12, 0x00
.byte 0x3f, 0x00, 0x12, 0x00
.byte 0x36, 0x00, 0x12, 0x00
.byte 0x2d, 0x00, 0x12, 0x00
.byte 0x24, 0x00, 0x12, 0x00
.byte 0x1b, 0x00, 0x12, 0x00
.byte 0x12, 0x00, 0x12, 0x00
.byte 0x09, 0x00, 0x12, 0x00
.byte 0x00, 0x00, 0x12, 0x00
.byte 0x3f, 0x3f, 0x09, 0x00
.byte 0x36, 0x3f, 0x09, 0x00
.byte 0x2d, 0x3f, 0x09, 0x00
.byte 0x24, 0x3f, 0x09, 0x00
.byte 0x1b, 0x3f, 0x09, 0x00
.byte 0x12, 0x3f, 0x09, 0x00
.byte 0x09, 0x3f, 0x09, 0x00
.byte 0x00, 0x3f, 0x09, 0x00
.byte 0x3f, 0x2a, 0x09, 0x00
.byte 0x36, 0x2a, 0x09, 0x00
.byte 0x2d, 0x2a, 0x09, 0x00
.byte 0x24, 0x2a, 0x09, 0x00
.byte 0x1b, 0x2a, 0x09, 0x00
.byte 0x12, 0x2a, 0x09, 0x00
.byte 0x09, 0x2a, 0x09, 0x00
.byte 0x00, 0x2a, 0x09, 0x00
.byte 0x3f, 0x15, 0x09, 0x00
.byte 0x36, 0x15, 0x09, 0x00
.byte 0x2d, 0x15, 0x09, 0x00
.byte 0x24, 0x15, 0x09, 0x00
.byte 0x1b, 0x15, 0x09, 0x00
.byte 0x12, 0x15, 0x09, 0x00
.byte 0x09, 0x15, 0x09, 0x00
.byte 0x00, 0x15, 0x09, 0x00
.byte 0x3f, 0x00, 0x09, 0x00
.byte 0x36, 0x00, 0x09, 0x00
.byte 0x2d, 0x00, 0x09, 0x00
.byte 0x24, 0x00, 0x09, 0x00
.byte 0x1b, 0x00, 0x09, 0x00
.byte 0x12, 0x00, 0x09, 0x00
.byte 0x09, 0x00, 0x09, 0x00
.byte 0x00, 0x00, 0x09, 0x00
.byte 0x3f, 0x3f, 0x00, 0x00
.byte 0x36, 0x3f, 0x00, 0x00
.byte 0x2d, 0x3f, 0x00, 0x00
.byte 0x24, 0x3f, 0x00, 0x00
.byte 0x1b, 0x3f, 0x00, 0x00
.byte 0x12, 0x3f, 0x00, 0x00
.byte 0x09, 0x3f, 0x00, 0x00
.byte 0x00, 0x3f, 0x00, 0x00
.byte 0x3f, 0x2a, 0x00, 0x00
.byte 0x36, 0x2a, 0x00, 0x00
.byte 0x2d, 0x2a, 0x00, 0x00
.byte 0x24, 0x2a, 0x00, 0x00
.byte 0x1b, 0x2a, 0x00, 0x00
.byte 0x12, 0x2a, 0x00, 0x00
.byte 0x09, 0x2a, 0x00, 0x00
.byte 0x00, 0x2a, 0x00, 0x00
.byte 0x3f, 0x15, 0x00, 0x00
.byte 0x36, 0x15, 0x00, 0x00
.byte 0x2d, 0x15, 0x00, 0x00
.byte 0x24, 0x15, 0x00, 0x00
.byte 0x1b, 0x15, 0x00, 0x00
.byte 0x12, 0x15, 0x00, 0x00
.byte 0x09, 0x15, 0x00, 0x00
.byte 0x00, 0x15, 0x00, 0x00
.byte 0x3f, 0x00, 0x00, 0x00
.byte 0x36, 0x00, 0x00, 0x00
.byte 0x2d, 0x00, 0x00, 0x00
.byte 0x24, 0x00, 0x00, 0x00
.byte 0x1b, 0x00, 0x00, 0x00
.byte 0x12, 0x00, 0x00, 0x00
.byte 0x09, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00
.byte 0x09, 0x00, 0x00, 0x00
.byte 0x12, 0x00, 0x00, 0x00
.byte 0x1b, 0x00, 0x00, 0x00
.byte 0x24, 0x00, 0x00, 0x00
.byte 0x2d, 0x00, 0x00, 0x00
.byte 0x36, 0x00, 0x00, 0x00
.byte 0x3f, 0x00, 0x00, 0x00
.byte 0x00, 0x15, 0x00, 0x00
.byte 0x09, 0x15, 0x00, 0x00
.byte 0x12, 0x15, 0x00, 0x00
.byte 0x1b, 0x15, 0x00, 0x00
.byte 0x24, 0x15, 0x00, 0x00
.byte 0x2d, 0x15, 0x00, 0x00
.byte 0x36, 0x15, 0x00, 0x00
.byte 0x3f, 0x15, 0x00, 0x00
.byte 0x00, 0x2a, 0x00, 0x00
.byte 0x09, 0x2a, 0x00, 0x00
.byte 0x12, 0x2a, 0x00, 0x00
.byte 0x1b, 0x2a, 0x00, 0x00
.byte 0x24, 0x2a, 0x00, 0x00
.byte 0x2d, 0x2a, 0x00, 0x00
.byte 0x36, 0x2a, 0x00, 0x00
.byte 0x3f, 0x2a, 0x00, 0x00
.byte 0x00, 0x3f, 0x00, 0x00
.byte 0x09, 0x3f, 0x00, 0x00
.byte 0x12, 0x3f, 0x00, 0x00
.byte 0x1b, 0x3f, 0x00, 0x00
.byte 0x24, 0x3f, 0x00, 0x00
.byte 0x2d, 0x3f, 0x00, 0x00
.byte 0x36, 0x3f, 0x00, 0x00
.byte 0x3f, 0x3f, 0x00, 0x00
.byte 0x00, 0x00, 0x09, 0x00
.byte 0x09, 0x00, 0x09, 0x00
.byte 0x12, 0x00, 0x09, 0x00
.byte 0x1b, 0x00, 0x09, 0x00
.byte 0x24, 0x00, 0x09, 0x00
.byte 0x2d, 0x00, 0x09, 0x00
.byte 0x36, 0x00, 0x09, 0x00
.byte 0x3f, 0x00, 0x09, 0x00
.byte 0x00, 0x15, 0x09, 0x00
.byte 0x09, 0x15, 0x09, 0x00
.byte 0x12, 0x15, 0x09, 0x00
.byte 0x1b, 0x15, 0x09, 0x00
.byte 0x24, 0x15, 0x09, 0x00
.byte 0x2d, 0x15, 0x09, 0x00
.byte 0x36, 0x15, 0x09, 0x00
.byte 0x3f, 0x15, 0x09, 0x00
.byte 0x00, 0x2a, 0x09, 0x00
.byte 0x09, 0x2a, 0x09, 0x00
.byte 0x12, 0x2a, 0x09, 0x00
.byte 0x1b, 0x2a, 0x09, 0x00
.byte 0x24, 0x2a, 0x09, 0x00
.byte 0x2d, 0x2a, 0x09, 0x00
.byte 0x36, 0x2a, 0x09, 0x00
.byte 0x3f, 0x2a, 0x09, 0x00
.byte 0x00, 0x3f, 0x09, 0x00
.byte 0x09, 0x3f, 0x09, 0x00
.byte 0x12, 0x3f, 0x09, 0x00
.byte 0x1b, 0x3f, 0x09, 0x00
.byte 0x24, 0x3f, 0x09, 0x00
.byte 0x2d, 0x3f, 0x09, 0x00
.byte 0x36, 0x3f, 0x09, 0x00
.byte 0x3f, 0x3f, 0x09, 0x00
.byte 0x00, 0x00, 0x12, 0x00
.byte 0x09, 0x00, 0x12, 0x00
.byte 0x12, 0x00, 0x12, 0x00
.byte 0x1b, 0x00, 0x12, 0x00
.byte 0x24, 0x00, 0x12, 0x00
.byte 0x2d, 0x00, 0x12, 0x00
.byte 0x36, 0x00, 0x12, 0x00
.byte 0x3f, 0x00, 0x12, 0x00
.byte 0x00, 0x15, 0x12, 0x00
.byte 0x09, 0x15, 0x12, 0x00
.byte 0x12, 0x15, 0x12, 0x00
.byte 0x1b, 0x15, 0x12, 0x00
.byte 0x24, 0x15, 0x12, 0x00
.byte 0x2d, 0x15, 0x12, 0x00
.byte 0x36, 0x15, 0x12, 0x00
.byte 0x3f, 0x15, 0x12, 0x00
.byte 0x00, 0x2a, 0x12, 0x00
.byte 0x09, 0x2a, 0x12, 0x00
.byte 0x12, 0x2a, 0x12, 0x00
.byte 0x1b, 0x2a, 0x12, 0x00
.byte 0x24, 0x2a, 0x12, 0x00
.byte 0x2d, 0x2a, 0x12, 0x00
.byte 0x36, 0x2a, 0x12, 0x00
.byte 0x3f, 0x2a, 0x12, 0x00
.byte 0x00, 0x3f, 0x12, 0x00
.byte 0x09, 0x3f, 0x12, 0x00
.byte 0x12, 0x3f, 0x12, 0x00
.byte 0x1b, 0x3f, 0x12, 0x00
.byte 0x24, 0x3f, 0x12, 0x00
.byte 0x2d, 0x3f, 0x12, 0x00
.byte 0x36, 0x3f, 0x12, 0x00
.byte 0x3f, 0x3f, 0x12, 0x00
.byte 0x00, 0x00, 0x1b, 0x00
.byte 0x09, 0x00, 0x1b, 0x00
.byte 0x12, 0x00, 0x1b, 0x00
.byte 0x1b, 0x00, 0x1b, 0x00
.byte 0x24, 0x00, 0x1b, 0x00
.byte 0x2d, 0x00, 0x1b, 0x00
.byte 0x36, 0x00, 0x1b, 0x00
.byte 0x3f, 0x00, 0x1b, 0x00
.byte 0x00, 0x15, 0x1b, 0x00
.byte 0x09, 0x15, 0x1b, 0x00
.byte 0x12, 0x15, 0x1b, 0x00
.byte 0x1b, 0x15, 0x1b, 0x00
.byte 0x24, 0x15, 0x1b, 0x00
.byte 0x2d, 0x15, 0x1b, 0x00
.byte 0x36, 0x15, 0x1b, 0x00
.byte 0x3f, 0x15, 0x1b, 0x00
.byte 0x00, 0x2a, 0x1b, 0x00
.byte 0x09, 0x2a, 0x1b, 0x00
.byte 0x12, 0x2a, 0x1b, 0x00
.byte 0x1b, 0x2a, 0x1b, 0x00
.byte 0x24, 0x2a, 0x1b, 0x00
.byte 0x2d, 0x2a, 0x1b, 0x00
.byte 0x36, 0x2a, 0x1b, 0x00
.byte 0x3f, 0x2a, 0x1b, 0x00
.byte 0x00, 0x3f, 0x1b, 0x00
.byte 0x09, 0x3f, 0x1b, 0x00
.byte 0x12, 0x3f, 0x1b, 0x00
.byte 0x1b, 0x3f, 0x1b, 0x00
.byte 0x24, 0x3f, 0x1b, 0x00
.byte 0x2d, 0x3f, 0x1b, 0x00
.byte 0x36, 0x3f, 0x1b, 0x00
.byte 0x3f, 0x3f, 0x1b, 0x00
.byte 0x00, 0x00, 0x24, 0x00
.byte 0x09, 0x00, 0x24, 0x00
.byte 0x12, 0x00, 0x24, 0x00
.byte 0x1b, 0x00, 0x24, 0x00
.byte 0x24, 0x00, 0x24, 0x00
.byte 0x2d, 0x00, 0x24, 0x00
.byte 0x36, 0x00, 0x24, 0x00
.byte 0x3f, 0x00, 0x24, 0x00
.byte 0x00, 0x15, 0x24, 0x00
.byte 0x09, 0x15, 0x24, 0x00
.byte 0x12, 0x15, 0x24, 0x00
.byte 0x1b, 0x15, 0x24, 0x00
.byte 0x24, 0x15, 0x24, 0x00
.byte 0x2d, 0x15, 0x24, 0x00
.byte 0x36, 0x15, 0x24, 0x00
.byte 0x3f, 0x15, 0x24, 0x00
.byte 0x00, 0x2a, 0x24, 0x00
.byte 0x09, 0x2a, 0x24, 0x00
.byte 0x12, 0x2a, 0x24, 0x00
.byte 0x1b, 0x2a, 0x24, 0x00
.byte 0x24, 0x2a, 0x24, 0x00
.byte 0x2d, 0x2a, 0x24, 0x00
.byte 0x36, 0x2a, 0x24, 0x00
.byte 0x3f, 0x2a, 0x24, 0x00
.byte 0x00, 0x3f, 0x24, 0x00
.byte 0x09, 0x3f, 0x24, 0x00
.byte 0x12, 0x3f, 0x24, 0x00
.byte 0x1b, 0x3f, 0x24, 0x00
.byte 0x24, 0x3f, 0x24, 0x00
.byte 0x2d, 0x3f, 0x24, 0x00
.byte 0x36, 0x3f, 0x24, 0x00
.byte 0x3f, 0x3f, 0x24, 0x00
.byte 0x00, 0x00, 0x2d, 0x00
.byte 0x09, 0x00, 0x2d, 0x00
.byte 0x12, 0x00, 0x2d, 0x00
.byte 0x1b, 0x00, 0x2d, 0x00
.byte 0x24, 0x00, 0x2d, 0x00
.byte 0x2d, 0x00, 0x2d, 0x00
.byte 0x36, 0x00, 0x2d, 0x00
.byte 0x3f, 0x00, 0x2d, 0x00
.byte 0x00, 0x15, 0x2d, 0x00
.byte 0x09, 0x15, 0x2d, 0x00
.byte 0x12, 0x15, 0x2d, 0x00
.byte 0x1b, 0x15, 0x2d, 0x00
.byte 0x24, 0x15, 0x2d, 0x00
.byte 0x2d, 0x15, 0x2d, 0x00
.byte 0x36, 0x15, 0x2d, 0x00
.byte 0x3f, 0x15, 0x2d, 0x00
.byte 0x00, 0x2a, 0x2d, 0x00
.byte 0x09, 0x2a, 0x2d, 0x00
.byte 0x12, 0x2a, 0x2d, 0x00
.byte 0x1b, 0x2a, 0x2d, 0x00
.byte 0x24, 0x2a, 0x2d, 0x00
.byte 0x2d, 0x2a, 0x2d, 0x00
.byte 0x36, 0x2a, 0x2d, 0x00
.byte 0x3f, 0x2a, 0x2d, 0x00
.byte 0x00, 0x3f, 0x2d, 0x00
.byte 0x09, 0x3f, 0x2d, 0x00
.byte 0x12, 0x3f, 0x2d, 0x00
.byte 0x1b, 0x3f, 0x2d, 0x00
.byte 0x24, 0x3f, 0x2d, 0x00
.byte 0x2d, 0x3f, 0x2d, 0x00
.byte 0x36, 0x3f, 0x2d, 0x00
.byte 0x3f, 0x3f, 0x2d, 0x00
.byte 0x00, 0x00, 0x36, 0x00
.byte 0x09, 0x00, 0x36, 0x00
.byte 0x12, 0x00, 0x36, 0x00
.byte 0x1b, 0x00, 0x36, 0x00
.byte 0x24, 0x00, 0x36, 0x00
.byte 0x2d, 0x00, 0x36, 0x00
.byte 0x36, 0x00, 0x36, 0x00
.byte 0x3f, 0x00, 0x36, 0x00
.byte 0x00, 0x15, 0x36, 0x00
.byte 0x09, 0x15, 0x36, 0x00
.byte 0x12, 0x15, 0x36, 0x00
.byte 0x1b, 0x15, 0x36, 0x00
.byte 0x24, 0x15, 0x36, 0x00
.byte 0x2d, 0x15, 0x36, 0x00
.byte 0x36, 0x15, 0x36, 0x00
.byte 0x3f, 0x15, 0x36, 0x00
.byte 0x00, 0x2a, 0x36, 0x00
.byte 0x09, 0x2a, 0x36, 0x00
.byte 0x12, 0x2a, 0x36, 0x00
.byte 0x1b, 0x2a, 0x36, 0x00
.byte 0x24, 0x2a, 0x36, 0x00
.byte 0x2d, 0x2a, 0x36, 0x00
.byte 0x36, 0x2a, 0x36, 0x00
.byte 0x3f, 0x2a, 0x36, 0x00
.byte 0x00, 0x3f, 0x36, 0x00
.byte 0x09, 0x3f, 0x36, 0x00
.byte 0x12, 0x3f, 0x36, 0x00
.byte 0x1b, 0x3f, 0x36, 0x00
.byte 0x24, 0x3f, 0x36, 0x00
.byte 0x2d, 0x3f, 0x36, 0x00
.byte 0x36, 0x3f, 0x36, 0x00
.byte 0x3f, 0x3f, 0x36, 0x00
.byte 0x00, 0x00, 0x3f, 0x00
.byte 0x09, 0x00, 0x3f, 0x00
.byte 0x12, 0x00, 0x3f, 0x00
.byte 0x1b, 0x00, 0x3f, 0x00
.byte 0x24, 0x00, 0x3f, 0x00
.byte 0x2d, 0x00, 0x3f, 0x00
.byte 0x36, 0x00, 0x3f, 0x00
.byte 0x3f, 0x00, 0x3f, 0x00
.byte 0x00, 0x15, 0x3f, 0x00
.byte 0x09, 0x15, 0x3f, 0x00
.byte 0x12, 0x15, 0x3f, 0x00
.byte 0x1b, 0x15, 0x3f, 0x00
.byte 0x24, 0x15, 0x3f, 0x00
.byte 0x2d, 0x15, 0x3f, 0x00
.byte 0x36, 0x15, 0x3f, 0x00
.byte 0x3f, 0x15, 0x3f, 0x00
.byte 0x00, 0x2a, 0x3f, 0x00
.byte 0x09, 0x2a, 0x3f, 0x00
.byte 0x12, 0x2a, 0x3f, 0x00
.byte 0x1b, 0x2a, 0x3f, 0x00
.byte 0x24, 0x2a, 0x3f, 0x00
.byte 0x2d, 0x2a, 0x3f, 0x00
.byte 0x36, 0x2a, 0x3f, 0x00
.byte 0x3f, 0x2a, 0x3f, 0x00
.byte 0x00, 0x3f, 0x3f, 0x00
.byte 0x09, 0x3f, 0x3f, 0x00
.byte 0x12, 0x3f, 0x3f, 0x00
.byte 0x1b, 0x3f, 0x3f, 0x00
.byte 0x24, 0x3f, 0x3f, 0x00
.byte 0x2d, 0x3f, 0x3f, 0x00
.byte 0x36, 0x3f, 0x3f, 0x00
.byte 0x3f, 0x3f, 0x3f, 0x00
/branches/arm/kernel/arch/ia32/src/drivers/ega.c
File deleted
/branches/arm/kernel/arch/ia32/src/drivers/vesa.c
56,12 → 56,20
uint16_t vesa_bpp;
uint16_t vesa_scanline;
 
uint8_t vesa_red_mask;
uint8_t vesa_red_pos;
 
uint8_t vesa_green_mask;
uint8_t vesa_green_pos;
 
uint8_t vesa_blue_mask;
uint8_t vesa_blue_pos;
 
int vesa_present(void)
{
if (vesa_width != 0xffff)
if ((vesa_width != 0xffff) && (vesa_height != 0xffff))
return true;
if (vesa_height != 0xffff)
return true;
return false;
}
 
74,7 → 82,12
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_6_5;
if ((vesa_red_mask == 5) && (vesa_red_pos == 10)
&& (vesa_green_mask == 5) && (vesa_green_pos == 5)
&& (vesa_blue_mask == 5) && (vesa_blue_pos == 0))
visual = VISUAL_RGB_5_5_5;
else
visual = VISUAL_RGB_5_6_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
83,12 → 96,25
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel");
panic("Unsupported bits per pixel.");
}
fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_scanline, visual);
fb_properties_t vesa_props = {
.addr = vesa_ph_addr,
.offset = 0,
.x = vesa_width,
.y = vesa_height,
.scan = vesa_scanline,
.visual = visual,
};
fb_init(&vesa_props);
}
 
void vesa_redraw(void)
{
fb_redraw();
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/src/drivers/i8254.c
26,12 → 26,12
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/**
* @file
* @brief i8254 chip driver.
* @brief i8254 chip driver.
*
* Low level time functions.
*/
53,8 → 53,8
#include <ddi/irq.h>
#include <ddi/device.h>
 
#define CLK_PORT1 0x40
#define CLK_PORT4 0x43
#define CLK_PORT1 ((ioport8_t *)0x40)
#define CLK_PORT4 ((ioport8_t *)0x43)
 
#define CLK_CONST 1193180
#define MAGIC_NUMBER 1194
61,12 → 61,12
 
static irq_t i8254_irq;
 
static irq_ownership_t i8254_claim(void)
static irq_ownership_t i8254_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
static void i8254_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...)
static void i8254_irq_handler(irq_t *irq)
{
/*
* This IRQ is responsible for kernel preemption.
94,10 → 94,10
 
void i8254_normal_operation(void)
{
outb(CLK_PORT4, 0x36);
pio_write_8(CLK_PORT4, 0x36);
pic_disable_irqs(1 << IRQ_CLK);
outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf);
outb(CLK_PORT1, (CLK_CONST / HZ) >> 8);
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) & 0xf);
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) >> 8);
pic_enable_irqs(1 << IRQ_CLK);
}
 
114,36 → 114,36
* One-shot timer. Count-down from 0xffff at 1193180Hz
* MAGIC_NUMBER is the magic value for 1ms.
*/
outb(CLK_PORT4, 0x30);
outb(CLK_PORT1, 0xff);
outb(CLK_PORT1, 0xff);
pio_write_8(CLK_PORT4, 0x30);
pio_write_8(CLK_PORT1, 0xff);
pio_write_8(CLK_PORT1, 0xff);
 
do {
/* will read both status and count */
outb(CLK_PORT4, 0xc2);
not_ok = (uint8_t) ((inb(CLK_PORT1) >> 6) & 1);
t1 = inb(CLK_PORT1);
t1 |= inb(CLK_PORT1) << 8;
pio_write_8(CLK_PORT4, 0xc2);
not_ok = (uint8_t) ((pio_read_8(CLK_PORT1) >> 6) & 1);
t1 = pio_read_8(CLK_PORT1);
t1 |= pio_read_8(CLK_PORT1) << 8;
} while (not_ok);
 
asm_delay_loop(LOOPS);
 
outb(CLK_PORT4, 0xd2);
t2 = inb(CLK_PORT1);
t2 |= inb(CLK_PORT1) << 8;
pio_write_8(CLK_PORT4, 0xd2);
t2 = pio_read_8(CLK_PORT1);
t2 |= pio_read_8(CLK_PORT1) << 8;
 
/*
* We want to determine the overhead of the calibrating mechanism.
*/
outb(CLK_PORT4, 0xd2);
o1 = inb(CLK_PORT1);
o1 |= inb(CLK_PORT1) << 8;
pio_write_8(CLK_PORT4, 0xd2);
o1 = pio_read_8(CLK_PORT1);
o1 |= pio_read_8(CLK_PORT1) << 8;
 
asm_fake_loop(LOOPS);
 
outb(CLK_PORT4, 0xd2);
o2 = inb(CLK_PORT1);
o2 |= inb(CLK_PORT1) << 8;
pio_write_8(CLK_PORT4, 0xd2);
o2 = pio_read_8(CLK_PORT1);
o2 |= pio_read_8(CLK_PORT1) << 8;
 
CPU->delay_loop_const =
((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) +
/branches/arm/kernel/arch/ia32/src/drivers/i8259.c
49,28 → 49,28
void i8259_init(void)
{
/* ICW1: this is ICW1, ICW4 to follow */
outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4);
pio_write_8(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4);
 
/* ICW2: IRQ 0 maps to INT IRQBASE */
outb(PIC_PIC0PORT2, IVT_IRQBASE);
pio_write_8(PIC_PIC0PORT2, IVT_IRQBASE);
 
/* ICW3: pic1 using IRQ IRQ_PIC1 */
outb(PIC_PIC0PORT2, 1 << IRQ_PIC1);
pio_write_8(PIC_PIC0PORT2, 1 << IRQ_PIC1);
 
/* ICW4: i8086 mode */
outb(PIC_PIC0PORT2, 1);
pio_write_8(PIC_PIC0PORT2, 1);
 
/* ICW1: ICW1, ICW4 to follow */
outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4);
pio_write_8(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4);
 
/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */
outb(PIC_PIC1PORT2, IVT_IRQBASE + 8);
pio_write_8(PIC_PIC1PORT2, IVT_IRQBASE + 8);
 
/* ICW3: pic1 is known as IRQ_PIC1 */
outb(PIC_PIC1PORT2, IRQ_PIC1);
pio_write_8(PIC_PIC1PORT2, IRQ_PIC1);
 
/* ICW4: i8086 mode */
outb(PIC_PIC1PORT2, 1);
pio_write_8(PIC_PIC1PORT2, 1);
 
/*
* Register interrupt handler for the PIC spurious interrupt.
94,12 → 94,12
uint8_t x;
 
if (irqmask & 0xff) {
x = inb(PIC_PIC0PORT2);
outb(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff))));
x = pio_read_8(PIC_PIC0PORT2);
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff))));
}
if (irqmask >> 8) {
x = inb(PIC_PIC1PORT2);
outb(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8))));
x = pio_read_8(PIC_PIC1PORT2);
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8))));
}
}
 
108,19 → 108,19
uint8_t x;
 
if (irqmask & 0xff) {
x = inb(PIC_PIC0PORT2);
outb(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff)));
x = pio_read_8(PIC_PIC0PORT2);
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff)));
}
if (irqmask >> 8) {
x = inb(PIC_PIC1PORT2);
outb(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8)));
x = pio_read_8(PIC_PIC1PORT2);
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8)));
}
}
 
void pic_eoi(void)
{
outb(0x20, 0x20);
outb(0xa0, 0x20);
pio_write_8((ioport8_t *)0x20, 0x20);
pio_write_8((ioport8_t *)0xa0, 0x20);
}
 
void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
/branches/arm/kernel/arch/ia32/src/proc/scheduler.c
38,7 → 38,6
#include <proc/thread.h>
#include <arch.h>
#include <arch/context.h> /* SP_DELTA */
#include <arch/debugger.h>
#include <arch/pm.h>
#include <arch/asm.h>
#include <arch/ddi/ddi.h>
58,21 → 57,18
*/
void before_thread_runs_arch(void)
{
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
SP_DELTA];
CPU->arch.tss->ss0 = selector(KDATA_DES);
 
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
write_msr(IA32_MSR_SYSENTER_ESP, kstk);
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
CPU->arch.tss->esp0 = kstk;
CPU->arch.tss->ss0 = gdtselector(KDATA_DES);
/* Set up TLS in GS register */
set_tls_desc(THREAD->arch.tls);
 
#ifdef CONFIG_DEBUG_AS_WATCHPOINT
/* Set watchpoint on AS to ensure that nobody sets it to zero */
if (CPU->id < BKPOINTS_MAX) {
the_t *the = THE;
breakpoint_add(&((the_t *) the->thread->kstack)->as,
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, the->cpu->id);
}
#endif
}
 
void after_thread_ran_arch(void)
/branches/arm/kernel/arch/ia32/src/syscall.c
0,0 → 1,53
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ia32
* @{
*/
/** @file
*/
 
#include <arch/syscall.h>
#include <arch/cpu.h>
#include <arch/asm.h>
#include <arch/types.h>
#include <arch/pm.h>
 
/** Enable & setup support for SYSENTER/SYSEXIT */
void syscall_setup_cpu(void)
{
extern void sysenter_handler(void);
 
/* set kernel mode CS selector */
write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES));
/* set kernel mode entry point */
write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler);
}
 
/** @}
*/
/branches/arm/kernel/arch/ia32/src/userspace.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
47,10 → 47,8
*/
void userspace(uspace_arg_t *kernel_uarg)
{
ipl_t ipl;
 
ipl = interrupts_disable();
 
ipl_t ipl = interrupts_disable();
asm volatile (
/*
* Clear nested task flag.
60,35 → 58,33
"and $0xffffbfff, %%eax\n"
"push %%eax\n"
"popfl\n"
 
/* Set up GS register (TLS) */
"movl %6, %%gs\n"
 
"pushl %0\n"
"pushl %1\n"
"pushl %2\n"
"pushl %3\n"
"pushl %4\n"
"movl %5, %%eax\n"
 
"movl %[tls_des], %%gs\n"
"pushl %[udata_des]\n"
"pushl %[stack_size]\n"
"pushl %[ipl]\n"
"pushl %[utext_des]\n"
"pushl %[entry]\n"
"movl %[uarg], %%eax\n"
/* %ebx is defined to hold pcb_ptr - set it to 0 */
"xorl %%ebx, %%ebx\n"
 
"xorl %%ebx, %%ebx\n"
"iret\n"
:
: "i" (selector(UDATA_DES) | PL_USER),
"r" ((uint8_t *) kernel_uarg->uspace_stack +
THREAD_STACK_SIZE),
"r" (ipl),
"i" (selector(UTEXT_DES) | PL_USER),
"r" (kernel_uarg->uspace_entry),
"r" (kernel_uarg->uspace_uarg),
"r" (selector(TLS_DES))
:
: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
[stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
[ipl] "r" (ipl),
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
[entry] "r" (kernel_uarg->uspace_entry),
[uarg] "r" (kernel_uarg->uspace_uarg),
[tls_des] "r" (gdtselector(TLS_DES))
: "eax");
/* Unreachable */
for(;;)
;
while (1);
}
 
/** @}
/branches/arm/kernel/arch/ia32/src/fpu_context.c
44,46 → 44,43
static void fpu_context_f_save(fpu_context_t *fctx)
{
asm volatile (
"fnsave %0"
: "=m"(*fctx)
);
"fnsave %[fctx]"
: [fctx] "=m" (*fctx)
);
}
 
static void fpu_context_f_restore(fpu_context_t *fctx)
{
asm volatile (
"frstor %0"
: "=m"(*fctx)
);
"frstor %[fctx]"
: [fctx] "=m" (*fctx)
);
}
 
static void fpu_context_fx_save(fpu_context_t *fctx)
{
asm volatile (
"fxsave %0"
: "=m"(*fctx)
);
"fxsave %[fctx]"
: [fctx] "=m" (*fctx)
);
}
 
static void fpu_context_fx_restore(fpu_context_t *fctx)
{
asm volatile (
"fxrstor %0"
: "=m"(*fctx)
);
"fxrstor %[fctx]"
: [fctx] "=m" (*fctx)
);
}
 
/*
Setup using fxsr instruction
*/
/* Setup using fxsr instruction */
void fpu_fxsr(void)
{
fpu_save=fpu_context_fx_save;
fpu_restore=fpu_context_fx_restore;
}
/*
Setup using not fxsr instruction
*/
 
/* Setup using not fxsr instruction */
void fpu_fsr(void)
{
fpu_save = fpu_context_f_save;
102,16 → 99,18
 
void fpu_init()
{
uint32_t help0 = 0, help1 = 0;
uint32_t help0 = 0;
uint32_t help1 = 0;
asm volatile (
"fninit;\n"
"stmxcsr %0\n"
"mov %0,%1;\n"
"or %2,%1;\n"
"mov %1,%0;\n"
"ldmxcsr %0;\n"
: "+m" (help0), "+r" (help1)
: "i" (0x1f80)
"fninit\n"
"stmxcsr %[help0]\n"
"mov %[help0], %[help1]\n"
"or %[magic], %[help1]\n"
"mov %[help1], %[help0]\n"
"ldmxcsr %[help0]\n"
: [help0] "+m" (help0), [help1] "+r" (help1)
: [magic] "i" (0x1f80)
);
}
 
/branches/arm/kernel/arch/ia32/src/cpu/cpu.c
42,22 → 42,23
#include <fpu_context.h>
 
#include <arch/smp/apic.h>
#include <arch/syscall.h>
 
/*
* Identification of CPUs.
* Contains only non-MP-Specification specific SMP code.
*/
#define AMD_CPUID_EBX 0x68747541
#define AMD_CPUID_ECX 0x444d4163
#define AMD_CPUID_EDX 0x69746e65
#define AMD_CPUID_EBX 0x68747541
#define AMD_CPUID_ECX 0x444d4163
#define AMD_CPUID_EDX 0x69746e65
 
#define INTEL_CPUID_EBX 0x756e6547
#define INTEL_CPUID_ECX 0x6c65746e
#define INTEL_CPUID_EDX 0x49656e69
#define INTEL_CPUID_EBX 0x756e6547
#define INTEL_CPUID_ECX 0x6c65746e
#define INTEL_CPUID_EDX 0x49656e69
 
 
enum vendor {
VendorUnknown=0,
VendorUnknown = 0,
VendorAMD,
VendorIntel
};
64,19 → 65,17
 
static char *vendor_str[] = {
"Unknown Vendor",
"AuthenticAMD",
"GenuineIntel"
"AMD",
"Intel"
};
 
void fpu_disable(void)
{
asm volatile (
"mov %%cr0,%%eax;"
"or $8,%%eax;"
"mov %%eax,%%cr0;"
:
:
:"%eax"
"mov %%cr0, %%eax\n"
"or $8, %%eax\n"
"mov %%eax, %%cr0\n"
::: "%eax"
);
}
 
83,13 → 82,11
void fpu_enable(void)
{
asm volatile (
"mov %%cr0,%%eax;"
"and $0xffFFffF7,%%eax;"
"mov %%eax,%%cr0;"
:
:
:"%eax"
);
"mov %%cr0, %%eax\n"
"and $0xffFFffF7, %%eax\n"
"mov %%eax,%%cr0\n"
::: "%eax"
);
}
 
void cpu_arch_init(void)
101,11 → 98,11
CPU->arch.tss = tss_p;
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss);
 
CPU->fpu_owner = NULL;
 
cpuid(1, &info);
 
fi.word = info.cpuid_edx;
efi.word = info.cpuid_ecx;
112,17 → 109,20
if (fi.bits.fxsr)
fpu_fxsr();
else
fpu_fsr();
fpu_fsr();
if (fi.bits.sse) {
asm volatile (
"mov %%cr4,%0\n"
"or %1,%0\n"
"mov %0,%%cr4\n"
: "+r" (help)
: "i" (CR4_OSFXSR_MASK|(1<<10))
"mov %%cr4, %[help]\n"
"or %[mask], %[help]\n"
"mov %[help], %%cr4\n"
: [help] "+r" (help)
: [mask] "i" (CR4_OSFXSR_MASK | (1 << 10))
);
}
/* Setup fast SYSENTER/SYSEXIT syscalls */
syscall_setup_cpu();
}
 
void cpu_identify(void)
136,29 → 136,31
/*
* Check for AMD processor.
*/
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
if ((info.cpuid_ebx == AMD_CPUID_EBX)
&& (info.cpuid_ecx == AMD_CPUID_ECX)
&& (info.cpuid_edx == AMD_CPUID_EDX))
CPU->arch.vendor = VendorAMD;
}
 
/*
* Check for Intel processor.
*/
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
if ((info.cpuid_ebx == INTEL_CPUID_EBX)
&& (info.cpuid_ecx == INTEL_CPUID_ECX)
&& (info.cpuid_edx == INTEL_CPUID_EDX))
CPU->arch.vendor = VendorIntel;
}
cpuid(1, &info);
CPU->arch.family = (info.cpuid_eax>>8)&0xf;
CPU->arch.model = (info.cpuid_eax>>4)&0xf;
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;
CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f;
CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f;
CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f;
}
}
 
void cpu_print_report(cpu_t* m)
void cpu_print_report(cpu_t* cpu)
{
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
m->frequency_mhz);
printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n",
cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family,
cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz);
}
 
/** @}
/branches/arm/kernel/arch/ia32/src/asm.S
147,6 → 147,46
popfl
.endm
 
/*
* The SYSENTER syscall mechanism can be used for syscalls with
* four or fewer arguments. To pass these four arguments, we
* use four registers: EDX, ECX, EBX, ESI. The syscall number
* is passed in EAX. We use EDI to remember the return address
* and EBP to remember the stack. The INT-based syscall mechanism
* can actually handle six arguments plus the syscall number
* entirely in registers.
*/
.global sysenter_handler
sysenter_handler:
sti
pushl %ebp # remember user stack
pushl %edi # remember return user address
 
pushl %gs # remember TLS
 
pushl %eax # syscall number
subl $8, %esp # unused sixth and fifth argument
pushl %esi # fourth argument
pushl %ebx # third argument
pushl %ecx # second argument
pushl %edx # first argument
 
movw $16, %ax
movw %ax, %ds
movw %ax, %es
 
cld
call syscall_handler
addl $28, %esp # remove arguments from stack
 
pop %gs # restore TLS
 
pop %edx # prepare return EIP for SYSEXIT
pop %ecx # prepare userspace ESP for SYSEXIT
 
sysexit # return to userspace
 
 
## Declare interrupt handlers
#
# Declare interrupt handlers for n interrupt
228,14 → 268,6
pushl %fs
pushl %gs
 
#ifdef CONFIG_DEBUG_ALLREGS
pushl %ebx
pushl %ebp
pushl %edi
pushl %esi
#else
subl $16, %esp
#endif
pushl %edx
pushl %ecx
pushl %eax
257,14 → 289,6
popl %eax
popl %ecx
popl %edx
#ifdef CONFIG_DEBUG_ALLREGS
popl %esi
popl %edi
popl %ebp
popl %ebx
#else
addl $16, %esp
#endif
popl %gs
popl %fs
/branches/arm/kernel/arch/ia32/_link.ld.in
1,11 → 1,11
/** IA-32 linker script
*
*
* umapped section:
* kernel text
* kernel data
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
* kernel text
* kernel data
*/
 
#include <arch/boot/boot.h>
28,9 → 28,9
ktext_end = .;
kdata_start = .;
*(.data); /* initialized data */
*(.rodata*); /* string literals */
*(COMMON); /* global variables */
*(.data); /* initialized data */
*(.rodata*); /* string literals */
*(COMMON); /* global variables */
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
hardcoded_ktext_size = .;
42,23 → 42,23
hardcoded_unmapped_kdata_size = .;
LONG(unmapped_kdata_end - unmapped_kdata_start);
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol! */
*(.bss); /* uninitialized static variables */
*(symtab.*); /* Symbol table, must be LAST symbol! */
*(.bss); /* uninitialized static variables */
kdata_end = .;
}
 
/DISCARD/ : {
*(.note.GNU-stack);
*(.note.GNU-stack);
*(.comment);
}
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
protected_ap_gdtr = PA2KA(ap_gdtr);
 
#endif /* CONFIG_SMP */
 
}
/branches/arm/kernel/generic/include/context.h
45,7 → 45,7
(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
#endif /* context_set */
 
extern int context_save_arch(context_t *c);
extern int context_save_arch(context_t *c) __attribute__ ((returns_twice));
extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
 
/** Save register context.
76,10 → 76,6
* corresponding call to context_save(), the only
* difference being return value.
*
* Note that content of any local variable defined by
* the caller of context_save() is undefined after
* context_restore().
*
* @param c Context structure.
*/
static inline void context_restore(context_t *c)
/branches/arm/kernel/generic/include/byteorder.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,32 → 35,48
#ifndef KERN_BYTEORDER_H_
#define KERN_BYTEORDER_H_
 
#include <arch/byteorder.h>
#include <arch/types.h>
 
#if !(defined(ARCH_IS_BIG_ENDIAN) ^ defined(ARCH_IS_LITTLE_ENDIAN))
#error The architecture must be either big-endian or little-endian.
#if !(defined(__BE__) ^ defined(__LE__))
#error The architecture must be either big-endian or little-endian.
#endif
 
#ifdef ARCH_IS_BIG_ENDIAN
#ifdef __BE__
 
#define uint16_t_le2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_le2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_le2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_le2host(n) (uint64_t_byteorder_swap(n))
 
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#define host2uint16_t_le(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_le(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_le(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_be(n) (n)
#define host2uint32_t_be(n) (n)
#define host2uint64_t_be(n) (n)
 
#else
 
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint16_t_be2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_be2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_be2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_be2host(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_le(n) (n)
#define host2uint32_t_le(n) (n)
#define host2uint64_t_le(n) (n)
 
#define host2uint16_t_be(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_be(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_be(n) (uint64_t_byteorder_swap(n))
 
#endif
 
static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
/branches/arm/kernel/generic/include/string.h
0,0 → 1,99
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef KERN_STRING_H_
#define KERN_STRING_H_
 
#include <typedefs.h>
 
/**< Common Unicode characters */
#define U_SPECIAL '?'
 
#define U_LEFT_ARROW 0x2190
#define U_UP_ARROW 0x2191
#define U_RIGHT_ARROW 0x2192
#define U_DOWN_ARROW 0x2193
 
#define U_PAGE_UP 0x21de
#define U_PAGE_DOWN 0x21df
 
#define U_HOME_ARROW 0x21f1
#define U_END_ARROW 0x21f2
 
#define U_NULL 0x2400
#define U_ESCAPE 0x241b
#define U_DELETE 0x2421
 
#define U_CURSOR 0x2588
 
/**< No size limit constant */
#define STR_NO_LIMIT ((size_t) -1)
 
/**< Maximum size of a string containing cnt characters */
#define STR_BOUNDS(cnt) (cnt << 2)
 
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
extern int chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
 
extern size_t str_size(const char *str);
extern size_t wstr_size(const wchar_t *str);
 
extern size_t str_lsize(const char *str, size_t max_len);
extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
 
extern size_t str_length(const char *str);
extern size_t wstr_length(const wchar_t *wstr);
 
extern size_t str_nlength(const char *str, size_t size);
extern size_t wstr_nlength(const wchar_t *str, size_t size);
 
extern bool ascii_check(wchar_t ch);
extern bool chr_check(wchar_t ch);
 
extern int str_cmp(const char *s1, const char *s2);
extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
 
extern void str_cpy(char *dest, size_t size, const char *src);
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
extern const char *str_chr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
 
#endif
 
/** @}
*/
/branches/arm/kernel/generic/include/symtab.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
44,15 → 44,20
char symbol_name[MAX_SYMBOL_NAME];
};
 
extern char * get_symtab_entry(unative_t addr);
extern uintptr_t get_symbol_addr(const char *name);
extern int symtab_name_lookup(unative_t addr, char **name);
extern char *symtab_fmt_name_lookup(unative_t addr);
extern int symtab_addr_lookup(const char *name, uintptr_t *addr);
extern void symtab_print_search(const char *name);
extern int symtab_compl(char *name);
extern int symtab_compl(char *input, size_t size);
 
#ifdef CONFIG_SYMTAB
 
/* Symtable linked together by build process */
extern struct symtab_entry symbol_table[];
 
#endif
 
#endif
 
/** @}
*/
/branches/arm/kernel/generic/include/config.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
38,17 → 38,19
#include <arch/types.h>
#include <arch/mm/page.h>
 
#define STACK_SIZE PAGE_SIZE
#define STACK_SIZE PAGE_SIZE
 
#define CONFIG_INIT_TASKS 32
#define CONFIG_INIT_TASKS 32
#define CONFIG_TASK_NAME_BUFLEN 32
 
typedef struct {
uintptr_t addr;
size_t size;
char name[CONFIG_TASK_NAME_BUFLEN];
} init_task_t;
 
typedef struct {
count_t cnt;
size_t cnt;
init_task_t tasks[CONFIG_INIT_TASKS];
} init_t;
 
63,14 → 65,14
} ballocs_t;
 
typedef struct {
count_t cpu_count; /**< Number of processors detected. */
volatile count_t cpu_active; /**< Number of processors that are up and running. */
 
size_t cpu_count; /**< Number of processors detected. */
volatile size_t cpu_active; /**< Number of processors that are up and running. */
uintptr_t base;
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */
uintptr_t stack_base; /**< Base adddress of initial stack */
size_t stack_size; /**< Size of initial stack */
uintptr_t stack_base; /**< Base adddress of initial stack */
size_t stack_size; /**< Size of initial stack */
} config_t;
 
extern config_t config;
/branches/arm/kernel/generic/include/proc/scheduler.h
47,7 → 47,7
typedef struct {
SPINLOCK_DECLARE(lock);
link_t rq_head; /**< List of ready threads. */
count_t n; /**< Number of threads in rq_ready. */
size_t n; /**< Number of threads in rq_ready. */
} runq_t;
 
extern atomic_t nrdy;
/branches/arm/kernel/generic/include/proc/task.h
53,7 → 53,10
#include <mm/tlb.h>
#include <proc/scheduler.h>
#include <udebug/udebug.h>
#include <ipc/kbox.h>
 
#define TASK_NAME_BUFLEN 20
 
struct thread;
 
/** Task structure. */
67,8 → 70,8
* threads.
*/
SPINLOCK_DECLARE(lock);
char *name;
 
char name[TASK_NAME_BUFLEN];
/** List of threads contained in this task. */
link_t th_head;
/** Address space. */
96,19 → 99,13
atomic_t active_calls;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
/** Debugging stuff. */
udebug_task_t udebug;
 
/** Kernel answerbox */
answerbox_t kernel_box;
/** Thread used to service kernel answerbox */
struct thread *kb_thread;
/** Kbox thread creation vs. begin of cleanup mutual exclusion */
mutex_t kb_cleanup_lock;
/** True if cleanup of kbox has already started */
bool kb_finished;
/** Kernel answerbox. */
kbox_t kb;
#endif
 
/** Architecture specific task data. */
task_arch_t arch;
147,6 → 144,7
#endif
 
extern unative_t sys_task_get_id(task_id_t *uspace_task_id);
extern unative_t sys_task_set_name(const char *uspace_name, size_t name_len);
 
#endif
 
/branches/arm/kernel/generic/include/proc/program.h
52,12 → 52,14
 
extern void *program_loader;
 
extern void program_create(as_t *as, uintptr_t entry_addr, program_t *p);
extern int program_create_from_image(void *image_addr, program_t *p);
extern int program_create_loader(program_t *p);
extern void program_create(as_t *as, uintptr_t entry_addr, char *name,
program_t *p);
extern int program_create_from_image(void *image_addr, char *name,
program_t *p);
extern int program_create_loader(program_t *p, char *name);
extern void program_ready(program_t *p);
 
extern unative_t sys_program_spawn_loader(int *uspace_phone_id);
extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
 
#endif
 
/branches/arm/kernel/generic/include/proc/thread.h
259,7 → 259,8
extern slab_cache_t *fpu_context_slab;
 
/* Thread syscall prototypes. */
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_exit(int uspace_status);
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
 
/branches/arm/kernel/generic/include/cpu.h
51,18 → 51,18
SPINLOCK_DECLARE(lock);
 
tlb_shootdown_msg_t tlb_messages[TLB_MESSAGE_QUEUE_LEN];
count_t tlb_messages_count;
size_t tlb_messages_count;
context_t saved_context;
 
atomic_t nrdy;
runq_t rq[RQ_COUNT];
volatile count_t needs_relink;
volatile size_t needs_relink;
 
SPINLOCK_DECLARE(timeoutlock);
link_t timeout_active_head;
 
count_t missed_clock_ticks; /**< When system clock loses a tick, it is recorded here
size_t missed_clock_ticks; /**< When system clock loses a tick, it is recorded here
so that clock() can react. This variable is
CPU-local and can be only accessed when interrupts
are disabled. */
/branches/arm/kernel/generic/include/synch/futex.h
49,7 → 49,7
/** Futex hash table link. */
link_t ht_link;
/** Number of tasks that reference this futex. */
count_t refcount;
size_t refcount;
} futex_t;
 
extern void futex_init(void);
/branches/arm/kernel/generic/include/synch/rwlock.h
53,7 → 53,7
*/
mutex_t exclusive;
/** Number of readers in critical section. */
count_t readers_in;
size_t readers_in;
} rwlock_t;
 
#define rwlock_write_lock(rwl) \
/branches/arm/kernel/generic/include/synch/spinlock.h
36,6 → 36,7
#define KERN_SPINLOCK_H_
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <atomic.h>
#include <debug.h>
106,7 → 107,7
extern int printf(const char *, ...);
 
#define DEADLOCK_THRESHOLD 100000000
#define DEADLOCK_PROBE_INIT(pname) count_t pname = 0
#define DEADLOCK_PROBE_INIT(pname) size_t pname = 0
#define DEADLOCK_PROBE(pname, value) \
if ((pname)++ > (value)) { \
(pname) = 0; \
/branches/arm/kernel/generic/include/ddi/irq.h
36,18 → 36,16
#define KERN_IRQ_H_
 
typedef enum {
CMD_MEM_READ_1 = 0,
CMD_MEM_READ_2,
CMD_MEM_READ_4,
CMD_MEM_READ_8,
CMD_MEM_WRITE_1,
CMD_MEM_WRITE_2,
CMD_MEM_WRITE_4,
CMD_MEM_WRITE_8,
CMD_PORT_READ_1,
CMD_PORT_WRITE_1,
CMD_IA64_GETCHAR,
CMD_PPC32_GETCHAR,
CMD_PIO_READ_8 = 1,
CMD_PIO_READ_16,
CMD_PIO_READ_32,
CMD_PIO_WRITE_8,
CMD_PIO_WRITE_16,
CMD_PIO_WRITE_32,
CMD_BTEST,
CMD_PREDICATE,
CMD_ACCEPT,
CMD_DECLINE,
CMD_LAST
} irq_cmd_type;
 
54,8 → 52,9
typedef struct {
irq_cmd_type cmd;
void *addr;
unsigned long long value;
int dstarg;
unsigned long long value;
unsigned int srcarg;
unsigned int dstarg;
} irq_cmd_t;
 
typedef struct {
67,8 → 66,10
 
#include <arch/types.h>
#include <adt/list.h>
#include <adt/hash_table.h>
#include <synch/spinlock.h>
#include <proc/task.h>
#include <ipc/ipc.h>
 
typedef enum {
IRQ_DECLINE, /**< Decline to service. */
81,8 → 82,11
} irq_trigger_t;
 
struct irq;
typedef void (* irq_handler_t)(struct irq *irq, void *arg, ...);
typedef void (* irq_handler_t)(struct irq *);
 
/** Type for function used to clear the interrupt. */
typedef void (* cir_t)(void *, inr_t);
 
/** IPC notification config structure.
*
* Primarily, this structure is encapsulated in the irq_t structure.
95,10 → 99,12
answerbox_t *answerbox;
/** Method to be used for the notification. */
unative_t method;
/** Arguments that will be sent if the IRQ is claimed. */
unative_t scratch[IPC_CALL_LEN];
/** Top-half pseudocode. */
irq_code_t *code;
/** Counter. */
count_t counter;
size_t counter;
/**
* Link between IRQs that are notifying the same answerbox. The list is
* protected by the answerbox irq_lock.
138,22 → 144,29
/** Trigger level of the IRQ. */
irq_trigger_t trigger;
/** Claim ownership of the IRQ. */
irq_ownership_t (* claim)(void);
irq_ownership_t (* claim)(struct irq *);
/** Handler for this IRQ and device. */
irq_handler_t handler;
/** Argument for the handler. */
void *arg;
/** Instance argument for the handler and the claim function. */
void *instance;
 
/** Clear interrupt routine. */
cir_t cir;
/** First argument to the clear interrupt routine. */
void *cir_arg;
 
/** Notification configuration structure. */
ipc_notif_cfg_t notif_cfg;
} irq_t;
 
extern void irq_init(count_t inrs, count_t chains);
extern void irq_initialize(irq_t *irq);
extern void irq_register(irq_t *irq);
extern irq_t *irq_dispatch_and_lock(inr_t inr);
extern irq_t *irq_find_and_lock(inr_t inr, devno_t devno);
SPINLOCK_EXTERN(irq_uspace_hash_table_lock);
extern hash_table_t irq_uspace_hash_table;
 
extern void irq_init(size_t, size_t);
extern void irq_initialize(irq_t *);
extern void irq_register(irq_t *);
extern irq_t *irq_dispatch_and_lock(inr_t);
 
#endif
 
#endif
/branches/arm/kernel/generic/include/ddi/device.h
39,6 → 39,7
#include <typedefs.h>
 
extern devno_t device_assign_devno(void);
extern unative_t sys_device_assign_devno(void);
 
#endif
 
/branches/arm/kernel/generic/include/ddi/ddi.h
38,13 → 38,14
#include <ddi/ddi_arg.h>
#include <arch/types.h>
#include <proc/task.h>
#include <adt/list.h>
 
/** Structure representing contiguous physical memory area. */
typedef struct {
uintptr_t pbase; /**< Physical base of the area. */
uintptr_t vbase; /**< Virtual base of the area. */
count_t frames; /**< Number of frames in the area. */
bool cacheable; /**< Cacheability. */
uintptr_t pbase; /**< Physical base of the area. */
pfn_t frames; /**< Number of frames in the area. */
link_t link; /**< Linked list link */
} parea_t;
 
extern void ddi_init(void);
/branches/arm/kernel/generic/include/console/chardev.h
39,41 → 39,63
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
#define CHARDEV_BUFLEN 512
#define INDEV_BUFLEN 512
 
struct chardev;
struct indev;
 
/* Character device operations interface. */
/* Input character device operations interface. */
typedef struct {
/** Suspend pushing characters. */
void (* suspend)(struct chardev *);
/** Resume pushing characters. */
void (* resume)(struct chardev *);
/** Write character to stream. */
void (* write)(struct chardev *, char c);
/** Read character directly from device, assume interrupts disabled. */
char (* read)(struct chardev *);
} chardev_operations_t;
wchar_t (* poll)(struct indev *);
} indev_operations_t;
 
/** Character input device. */
typedef struct chardev {
typedef struct indev {
char *name;
waitq_t wq;
waitq_t wq;
/** Protects everything below. */
SPINLOCK_DECLARE(lock);
uint8_t buffer[CHARDEV_BUFLEN];
count_t counter;
/** Implementation of chardev operations. */
chardev_operations_t *op;
index_t index;
SPINLOCK_DECLARE(lock);
wchar_t buffer[INDEV_BUFLEN];
size_t counter;
/** Implementation of indev operations. */
indev_operations_t *op;
size_t index;
void *data;
} chardev_t;
} indev_t;
 
extern void chardev_initialize(char *name, chardev_t *chardev,
chardev_operations_t *op);
extern void chardev_push_character(chardev_t *chardev, uint8_t ch);
 
struct outdev;
 
/* Output character device operations interface. */
typedef struct {
/** Write character to output. */
void (* write)(struct outdev *, wchar_t, bool);
} outdev_operations_t;
 
/** Character input device. */
typedef struct outdev {
char *name;
/** Protects everything below. */
SPINLOCK_DECLARE(lock);
/** Implementation of outdev operations. */
outdev_operations_t *op;
void *data;
} outdev_t;
 
extern void indev_initialize(char *name, indev_t *indev,
indev_operations_t *op);
extern void indev_push_character(indev_t *indev, wchar_t ch);
extern wchar_t indev_pop_character(indev_t *indev);
 
extern void outdev_initialize(char *name, outdev_t *outdev,
outdev_operations_t *op);
 
extern bool check_poll(indev_t *indev);
 
#endif /* KERN_CHARDEV_H_ */
 
/** @}
/branches/arm/kernel/generic/include/console/kconsole.h
37,9 → 37,10
 
#include <adt/list.h>
#include <synch/spinlock.h>
#include <ipc/irq.h>
 
#define MAX_CMDLINE 256
#define KCONSOLE_HISTORY 10
#define MAX_CMDLINE 256
#define KCONSOLE_HISTORY 10
 
typedef enum {
ARG_TYPE_INVALID = 0,
46,7 → 47,7
ARG_TYPE_INT,
ARG_TYPE_STRING,
/** Variable type - either symbol or string. */
ARG_TYPE_VAR
ARG_TYPE_VAR
} cmd_arg_type_t;
 
/** Structure representing one argument of kconsole command line. */
76,7 → 77,7
/** Function implementing the command. */
int (* func)(cmd_arg_t *);
/** Number of arguments. */
count_t argc;
size_t argc;
/** Argument vector. */
cmd_arg_t *argv;
/** Function for printing detailed help. */
83,13 → 84,19
void (* help)(void);
} cmd_info_t;
 
extern bool kconsole_notify;
extern irq_t kconsole_irq;
 
SPINLOCK_EXTERN(cmd_lock);
extern link_t cmd_head;
 
extern void kconsole_init(void);
extern void kconsole(void *prompt);
extern void kconsole_notify_init(void);
extern bool kconsole_check_poll(void);
extern void kconsole(char *prompt, char *msg, bool kcon);
extern void kconsole_thread(void *data);
 
extern int cmd_register(cmd_info_t *cmd);
extern bool cmd_register(cmd_info_t *cmd);
 
#endif
 
/branches/arm/kernel/generic/include/console/console.h
38,17 → 38,26
#include <arch/types.h>
#include <console/chardev.h>
 
extern chardev_t *stdin;
extern chardev_t *stdout;
extern indev_t *stdin;
extern outdev_t *stdout;
extern bool silent;
 
extern indev_t *stdin_wire(void);
extern void console_init(void);
 
extern void klog_init(void);
extern void klog_update(void);
 
extern uint8_t getc(chardev_t *chardev);
uint8_t _getc(chardev_t *chardev);
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
extern void putchar(char c);
extern wchar_t getc(indev_t *indev);
extern size_t gets(indev_t *indev, char *buf, size_t buflen);
extern unative_t sys_klog(int fd, const void *buf, size_t size);
 
extern void grab_console(void);
extern void release_console(void);
 
extern unative_t sys_debug_enable_console(void);
extern unative_t sys_debug_disable_console(void);
 
extern void arch_grab_console(void);
extern void arch_release_console(void);
 
/branches/arm/kernel/generic/include/arch.h
56,7 → 56,7
* the base address of the stack.
*/
typedef struct {
count_t preemption_disabled; /**< Preemption disabled counter. */
size_t preemption_disabled; /**< Preemption disabled counter. */
thread_t *thread; /**< Current thread. */
task_t *task; /**< Current task. */
cpu_t *cpu; /**< Executing cpu. */
63,12 → 63,11
as_t *as; /**< Current address space. */
} the_t;
 
#define THE ((the_t *)(get_stack_base()))
#define THE ((the_t * )(get_stack_base()))
 
extern void the_initialize(the_t *the);
extern void the_copy(the_t *src, the_t *dst);
 
extern void arch_pre_main(void);
extern void arch_pre_mm_init(void);
extern void arch_post_mm_init(void);
extern void arch_post_cpu_init(void);
79,6 → 78,7
 
extern void reboot(void);
extern void arch_reboot(void);
extern void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller);
 
#endif
 
/branches/arm/kernel/generic/include/adt/hash_table.h
47,7 → 47,7
*
* @return Index into hash table.
*/
index_t (* hash)(unative_t key[]);
size_t (* hash)(unative_t key[]);
/** Hash table item comparison function.
*
56,7 → 56,7
*
* @return true if the keys match, false otherwise.
*/
bool (*compare)(unative_t key[], count_t keys, link_t *item);
bool (*compare)(unative_t key[], size_t keys, link_t *item);
 
/** Hash table item removal callback.
*
68,8 → 68,8
/** Hash table structure. */
typedef struct {
link_t *entry;
count_t entries;
count_t max_keys;
size_t entries;
size_t max_keys;
hash_table_operations_t *op;
} hash_table_t;
 
76,11 → 76,11
#define hash_table_get_instance(item, type, member) \
list_get_instance((item), type, member)
 
extern void hash_table_create(hash_table_t *h, count_t m, count_t max_keys,
extern void hash_table_create(hash_table_t *h, size_t m, size_t max_keys,
hash_table_operations_t *op);
extern void hash_table_insert(hash_table_t *h, unative_t key[], link_t *item);
extern link_t *hash_table_find(hash_table_t *h, unative_t key[]);
extern void hash_table_remove(hash_table_t *h, unative_t key[], count_t keys);
extern void hash_table_remove(hash_table_t *h, unative_t key[], size_t keys);
 
#endif
 
/branches/arm/kernel/generic/include/adt/bitmap.h
41,14 → 41,23
 
typedef struct {
uint8_t *map;
count_t bits;
size_t bits;
} bitmap_t;
 
extern void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, count_t bits);
extern void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits);
extern void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits);
extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits);
extern void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, size_t bits);
extern void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t bits);
extern void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t bits);
extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t bits);
 
static inline int bitmap_get(bitmap_t *bitmap, size_t bit)
{
if(bit >= bitmap->bits)
return 0;
return !! ((bitmap->map)[bit/8] & (1 << (bit & 7)));
}
 
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/adt/btree.h
46,7 → 46,7
/** B-tree node structure. */
typedef struct btree_node {
/** Number of keys. */
count_t keys;
size_t keys;
 
/**
* Keys. We currently support only single keys. Additional room for one
/branches/arm/kernel/generic/include/adt/fifo.h
59,9 → 59,9
#define FIFO_INITIALIZE_STATIC(name, t, itms) \
struct { \
t fifo[(itms)]; \
count_t items; \
index_t head; \
index_t tail; \
size_t items; \
size_t head; \
size_t tail; \
} name = { \
.items = (itms), \
.head = 0, \
80,9 → 80,9
#define FIFO_INITIALIZE_DYNAMIC(name, t, itms) \
struct { \
t *fifo; \
count_t items; \
index_t head; \
index_t tail; \
size_t items; \
size_t head; \
size_t tail; \
} name = { \
.fifo = NULL, \
.items = (itms), \
/branches/arm/kernel/generic/include/mm/frame.h
38,34 → 38,82
 
#include <arch/types.h>
#include <adt/list.h>
#include <mm/buddy.h>
#include <synch/spinlock.h>
#include <mm/buddy.h>
#include <arch/mm/page.h>
#include <arch/mm/frame.h>
 
#define ONE_FRAME 0
#define TWO_FRAMES 1
#define FOUR_FRAMES 2
#define ONE_FRAME 0
#define TWO_FRAMES 1
#define FOUR_FRAMES 2
 
 
#ifdef ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#else
#define STACK_FRAMES ONE_FRAME
#define STACK_FRAMES ONE_FRAME
#endif
 
/** Maximum number of zones in system. */
#define ZONES_MAX 16
/** Maximum number of zones in the system. */
#define ZONES_MAX 32
 
/** Convert the frame address to kernel va. */
#define FRAME_KA 0x1
typedef uint8_t frame_flags_t;
 
/** Convert the frame address to kernel VA. */
#define FRAME_KA 0x01
/** Do not panic and do not sleep on failure. */
#define FRAME_ATOMIC 0x2
#define FRAME_ATOMIC 0x02
/** Do not start reclaiming when no free memory. */
#define FRAME_NO_RECLAIM 0x4
/** Do not allocate above 4 GiB. */
#define FRAME_LOW_4_GiB 0x8
#define FRAME_NO_RECLAIM 0x04
 
typedef uint8_t zone_flags_t;
 
/** Available zone (free for allocation) */
#define ZONE_AVAILABLE 0x00
/** Zone is reserved (not available for allocation) */
#define ZONE_RESERVED 0x08
/** Zone is used by firmware (not available for allocation) */
#define ZONE_FIRMWARE 0x10
 
/** Currently there is no equivalent zone flags
for frame flags */
#define FRAME_TO_ZONE_FLAGS(frame_flags) 0
 
typedef struct {
size_t refcount; /**< Tracking of shared frames */
uint8_t buddy_order; /**< Buddy system block order */
link_t buddy_link; /**< Link to the next free block inside
one order */
void *parent; /**< If allocated by slab, this points there */
} frame_t;
 
typedef struct {
pfn_t base; /**< Frame_no of the first frame
in the frames array */
size_t count; /**< Size of zone */
size_t free_count; /**< Number of free frame_t
structures */
size_t busy_count; /**< Number of busy frame_t
structures */
zone_flags_t flags; /**< Type of the zone */
frame_t *frames; /**< Array of frame_t structures
in this zone */
buddy_system_t *buddy_system; /**< Buddy system for the zone */
} zone_t;
 
/*
* The zoneinfo.lock must be locked when accessing zoneinfo structure.
* Some of the attributes in zone_t structures are 'read-only'
*/
typedef struct {
SPINLOCK_DECLARE(lock);
size_t count;
zone_t info[ZONES_MAX];
} zones_t;
 
extern zones_t zones;
 
static inline uintptr_t PFN2ADDR(pfn_t frame)
{
return (uintptr_t) (frame << FRAME_WIDTH);
76,43 → 124,49
return (pfn_t) (addr >> FRAME_WIDTH);
}
 
static inline count_t SIZE2FRAMES(size_t size)
static inline size_t SIZE2FRAMES(size_t size)
{
if (!size)
return 0;
return (count_t) ((size - 1) >> FRAME_WIDTH) + 1;
return (size_t) ((size - 1) >> FRAME_WIDTH) + 1;
}
 
static inline size_t FRAMES2SIZE(count_t frames)
static inline size_t FRAMES2SIZE(size_t frames)
{
return (size_t) (frames << FRAME_WIDTH);
}
 
#define IS_BUDDY_ORDER_OK(index, order) \
static inline bool zone_flags_available(zone_flags_t flags)
{
return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);
}
 
#define IS_BUDDY_ORDER_OK(index, order) \
((~(((unative_t) -1) << (order)) & (index)) == 0)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
 
#define frame_alloc(order, flags) \
#define frame_alloc(order, flags) \
frame_alloc_generic(order, flags, NULL)
 
extern void frame_init(void);
extern void *frame_alloc_generic(uint8_t, int, unsigned int *);
extern void *frame_alloc_generic(uint8_t, frame_flags_t, size_t *);
extern void frame_free(uintptr_t);
extern void frame_reference_add(pfn_t);
 
extern int zone_create(pfn_t, count_t, pfn_t, int);
extern void *frame_get_parent(pfn_t, unsigned int);
extern void frame_set_parent(pfn_t, void *, unsigned int);
extern void frame_mark_unavailable(pfn_t, count_t);
extern uintptr_t zone_conf_size(count_t);
extern void zone_merge(unsigned int, unsigned int);
extern size_t find_zone(pfn_t frame, size_t count, size_t hint);
extern size_t zone_create(pfn_t, size_t, pfn_t, zone_flags_t);
extern void *frame_get_parent(pfn_t, size_t);
extern void frame_set_parent(pfn_t, void *, size_t);
extern void frame_mark_unavailable(pfn_t, size_t);
extern uintptr_t zone_conf_size(size_t);
extern bool zone_merge(size_t, size_t);
extern void zone_merge_all(void);
extern uint64_t zone_total_size(void);
 
120,7 → 174,7
* Console functions
*/
extern void zone_print_list(void);
extern void zone_print_one(unsigned int);
extern void zone_print_one(size_t);
 
#endif
 
/branches/arm/kernel/generic/include/mm/slab.h
41,40 → 41,40
#include <mm/frame.h>
 
/** Minimum size to be allocated by malloc */
#define SLAB_MIN_MALLOC_W 4
#define SLAB_MIN_MALLOC_W 4
 
/** Maximum size to be allocated by malloc */
#define SLAB_MAX_MALLOC_W 18
#define SLAB_MAX_MALLOC_W 22
 
/** Initial Magazine size (TODO: dynamically growing magazines) */
#define SLAB_MAG_SIZE 4
 
/** If object size is less, store control structure inside SLAB */
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
 
/** Maximum wasted space we allow for cache */
#define SLAB_MAX_BADNESS(cache) \
#define SLAB_MAX_BADNESS(cache) \
(((unsigned int) PAGE_SIZE << (cache)->order) >> 2)
 
/* slab_reclaim constants */
 
/** Reclaim all possible memory, because we are in memory stress */
#define SLAB_RECLAIM_ALL 0x1
#define SLAB_RECLAIM_ALL 0x01
 
/* cache_create flags */
 
/** Do not use per-cpu cache */
#define SLAB_CACHE_NOMAGAZINE 0x1
#define SLAB_CACHE_NOMAGAZINE 0x01
/** Have control structure inside SLAB */
#define SLAB_CACHE_SLINSIDE 0x2
#define SLAB_CACHE_SLINSIDE 0x02
/** We add magazine cache later, if we have this flag */
#define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE)
#define SLAB_CACHE_MAGDEFERRED (0x04 | SLAB_CACHE_NOMAGAZINE)
 
typedef struct {
link_t link;
count_t busy; /**< Count of full slots in magazine */
count_t size; /**< Number of slots in magazine */
void *objs[]; /**< Slots in magazine */
size_t busy; /**< Count of full slots in magazine */
size_t size; /**< Number of slots in magazine */
void *objs[]; /**< Slots in magazine */
} slab_magazine_t;
 
typedef struct {
86,23 → 86,23
 
typedef struct {
char *name;
 
link_t link;
 
/* Configuration */
/** Size of slab position - align_up(sizeof(obj)) */
size_t size;
 
int (*constructor)(void *obj, int kmflag);
int (*destructor)(void *obj);
 
/** Flags changing behaviour of cache */
int flags;
 
/* Computed values */
uint8_t order; /**< Order of frames to be allocated */
unsigned int objects; /**< Number of objects that fit in */
 
uint8_t order; /**< Order of frames to be allocated */
unsigned int objects; /**< Number of objects that fit in */
/* Statistics */
atomic_t allocated_slabs;
atomic_t allocated_objs;
109,15 → 109,15
atomic_t cached_objs;
/** How many magazines in magazines list */
atomic_t magazine_counter;
 
/* Slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
SPINLOCK_DECLARE(slablock);
/* Magazines */
link_t magazines; /**< List o full magazines */
/* Magazines */
link_t magazines; /**< List o full magazines */
SPINLOCK_DECLARE(maglock);
 
/** CPU cache */
slab_mag_cache_t *mag_cache;
} slab_cache_t;
128,7 → 128,7
 
extern void * slab_alloc(slab_cache_t *, int);
extern void slab_free(slab_cache_t *, void *);
extern count_t slab_reclaim(int);
extern size_t slab_reclaim(int);
 
/* slab subsytem initialization */
extern void slab_cache_init(void);
141,6 → 141,7
extern void *malloc(unsigned int, int);
extern void *realloc(void *, unsigned int, int);
extern void free(void *);
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/mm/tlb.h
61,7 → 61,7
tlb_invalidate_type_t type; /**< Message type. */
asid_t asid; /**< Address space identifier. */
uintptr_t page; /**< Page address. */
count_t count; /**< Number of pages to invalidate. */
size_t count; /**< Number of pages to invalidate. */
} tlb_shootdown_msg_t;
 
extern void tlb_init(void);
68,7 → 68,7
 
#ifdef CONFIG_SMP
extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
uintptr_t page, count_t count);
uintptr_t page, size_t count);
extern void tlb_shootdown_finalize(void);
extern void tlb_shootdown_ipi_recv(void);
#else
84,7 → 84,7
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_asid(asid_t asid);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt);
#endif
 
/** @}
/branches/arm/kernel/generic/include/mm/as.h
94,7 → 94,7
* Number of processors on wich is this address space active.
* Protected by asidlock.
*/
count_t cpu_refcount;
size_t cpu_refcount;
/**
* Address space identifier.
* Constant on architectures that do not support ASIDs.
132,7 → 132,7
/** This lock must be acquired only when the as_area lock is held. */
mutex_t lock;
/** This structure can be deallocated if refcount drops to 0. */
count_t refcount;
size_t refcount;
/**
* B+tree containing complete map of anonymous pages of the shared area.
*/
156,7 → 156,7
};
struct { /**< phys_backend members */
uintptr_t base;
count_t frames;
size_t frames;
};
} mem_backend_data_t;
 
175,7 → 175,7
/** Attributes related to the address space area itself. */
int attributes;
/** Size of this area in multiples of PAGE_SIZE. */
count_t pages;
size_t pages;
/** Base address of this area. */
uintptr_t base;
/** Map of used space. */
225,8 → 225,8
extern int as_area_get_flags(as_area_t *area);
extern bool as_area_check_access(as_area_t *area, pf_access_t access);
extern size_t as_area_get_size(uintptr_t base);
extern int used_space_insert(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_insert(as_area_t *a, uintptr_t page, size_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, size_t count);
 
 
/* Interface to be implemented by architectures. */
/branches/arm/kernel/generic/include/mm/page.h
42,7 → 42,7
/** Operations to manipulate page mappings. */
typedef struct {
void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame,
int flags);
int flags);
void (* mapping_remove)(as_t *as, uintptr_t page);
pte_t *(* mapping_find)(as_t *as, uintptr_t page);
} page_mapping_operations_t;
59,6 → 59,7
extern pte_t *page_table_create(int flags);
extern void page_table_destroy(pte_t *page_table);
extern void map_structure(uintptr_t s, size_t size);
 
extern uintptr_t hw_map(uintptr_t physaddr, size_t size);
 
#endif
/branches/arm/kernel/generic/include/mm/buddy.h
82,7 → 82,7
extern link_t *buddy_system_alloc(buddy_system_t *, uint8_t);
extern bool buddy_system_can_alloc(buddy_system_t *, uint8_t);
extern void buddy_system_free(buddy_system_t *, link_t *);
extern size_t buddy_conf_size(int);
extern size_t buddy_conf_size(size_t);
extern link_t *buddy_system_alloc_block(buddy_system_t *, link_t *);
 
#endif
/branches/arm/kernel/generic/include/ipc/event.h
0,0 → 1,79
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef KERN_EVENT_H_
#define KERN_EVENT_H_
 
#include <ipc/event_types.h>
#include <arch/types.h>
#include <synch/spinlock.h>
#include <ipc/ipc.h>
 
/** Event notification structure. */
typedef struct {
SPINLOCK_DECLARE(lock);
/** Answerbox for notifications. */
answerbox_t *answerbox;
/** Method to be used for the notification. */
unative_t method;
/** Counter. */
size_t counter;
} event_t;
 
extern void event_init(void);
extern unative_t sys_event_subscribe(unative_t, unative_t);
extern bool event_is_subscribed(event_type_t);
extern void event_cleanup_answerbox(answerbox_t *);
 
#define event_notify_0(e) \
event_notify((e), 0, 0, 0, 0, 0)
#define event_notify_1(e, a1) \
event_notify((e), (a1), 0, 0, 0, 0)
#define event_notify_2(e, a1, a2) \
event_notify((e), (a1), (a2), 0, 0, 0)
#define event_notify_3(e, a1, a2, a3) \
event_notify((e), (a1), (a2), (a3), 0, 0)
#define event_notify_4(e, a1, a2, a3, a4) \
event_notify((e), (a1), (a2), (a3), (a4), 0)
#define event_notify_5(e, a1, a2, a3, a4, a5) \
event_notify((e), (a1), (a2), (a3), (a4), (a5))
 
extern void event_notify(event_type_t, unative_t, unative_t, unative_t,
unative_t, unative_t);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/generic/include/ipc/event_types.h
0,0 → 1,53
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup generic
* @{
*/
/** @file
*/
 
#ifndef KERN_EVENT_TYPES_H_
#define KERN_EVENT_TYPES_H_
 
typedef enum event_type {
EVENT_KLOG = 0,
EVENT_KCONSOLE,
EVENT_WAIT,
EVENT_END
} event_type_t;
 
typedef enum wait_type {
TASK_CREATE = 0,
TASK_DESTROY
} wait_type_t;
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/generic/include/ipc/ipc.h
111,6 → 111,25
/* System-specific methods - only through special syscalls
* These methods have special behaviour
*/
/** Clone connection.
*
* The calling task clones one of its phones for the callee.
*
* - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
* - The callee gets the new phone from ARG1.
* - on answer, the callee acknowledges the new connection by sending EOK back
* or the kernel closes it
*/
#define IPC_M_CONNECTION_CLONE 1
/** Protocol for CONNECT - ME
*
* Through this call, the recipient learns about the new cloned connection.
*
* - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
* - on asnwer, the callee acknowledges the new connection by sending EOK back
* or the kernel closes it
*/
#define IPC_M_CONNECT_ME 2
/** Protocol for CONNECT - TO - ME
*
* Calling process asks the callee to create a callback connection,
127,7 → 146,7
* - the allocated phoneid is passed to userspace
* (on the receiving side) as ARG5 of the call.
*/
#define IPC_M_CONNECT_TO_ME 1
#define IPC_M_CONNECT_TO_ME 3
/** Protocol for CONNECT - ME - TO
*
* Calling process asks the callee to create for him a new connection.
145,11 → 164,11
* - recepient may forward message.
*
*/
#define IPC_M_CONNECT_ME_TO 2
#define IPC_M_CONNECT_ME_TO 4
/** This message is sent to answerbox when the phone
* is hung up
*/
#define IPC_M_PHONE_HUNGUP 3
#define IPC_M_PHONE_HUNGUP 5
 
/** Send as_area over IPC.
* - ARG1 - source as_area base address
159,7 → 178,7
* on answer, the recipient must set:
* - ARG1 - dst as_area base adress
*/
#define IPC_M_SHARE_OUT 4
#define IPC_M_SHARE_OUT 6
 
/** Receive as_area over IPC.
* - ARG1 - destination as_area base address
171,7 → 190,7
* - ARG1 - source as_area base address
* - ARG2 - flags that will be used for sharing
*/
#define IPC_M_SHARE_IN 5
#define IPC_M_SHARE_IN 7
 
/** Send data to another address space over IPC.
* - ARG1 - source address space virtual address
182,7 → 201,7
* - ARG1 - final destination address space virtual address
* - ARG2 - final size of data to be copied
*/
#define IPC_M_DATA_WRITE 6
#define IPC_M_DATA_WRITE 8
 
/** Receive data from another address space over IPC.
* - ARG1 - destination virtual address in the source address space
193,13 → 212,13
* - ARG1 - source virtual address in the destination address space
* - ARG2 - final size of data to be copied
*/
#define IPC_M_DATA_READ 7
#define IPC_M_DATA_READ 9
 
/** Debug the recipient.
* - ARG1 - specifies the debug method (from udebug_method_t)
* - other arguments are specific to the debug method
*/
#define IPC_M_DEBUG_ALL 8
#define IPC_M_DEBUG_ALL 10
 
/* Well-known methods */
#define IPC_M_LAST_SYSTEM 511
/branches/arm/kernel/generic/include/ipc/ipcrsc.h
35,8 → 35,11
#ifndef KERN_IPCRSC_H_
#define KERN_IPCRSC_H_
 
#include <proc/task.h>
#include <ipc/ipc.h>
 
extern call_t * get_call(unative_t callid);
extern int phone_alloc(void);
extern int phone_alloc(task_t *t);
extern void phone_connect(int phoneid, answerbox_t *box);
extern void phone_dealloc(int phoneid);
 
/branches/arm/kernel/generic/include/ipc/irq.h
36,7 → 36,7
#define KERN_IPC_IRQ_H_
 
/** Maximum length of IPC IRQ program */
#define IRQ_MAX_PROG_SIZE 10
#define IRQ_MAX_PROG_SIZE 20
 
#include <ipc/ipc.h>
#include <ddi/irq.h>
43,16 → 43,21
#include <arch/types.h>
#include <adt/list.h>
 
extern int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno,
unative_t method, irq_code_t *ucode);
extern void ipc_irq_send_notif(irq_t *irq);
extern void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno);
extern void ipc_irq_cleanup(answerbox_t *box);
extern int ipc_irq_register(answerbox_t *, inr_t, devno_t, unative_t,
irq_code_t *);
 
extern irq_ownership_t ipc_irq_top_half_claim(irq_t *);
extern void ipc_irq_top_half_handler(irq_t *);
 
extern int ipc_irq_unregister(answerbox_t *, inr_t, devno_t);
extern void ipc_irq_cleanup(answerbox_t *);
 
/*
* User friendly wrappers for ipc_irq_send_msg(). They are in the form
* ipc_irq_send_msg_m(), where m is the number of payload arguments.
*/
#define ipc_irq_send_msg_0(irq) \
ipc_irq_send_msg((irq), 0, 0, 0, 0, 0)
#define ipc_irq_send_msg_1(irq, a1) \
ipc_irq_send_msg((irq), (a1), 0, 0, 0, 0)
#define ipc_irq_send_msg_2(irq, a1, a2) \
64,8 → 69,8
#define ipc_irq_send_msg_5(irq, a1, a2, a3, a4, a5) \
ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), (a5))
 
extern void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2,
unative_t a3, unative_t a4, unative_t a5);
extern void ipc_irq_send_msg(irq_t *, unative_t, unative_t, unative_t, unative_t,
unative_t);
 
#endif
 
/branches/arm/kernel/generic/include/ipc/sysipc.h
53,6 → 53,8
int nonblocking);
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, int mode);
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
ipc_data_t *data, int mode);
unative_t sys_ipc_hangup(int phoneid);
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
irq_code_t *ucode);
/branches/arm/kernel/generic/include/ipc/kbox.h
37,6 → 37,18
 
#include <typedefs.h>
 
/** Kernel answerbox structure. */
typedef struct kbox {
/** The answerbox itself. */
answerbox_t box;
/** Thread used to service the answerbox. */
struct thread *thread;
/** Kbox thread creation vs. begin of cleanup mutual exclusion. */
mutex_t cleanup_lock;
/** True if cleanup of kbox has already started. */
bool finished;
} kbox_t;
 
extern int ipc_connect_kbox(task_id_t);
extern void ipc_kbox_cleanup(void);
 
/branches/arm/kernel/generic/include/sort.h
40,8 → 40,8
/*
* sorting routines
*/
extern void bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
 
/*
* default sorting comparators
/branches/arm/kernel/generic/include/macros.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,47 → 35,73
#ifndef KERN_MACROS_H_
#define KERN_MACROS_H_
 
#ifndef __ASM__
 
#include <arch/types.h>
 
#define isdigit(d) (((d) >= '0') && ((d) <= '9'))
#define islower(c) (((c) >= 'a') && ((c) <= 'z'))
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define isalpha(c) (is_lower((c)) || is_upper((c)))
#define isalphanum(c) (is_alpha((c)) || is_digit((c)))
#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || \
((c) == '\r'))
 
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
 
/** Return true if the intervals overlap.
*
* @param s1 Start address of the first interval.
* @param sz1 Size of the first interval.
* @param s2 Start address of the second interval.
* @param sz2 Size of the second interval.
* @param s1 Start address of the first interval.
* @param sz1 Size of the first interval.
* @param s2 Start address of the second interval.
* @param sz2 Size of the second interval.
*/
static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
{
uintptr_t e1 = s1 + sz1;
uintptr_t e2 = s2 + sz2;
 
return (s1 < e2) && (s2 < e1);
return ((s1 < e2) && (s2 < e1));
}
 
#endif /* __ASM__ */
 
#define isdigit(d) (((d) >= '0') && ((d) <= '9'))
#define islower(c) (((c) >= 'a') && ((c) <= 'z'))
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define isalpha(c) (is_lower((c)) || is_upper((c)))
#define isalphanum(c) (is_alpha((c)) || is_digit((c)))
#define isspace(c) \
(((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
#define min3(a, b, c) ((a) < (b) ? (min(a, c)) : (min(b, c)))
#define max3(a, b, c) ((a) > (b) ? (max(a, c)) : (max(b, c)))
 
/* Compute overlapping of physical addresses */
#define PA_overlaps(x, szx, y, szy) \
#define PA_overlaps(x, szx, y, szy) \
overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy))
 
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
 
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
 
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
 
#define LOWER32(arg) ((arg) & 0xffffffff)
#define UPPER32(arg) (((arg) >> 32) & 0xffffffff)
 
#define MERGE_LOUP32(lo, up) \
((((uint64_t) (lo)) & 0xffffffff) \
| ((((uint64_t) (up)) & 0xffffffff) << 32))
 
/** Pseudorandom generator
*
* A pretty standard linear congruential pseudorandom
* number generator (m = 2^32 or 2^64 depending on architecture).
*
*/
#define RANDI(seed) \
({ \
(seed) = 1103515245 * (seed) + 12345; \
(seed); \
})
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/sysinfo/sysinfo.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
36,6 → 36,7
#define KERN_SYSINFO_H_
 
#include <arch/types.h>
#include <string.h>
 
typedef union sysinfo_item_val {
unative_t val;
59,13 → 60,13
int subinfo_type;
} sysinfo_item_t;
 
#define SYSINFO_VAL_VAL 0
#define SYSINFO_VAL_FUNCTION 1
#define SYSINFO_VAL_UNDEFINED '?'
#define SYSINFO_VAL_VAL 0
#define SYSINFO_VAL_FUNCTION 1
#define SYSINFO_VAL_UNDEFINED U_SPECIAL
 
#define SYSINFO_SUBINFO_NONE 0
#define SYSINFO_SUBINFO_TABLE 1
#define SYSINFO_SUBINFO_FUNCTION 2
#define SYSINFO_SUBINFO_NONE 0
#define SYSINFO_SUBINFO_TABLE 1
#define SYSINFO_SUBINFO_FUNCTION 2
 
typedef unative_t (*sysinfo_val_fn_t)(sysinfo_item_t *root);
typedef unative_t (*sysinfo_subinfo_fn_t)(const char *subname);
/branches/arm/kernel/generic/include/printf/printf_core.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,20 → 35,23
#ifndef KERN_PRINTF_CORE_H_
#define KERN_PRINTF_CORE_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/arg.h>
 
/** Structure for specifying output methods for different printf clones. */
struct printf_spec {
/* Output function, returns count of printed characters or EOF */
int (*write)(void *, size_t, void *);
/* Support data - output stream specification, its state, locks,... */
typedef struct {
/* String output function, returns number of printed characters or EOF */
int (*str_write)(const char *, size_t, void *);
/* Wide string output function, returns number of printed characters or EOF */
int (*wstr_write)(const wchar_t *, size_t, void *);
/* User data - output stream specification, state, locks, etc. */
void *data;
} printf_spec_t;
 
};
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
 
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap);
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/print.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
46,11 → 46,9
 
extern int puts(const char *s);
extern int printf(const char *fmt, ...);
extern int sprintf(char *str, const char *fmt, ...);
extern int snprintf(char *str, size_t size, const char *fmt, ...);
 
extern int vprintf(const char *fmt, va_list ap);
extern int vsprintf(char *str, const char *fmt, va_list ap);
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
 
#endif
/branches/arm/kernel/generic/include/putchar.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,7 → 35,7
#ifndef KERN_PUTCHAR_H_
#define KERN_PUTCHAR_H_
 
extern void putchar(const char ch);
extern void putchar(const wchar_t ch);
 
#endif
 
/branches/arm/kernel/generic/include/syscall/syscall.h
44,6 → 44,7
SYS_THREAD_GET_ID,
SYS_TASK_GET_ID,
SYS_TASK_SET_NAME,
SYS_PROGRAM_SPAWN_LOADER,
SYS_FUTEX_SLEEP,
62,14 → 63,18
SYS_IPC_ANSWER_FAST,
SYS_IPC_ANSWER_SLOW,
SYS_IPC_FORWARD_FAST,
SYS_IPC_FORWARD_SLOW,
SYS_IPC_WAIT,
SYS_IPC_HANGUP,
SYS_IPC_REGISTER_IRQ,
SYS_IPC_UNREGISTER_IRQ,
 
SYS_EVENT_SUBSCRIBE,
SYS_CAP_GRANT,
SYS_CAP_REVOKE,
SYS_DEVICE_ASSIGN_DEVNO,
SYS_PHYSMEM_MAP,
SYS_IOSPACE_ENABLE,
SYS_PREEMPT_CONTROL,
78,6 → 83,7
SYS_SYSINFO_VALUE,
SYS_DEBUG_ENABLE_CONSOLE,
SYS_DEBUG_DISABLE_CONSOLE,
SYS_IPC_CONNECT_KBOX,
SYSCALL_END
} syscall_t;
/branches/arm/kernel/generic/include/typedefs.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
51,6 → 51,12
typedef int32_t inr_t;
typedef int32_t devno_t;
 
typedef int32_t wchar_t;
 
typedef volatile uint8_t ioport8_t;
typedef volatile uint16_t ioport16_t;
typedef volatile uint32_t ioport32_t;
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/errno.h
48,15 → 48,18
* sys_ipc_hangup() to close the connection.
* Used by answerbox to close the connection.
*/
#define EEXISTS -8 /* Entry already exists */
#define EBADMEM -9 /* Bad memory pointer */
#define ENOTSUP -10 /* Not supported */
#define EADDRNOTAVAIL -11 /* Address not available. */
#define ETIMEOUT -12 /* Timeout expired */
#define EINVAL -13 /* Invalid value */
#define EBUSY -14 /* Resource is busy */
#define EOVERFLOW -15 /* The result does not fit its size. */
#define EINTR -16 /* Operation was interrupted. */
#define EPARTY -8 /* The other party encountered an error when
* receiving the call.
*/
#define EEXISTS -9 /* Entry already exists */
#define EBADMEM -10 /* Bad memory pointer */
#define ENOTSUP -11 /* Not supported */
#define EADDRNOTAVAIL -12 /* Address not available. */
#define ETIMEOUT -13 /* Timeout expired */
#define EINVAL -14 /* Invalid value */
#define EBUSY -15 /* Resource is busy */
#define EOVERFLOW -16 /* The result does not fit its size. */
#define EINTR -17 /* Operation was interrupted. */
 
#endif
 
/branches/arm/kernel/generic/include/func.h
41,11 → 41,6
extern atomic_t haltstate;
 
extern void halt(void);
 
extern size_t strlen(const char *str);
extern int strcmp(const char *src, const char *dst);
extern int strncmp(const char *src, const char *dst, size_t len);
extern void strncpy(char *dest, const char *src, size_t len);
extern unative_t atoi(const char *text);
extern void order(const uint64_t val, uint64_t *rv, char *suffix);
 
/branches/arm/kernel/generic/include/memstr.h
44,7 → 44,7
extern void *_memcpy(void *dst, const void *src, size_t cnt);
extern void _memsetb(void *dst, size_t cnt, uint8_t x);
extern void _memsetw(void *dst, size_t cnt, uint16_t x);
extern char *strcpy(char *dest, const char *src);
extern void *memmove(void *dst, const void *src, size_t cnt);
 
#endif
 
/branches/arm/kernel/generic/include/main/main.h
35,8 → 35,13
#ifndef KERN_MAIN_H_
#define KERN_MAIN_H_
 
#include <arch/types.h>
 
extern uintptr_t stack_safe;
 
extern void main_bsp(void);
extern void main_ap(void);
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/align.h
26,13 → 26,13
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @ingroup others
* @{
*/
/**
* @file
* @brief Macros for making values and addresses aligned.
* @brief Macros for making values and addresses aligned.
*/
 
#ifndef KERN_ALIGN_H_
43,7 → 43,7
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
 
 
/** Align to the nearest higher address.
51,7 → 51,7
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1))
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1))
 
#endif
 
/branches/arm/kernel/generic/include/fpu_context.h
37,10 → 37,6
 
#include <arch/fpu_context.h>
 
#if defined(CONFIG_FPU_LAZY) && !defined(ARCH_HAS_FPU)
# error "CONFIG_FPU_LAZY defined, but no ARCH_HAS_FPU"
#endif
 
extern void fpu_context_save(fpu_context_t *);
extern void fpu_context_restore(fpu_context_t *);
extern void fpu_init(void);
/branches/arm/kernel/generic/include/interrupt.h
44,12 → 44,12
 
typedef void (* iroutine)(int n, istate_t *istate);
 
#define fault_if_from_uspace(istate, cmd, ...) \
#define fault_if_from_uspace(istate, fmt, ...) \
{ \
if (istate_from_uspace(istate)) { \
task_t *task = TASK; \
printf("Task %" PRIu64 " killed due to an exception at %p.", task->taskid, istate_get_pc(istate)); \
printf(" " cmd, ##__VA_ARGS__); \
printf("Task %s (%" PRIu64 ") killed due to an exception at %p: ", task->name, task->taskid, istate_get_pc(istate)); \
printf(fmt "\n", ##__VA_ARGS__); \
task_kill(task->taskid); \
thread_exit(); \
} \
/branches/arm/kernel/generic/include/debug.h
57,21 → 57,21
#ifdef CONFIG_DEBUG
# define ASSERT(expr) \
if (!(expr)) { \
panic("assertion failed (%s), caller=%p\n", #expr, CALLER); \
panic("Assertion failed (%s), caller=%p.", #expr, CALLER); \
}
#else
# define ASSERT(expr)
#endif
 
/** Extensive debugging output macro
/** Extensive logging output macro
*
* If CONFIG_EDEBUG is set, the LOG() macro
* If CONFIG_LOG is set, the LOG() macro
* will print whatever message is indicated plus
* an information about the location.
*
*/
 
#ifdef CONFIG_EDEBUG
#ifdef CONFIG_LOG
# define LOG(format, ...) \
printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \
__LINE__, ##__VA_ARGS__);
79,15 → 79,15
# define LOG(format, ...)
#endif
 
/** Extensive debugging execute macro
/** Extensive logging execute macro
*
* If CONFIG_EDEBUG is set, the LOG_EXEC() macro
* If CONFIG_LOG is set, the LOG_EXEC() macro
* will print an information about calling a given
* function and call it.
*
*/
 
#ifdef CONFIG_EDEBUG
#ifdef CONFIG_LOG
# define LOG_EXEC(fnc) \
{ \
printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \
/branches/arm/kernel/generic/include/panic.h
37,11 → 37,11
 
#ifdef CONFIG_DEBUG
# define panic(format, ...) \
panic_printf("Kernel panic in %s() at %s:%u: " format, __func__, \
__FILE__, __LINE__, ##__VA_ARGS__);
panic_printf("Kernel panic in %s() at %s:%u: " format "\n", \
__func__, __FILE__, __LINE__, ##__VA_ARGS__);
#else
# define panic(format, ...) \
panic_printf("Kernel panic: " format, ##__VA_ARGS__);
panic_printf("Kernel panic: " format "\n", ##__VA_ARGS__);
#endif
 
extern void panic_printf(char *fmt, ...) __attribute__((noreturn));
/branches/arm/kernel/generic/include/udebug/udebug.h
147,9 → 147,7
/** BEGIN operation in progress (waiting for threads to stop) */
UDEBUG_TS_BEGINNING,
/** Debugger fully connected */
UDEBUG_TS_ACTIVE,
/** Task is shutting down, no more debug activities allowed */
UDEBUG_TS_SHUTDOWN
UDEBUG_TS_ACTIVE
} udebug_task_state_t;
 
/** Debugging part of task_t structure.
169,25 → 167,19
/** Debugging part of thread_t structure.
*/
typedef struct {
/**
* Prevent deadlock with udebug_before_thread_runs() in interrupt
* handler, without actually disabling interrupts.
* ==0 means "unlocked", >0 means "locked"
*/
atomic_t int_lock;
 
/** Synchronize debug ops on this thread / access to this structure */
/** Synchronize debug ops on this thread / access to this structure. */
mutex_t lock;
 
waitq_t go_wq;
call_t *go_call;
unative_t syscall_args[6];
istate_t *uspace_state;
 
/** What type of event are we stopped in or 0 if none */
udebug_event_t cur_event;
bool stop;
bool stoppable;
bool debug_active; /**< In a debugging session */
/** What type of event are we stopped in or 0 if none. */
udebug_event_t cur_event;
bool go; /**< thread is GO */
bool stoppable; /**< thread is stoppable */
bool active; /**< thread is in a debugging session */
} udebug_thread_t;
 
struct task;
200,7 → 192,7
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc,
bool end_variant);
 
void udebug_thread_b_event(struct thread *t);
void udebug_thread_b_event_attach(struct thread *t, struct task *ta);
void udebug_thread_e_event(void);
 
void udebug_stoppable_begin(void);
/branches/arm/kernel/generic/include/stdarg.h
45,7 → 45,7
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dst,src) __builtin_va_copy(dst,src)
#define va_copy(dst, src) __builtin_va_copy(dst, src)
 
#endif
 
/branches/arm/kernel/generic/src/main/uinit.c
79,6 → 79,14
uarg.uspace_thread_arg = NULL;
 
free((uspace_arg_t *) arg);
/*
* Disable interrupts so that the execution of userspace() is not
* disturbed by any interrupts as some of the userspace()
* implementations will switch to the userspace stack before switching
* the mode.
*/
(void) interrupts_disable();
userspace(&uarg);
}
 
/branches/arm/kernel/generic/src/main/kinit.c
32,7 → 32,7
 
/**
* @file
* @brief Kernel initialization thread.
* @brief Kernel initialization thread.
*
* This file contains kinit kernel thread which carries out
* high level system initialization.
64,6 → 64,8
#include <security/cap.h>
#include <lib/rd.h>
#include <ipc/ipc.h>
#include <debug.h>
#include <string.h>
 
#ifdef CONFIG_SMP
#include <smp/smp.h>
72,6 → 74,15
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
#define ALIVE_CHARS 4
 
#ifdef CONFIG_KCONSOLE
static char alive[ALIVE_CHARS] = "-\\|/";
#endif
 
#define INIT_PREFIX "init:"
#define INIT_PREFIX_LEN 5
 
/** Kernel initialization thread.
*
* kinit takes care of higher level kernel
82,16 → 93,19
*/
void kinit(void *arg)
{
thread_t *t;
 
#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE)
thread_t *thread;
#endif
/*
* Detach kinit as nobody will call thread_join_timeout() on it.
*/
thread_detach(THREAD);
 
interrupts_disable();
 
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
waitq_initialize(&ap_completion_wq);
/*
100,78 → 114,90
* not mess together with kcpulb threads.
* Just a beautification.
*/
if ((t = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED,
"kmp", true))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[0];
spinlock_unlock(&t->lock);
thread_ready(t);
thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true);
if (thread != NULL) {
spinlock_lock(&thread->lock);
thread->cpu = &cpus[0];
spinlock_unlock(&thread->lock);
thread_ready(thread);
} else
panic("thread_create/kmp\n");
thread_join(t);
thread_detach(t);
panic("Unable to create kmp thread.");
thread_join(thread);
thread_detach(thread);
}
#endif /* CONFIG_SMP */
/*
* Now that all CPUs are up, we can report what we've found.
*/
cpu_list();
 
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
count_t i;
size_t i;
/*
* For each CPU, create its load balancing thread.
*/
for (i = 0; i < config.cpu_count; i++) {
 
if ((t = thread_create(kcpulb, NULL, TASK,
THREAD_FLAG_WIRED, "kcpulb", true))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[i];
spinlock_unlock(&t->lock);
thread_ready(t);
thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true);
if (thread != NULL) {
spinlock_lock(&thread->lock);
thread->cpu = &cpus[i];
spinlock_unlock(&thread->lock);
thread_ready(thread);
} else
panic("thread_create/kcpulb\n");
 
printf("Unable to create kcpulb thread for cpu" PRIs "\n", i);
}
}
#endif /* CONFIG_SMP */
 
/*
* At this point SMP, if present, is configured.
*/
arch_post_smp_init();
 
/*
* Create kernel console.
*/
t = thread_create(kconsole, (void *) "kconsole", TASK, 0, "kconsole",
false);
if (t)
thread_ready(t);
else
panic("thread_create/kconsole\n");
 
#ifdef CONFIG_KCONSOLE
if (stdin) {
/*
* Create kernel console.
*/
thread = thread_create(kconsole_thread, NULL, TASK, 0, "kconsole", false);
if (thread != NULL)
thread_ready(thread);
else
printf("Unable to create kconsole thread\n");
}
#endif /* CONFIG_KCONSOLE */
interrupts_enable();
/*
* Create user tasks, load RAM disk images.
*/
count_t i;
size_t i;
program_t programs[CONFIG_INIT_TASKS];
for (i = 0; i < init.cnt; i++) {
if (init.tasks[i].addr % FRAME_SIZE) {
printf("init[%" PRIc "].addr is not frame aligned", i);
printf("init[%" PRIs "].addr is not frame aligned\n", i);
continue;
}
/*
* Construct task name from the 'init:' prefix and the
* name stored in the init structure (if any).
*/
char namebuf[TASK_NAME_BUFLEN];
char *name;
name = init.tasks[i].name;
if (name[0] == 0)
name = "<unknown>";
ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN);
str_cpy(namebuf, TASK_NAME_BUFLEN, INIT_PREFIX);
str_cpy(namebuf + INIT_PREFIX_LEN,
TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name);
 
int rc = program_create_from_image((void *) init.tasks[i].addr,
&programs[i]);
 
if (rc == 0 && programs[i].task != NULL) {
namebuf, &programs[i]);
if ((rc == 0) && (programs[i].task != NULL)) {
/*
* Set capabilities to init userspace tasks.
*/
184,31 → 210,34
/* It was the program loader and was registered */
} else {
/* RAM disk image */
int rd = init_rd((rd_header_t *) init.tasks[i].addr,
init.tasks[i].size);
int rd = init_rd((rd_header_t *) init.tasks[i].addr, init.tasks[i].size);
if (rd != RE_OK)
printf("Init binary %" PRIc " not used, error "
"code %d.\n", i, rd);
printf("Init binary %" PRIs " not used (error %d)\n", i, rd);
}
}
/*
* Run user tasks with reasonable delays
* Run user tasks.
*/
for (i = 0; i < init.cnt; i++) {
if (programs[i].task != NULL) {
thread_usleep(50000);
if (programs[i].task != NULL)
program_ready(&programs[i]);
}
}
 
#ifdef CONFIG_KCONSOLE
if (!stdin) {
while (1) {
thread_sleep(10);
printf("kinit: No stdin\nKernel alive: .");
unsigned int i = 0;
while (true) {
printf("\b%c", alive[i % ALIVE_CHARS]);
thread_sleep(1);
printf("kinit... ");
i++;
}
}
#endif /* CONFIG_KCONSOLE */
}
 
/** @}
/branches/arm/kernel/generic/src/main/main.c
32,7 → 32,7
 
/**
* @file
* @brief Main initialization kernel function for all processors.
* @brief Main initialization kernel function for all processors.
*
* During kernel boot, all processors, after architecture dependent
* initialization, start executing code found in this file. After
81,8 → 81,9
#include <adt/btree.h>
#include <smp/smp.h>
#include <ddi/ddi.h>
#include <main/main.h>
#include <ipc/event.h>
 
 
/** Global configuration structure. */
config_t config;
 
105,18 → 106,15
* appropriate sizes and addresses.
*/
 
/**< Virtual address of where the kernel is loaded. */
/** Virtual address of where the kernel is loaded. */
uintptr_t hardcoded_load_address = 0;
/**< Size of the kernel code in bytes. */
/** Size of the kernel code in bytes. */
size_t hardcoded_ktext_size = 0;
/**< Size of the kernel data in bytes. */
/** Size of the kernel data in bytes. */
size_t hardcoded_kdata_size = 0;
/**< Lowest safe stack virtual address. */
/** Lowest safe stack virtual address. */
uintptr_t stack_safe = 0;
 
void main_bsp(void);
void main_ap(void);
 
/*
* These two functions prevent stack from underflowing during the
* kernel boot phase when SP is set to the very top of the reserved
155,7 → 153,7
config.stack_base = config.base + config.kernel_size;
/* Avoid placing stack on top of init */
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++) {
if (PA_overlaps(config.stack_base, config.stack_size,
init.tasks[i].addr, init.tasks[i].size))
191,8 → 189,6
{
/* Keep this the first thing. */
the_initialize(THE);
 
LOG();
version_print();
201,7 → 197,7
config.base, config.kernel_size, config.stack_base,
config.stack_size);
 
#ifdef CONFIG_KCONSOLE
/*
* kconsole data structures must be initialized very early
* because other subsystems will register their respective
208,6 → 204,7
* commands.
*/
LOG_EXEC(kconsole_init());
#endif
/*
* Exception handler initialization, before architecture
214,7 → 211,7
* starts adding its own handlers
*/
LOG_EXEC(exc_init());
 
/*
* Memory management subsystems initialization.
*/
236,7 → 233,7
/* Slab must be initialized after we know the number of processors. */
LOG_EXEC(slab_enable_cpucache());
printf("Detected %" PRIc " CPU(s), %" PRIu64" MiB free memory\n",
printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
config.cpu_count, SIZE2MB(zone_total_size()));
LOG_EXEC(cpu_init());
250,31 → 247,32
LOG_EXEC(futex_init());
if (init.cnt > 0) {
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++)
printf("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc
"].size=%#" PRIs "\n", i, init.tasks[i].addr, i,
LOG("init[%" PRIs "].addr=%#" PRIp ", init[%" PRIs
"].size=%#" PRIs, i, init.tasks[i].addr, i,
init.tasks[i].size);
} else
printf("No init binaries found\n");
printf("No init binaries found.\n");
LOG_EXEC(ipc_init());
LOG_EXEC(event_init());
LOG_EXEC(klog_init());
 
/*
* Create kernel task.
*/
task_t *kernel = task_create(AS_KERNEL, "kernel");
if (!kernel)
panic("Can't create kernel task\n");
panic("Cannot create kernel task.");
/*
* Create the first thread.
*/
thread_t *kinit_thread = thread_create(kinit, NULL, kernel, 0, "kinit",
true);
thread_t *kinit_thread
= thread_create(kinit, NULL, kernel, 0, "kinit", true);
if (!kinit_thread)
panic("Can't create kinit thread\n");
panic("Cannot create kinit thread.");
LOG_EXEC(thread_ready(kinit_thread));
/*
328,6 → 326,7
* collide with another CPU coming up. To prevent this, we
* switch to this cpu's private stack prior to waking kmp up.
*/
context_save(&CPU->saved_context);
context_set(&CPU->saved_context, FADDR(main_ap_separated_stack),
(uintptr_t) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/branches/arm/kernel/generic/src/main/shutdown.c
32,10 → 32,11
 
/**
* @file
* @brief Shutdown procedures.
* @brief Shutdown procedures.
*/
 
#include <arch.h>
#include <func.h>
#include <print.h>
 
void reboot(void)
47,6 → 48,7
#endif
arch_reboot();
halt();
}
 
/** @}
/branches/arm/kernel/generic/src/main/version.c
34,21 → 34,22
 
#include <main/version.h>
#include <print.h>
#include <macros.h>
 
char *project = "SPARTAN kernel";
char *copyright = "Copyright (c) 2001-2009 HelenOS project";
char *release = RELEASE;
char *name = NAME;
char *arch = ARCH;
char *release = STRING(RELEASE);
char *name = STRING(NAME);
char *arch = STRING(KARCH);
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = " on " TIMESTAMP;
char *timestamp = " on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
/branches/arm/kernel/generic/src/printf/sprintf.c
File deleted
/branches/arm/kernel/generic/src/printf/vsprintf.c
File deleted
/branches/arm/kernel/generic/src/printf/printf_core.c
1,6 → 1,7
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
27,38 → 28,37
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/**
* @file
* @brief Printing functions.
* @brief Printing functions.
*/
 
#include <printf/printf_core.h>
#include <putchar.h>
#include <print.h>
#include <arch/arg.h>
#include <macros.h>
#include <func.h>
#include <string.h>
#include <arch.h>
 
/** show prefixes 0x or 0 */
#define __PRINTF_FLAG_PREFIX 0x00000001
#define __PRINTF_FLAG_PREFIX 0x00000001
/** signed / unsigned number */
#define __PRINTF_FLAG_SIGNED 0x00000002
#define __PRINTF_FLAG_SIGNED 0x00000002
/** print leading zeroes */
#define __PRINTF_FLAG_ZEROPADDED 0x00000004
#define __PRINTF_FLAG_ZEROPADDED 0x00000004
/** align to left */
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010
/** always show + sign */
#define __PRINTF_FLAG_SHOWPLUS 0x00000020
#define __PRINTF_FLAG_SHOWPLUS 0x00000020
/** print space instead of plus */
#define __PRINTF_FLAG_SPACESIGN 0x00000040
#define __PRINTF_FLAG_SPACESIGN 0x00000040
/** show big characters */
#define __PRINTF_FLAG_BIGCHARS 0x00000080
#define __PRINTF_FLAG_BIGCHARS 0x00000080
/** number has - sign */
#define __PRINTF_FLAG_NEGATIVE 0x00000100
#define __PRINTF_FLAG_NEGATIVE 0x00000100
 
/**
* Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0
65,7 → 65,7
* to terminate string... (last one is only for better testing end of buffer by
* zero-filling subroutine)
*/
#define PRINT_NUMBER_BUFFER_SIZE (64 + 5)
#define PRINT_NUMBER_BUFFER_SIZE (64 + 5)
 
/** Enumeration of possible arguments types.
*/
78,69 → 78,103
PrintfQualifierPointer
} qualifier_t;
 
static char nullstr[] = "(NULL)";
static char digits_small[] = "0123456789abcdef";
static char digits_big[] = "0123456789ABCDEF";
static char invalch = U_SPECIAL;
 
/** Print one or more characters without adding newline.
*
* @param buf Buffer with size at least count bytes. NULL pointer is
* not allowed!
* @param count Number of characters to print.
* @param ps Output method and its data.
* @return Number of characters printed.
* @param buf Buffer holding characters with size of
* at least size bytes. NULL is not allowed!
* @param size Size of the buffer in bytes.
* @param ps Output method and its data.
*
* @return Number of characters printed.
*
*/
static int printf_putnchars(const char * buf, size_t count,
struct printf_spec *ps)
static int printf_putnchars(const char *buf, size_t size,
printf_spec_t *ps)
{
return ps->write((void *) buf, count, ps->data);
return ps->str_write((void *) buf, size, ps->data);
}
 
/** Print a string without adding a newline.
/** Print one or more wide characters without adding newline.
*
* @param str String to print.
* @param ps Write function specification and support data.
* @return Number of characters printed.
* @param buf Buffer holding wide characters with size of
* at least size bytes. NULL is not allowed!
* @param size Size of the buffer in bytes.
* @param ps Output method and its data.
*
* @return Number of wide characters printed.
*
*/
static int printf_putstr(const char * str, struct printf_spec *ps)
static int printf_wputnchars(const wchar_t *buf, size_t size,
printf_spec_t *ps)
{
size_t count;
return ps->wstr_write((void *) buf, size, ps->data);
}
 
/** Print string without adding a newline.
*
* @param str String to print.
* @param ps Write function specification and support data.
*
* @return Number of characters printed.
*
*/
static int printf_putstr(const char *str, printf_spec_t *ps)
{
if (str == NULL)
return printf_putnchars(nullstr, str_size(nullstr), ps);
if (str == NULL) {
char *nullstr = "(NULL)";
return printf_putnchars(nullstr, strlen(nullstr), ps);
}
return ps->str_write((void *) str, str_size(str), ps->data);
}
 
count = strlen(str);
 
return ps->write((void *) str, count, ps->data);
/** Print one ASCII character.
*
* @param c ASCII character to be printed.
* @param ps Output method.
*
* @return Number of characters printed.
*
*/
static int printf_putchar(const char ch, printf_spec_t *ps)
{
if (!ascii_check(ch))
return ps->str_write((void *) &invalch, 1, ps->data);
return ps->str_write(&ch, 1, ps->data);
}
 
/** Print one character.
/** Print one wide character.
*
* @param c Character to be printed.
* @param ps Output method.
* @param c Wide character to be printed.
* @param ps Output method.
*
* @return Number of characters printed.
* @return Number of characters printed.
*
*/
static int printf_putchar(int c, struct printf_spec *ps)
static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
{
unsigned char ch = c;
if (!chr_check(ch))
return ps->str_write((void *) &invalch, 1, ps->data);
return ps->write((void *) &ch, 1, ps->data);
return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
}
 
/** Print one formatted character.
/** Print one formatted ASCII character.
*
* @param c Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
* @param ch Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
*
* @return Number of characters printed, negative value on failure.
* @return Number of characters printed, negative value on failure.
*
*/
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
{
int counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
147,106 → 181,190
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
++counter;
if (printf_putchar(' ', ps) > 0)
counter++;
}
}
if (printf_putchar(c, ps) > 0)
if (printf_putchar(ch, ps) > 0)
counter++;
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
return (int) (counter + 1);
}
 
while (--width > 0) {
/** Print one formatted wide character.
*
* @param ch Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
*
* @return Number of characters printed, negative value on failure.
*
*/
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
{
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
}
if (printf_putwchar(ch, ps) > 0)
counter++;
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
++counter;
counter++;
}
return ++counter;
return (int) (counter + 1);
}
 
/** Print string.
*
* @param s String to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
* @param str String to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
*
* @return Number of characters printed, negative value on failure.
*/
static int print_string(char *s, int width, unsigned int precision,
uint64_t flags, struct printf_spec *ps)
* @return Number of characters printed, negative value on failure.
*/
static int print_str(char *str, int width, unsigned int precision,
uint32_t flags, printf_spec_t *ps)
{
int counter = 0;
size_t size;
if (str == NULL)
return printf_putstr(nullstr, ps);
 
/* Print leading spaces. */
size_t strw = str_length(str);
if (precision == 0)
precision = strw;
 
/* Left padding */
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
 
/* Part of @a str fitting into the alloted space. */
int retval;
size_t size = str_lsize(str, precision);
if ((retval = printf_putnchars(str, size, ps)) < 0)
return -counter;
 
if (s == NULL) {
return printf_putstr("(NULL)", ps);
counter += retval;
 
/* Right padding */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
size = strlen(s);
 
/* print leading spaces */
return ((int) counter);
 
if (precision == 0)
precision = size;
}
 
/** Print wide string.
*
* @param str Wide string to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
*
* @return Number of wide characters printed, negative value on failure.
*/
static int print_wstr(wchar_t *str, int width, unsigned int precision,
uint32_t flags, printf_spec_t *ps)
{
if (str == NULL)
return printf_putstr(nullstr, ps);
/* Print leading spaces. */
size_t strw = wstr_length(str);
if (precision == 0)
precision = strw;
/* Left padding */
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
 
if ((retval = printf_putnchars(s, min(size, precision), ps)) < 0) {
/* Part of @a wstr fitting into the alloted space. */
int retval;
size_t size = wstr_lsize(str, precision);
if ((retval = printf_wputnchars(str, size, ps)) < 0)
return -counter;
counter += retval;
/* Right padding */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
counter += retval;
 
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
++counter;
}
return counter;
return ((int) counter);
}
 
 
/** Print a number in a given base.
*
* Print significant digits of a number in given base.
*
* @param num Number to print.
* @param widt Width modifier.h
* @param precision Precision modifier.
* @param base Base to print the number in (must be between 2 and 16).
* @param flags Flags that modify the way the number is printed.
* @param num Number to print.
* @param width Width modifier.
* @param precision Precision modifier.
* @param base Base to print the number in (must be between 2 and 16).
* @param flags Flags that modify the way the number is printed.
*
* @return Number of characters printed.
* @return Number of characters printed.
*
*/
static int print_number(uint64_t num, int width, int precision, int base,
uint64_t flags, struct printf_spec *ps)
uint32_t flags, printf_spec_t *ps)
{
char *digits = digits_small;
char d[PRINT_NUMBER_BUFFER_SIZE];
char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
int size = 0; /* size of number with all prefixes and signs */
int number_size; /* size of plain number */
char sgn;
int retval;
int counter = 0;
char *digits;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
else
digits = digits_small;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
char data[PRINT_NUMBER_BUFFER_SIZE];
char *ptr = &data[PRINT_NUMBER_BUFFER_SIZE - 1];
*ptr-- = 0; /* Put zero at end of string */
 
/* Size of number with all prefixes and signs */
int size = 0;
/* Put zero at end of string */
*ptr-- = 0;
if (num == 0) {
*ptr-- = '0';
size++;
257,15 → 375,17
} while (num /= base);
}
number_size = size;
 
/* Size of plain number */
int number_size = size;
/*
* Collect the sum of all prefixes/signs/... to calculate padding and
* Collect the sum of all prefixes/signs/etc. to calculate padding and
* leading zeroes.
*/
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
case 2:
/* Binary formating is not standard, but usefull */
size += 2;
break;
case 8:
276,8 → 396,8
break;
}
}
 
sgn = 0;
char sgn = 0;
if (flags & __PRINTF_FLAG_SIGNED) {
if (flags & __PRINTF_FLAG_NEGATIVE) {
sgn = '-';
290,48 → 410,46
size++;
}
}
 
if (flags & __PRINTF_FLAG_LEFTALIGNED) {
if (flags & __PRINTF_FLAG_LEFTALIGNED)
flags &= ~__PRINTF_FLAG_ZEROPADDED;
}
 
/*
* If the number is leftaligned or precision is specified then
* zeropadding is ignored.
* If the number is left-aligned or precision is specified then
* padding with zeros is ignored.
*/
if (flags & __PRINTF_FLAG_ZEROPADDED) {
if ((precision == 0) && (width > size)) {
if ((precision == 0) && (width > size))
precision = width - size + number_size;
}
}
 
/* print leading spaces */
/* Print leading spaces */
if (number_size > precision) {
/* print the whole number not only a part */
/* Print the whole number, not only a part */
precision = number_size;
}
 
width -= precision + size - number_size;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
/* print sign */
/* Print sign */
if (sgn) {
if (printf_putchar(sgn, ps) == 1)
counter++;
}
/* print prefix */
/* Print prefix */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
case 2:
/* Binary formating is not standard, but usefull */
if (printf_putchar('0', ps) == 1)
counter++;
if (flags & __PRINTF_FLAG_BIGCHARS) {
359,150 → 477,154
break;
}
}
 
/* print leading zeroes */
/* Print leading zeroes */
precision -= number_size;
while (precision-- > 0) {
while (precision-- > 0) {
if (printf_putchar('0', ps) == 1)
counter++;
}
 
/* print number itself */
 
if ((retval = printf_putstr(++ptr, ps)) > 0) {
/* Print the number itself */
int retval;
if ((retval = printf_putstr(++ptr, ps)) > 0)
counter += retval;
}
/* print ending spaces */
/* Print tailing spaces */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
 
return counter;
return ((int) counter);
}
 
 
/** Print formatted string.
*
* Print string formatted according to the fmt parameter and variadic arguments.
* Each formatting directive must have the following form:
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* FLAGS:@n
* - "#" Force to print prefix.For \%o conversion, the prefix is 0, for
* \%x and \%X prefixes are 0x and 0X and for conversion \%b the
* prefix is 0b.
* - "#" Force to print prefix. For \%o conversion, the prefix is 0, for
* \%x and \%X prefixes are 0x and 0X and for conversion \%b the
* prefix is 0b.
*
* - "-" Align to left.
* - "-" Align to left.
*
* - "+" Print positive sign just as negative.
* - "+" Print positive sign just as negative.
*
* - " " If the printed number is positive and "+" flag is not set,
* print space in place of sign.
* - " " If the printed number is positive and "+" flag is not set,
* print space in place of sign.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between
* sign and the rest of the number. This flag is ignored if "-"
* flag is specified.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between
* sign and the rest of the number. This flag is ignored if "-"
* flag is specified.
*
* WIDTH:@n
* - Specify the minimal width of a printed argument. If it is bigger,
* width is ignored. If width is specified with a "*" character instead of
* number, width is taken from parameter list. And integer parameter is
* expected before parameter for processed conversion specification. If
* this value is negative its absolute value is taken and the "-" flag is
* set.
* - Specify the minimal width of a printed argument. If it is bigger,
* width is ignored. If width is specified with a "*" character instead of
* number, width is taken from parameter list. And integer parameter is
* expected before parameter for processed conversion specification. If
* this value is negative its absolute value is taken and the "-" flag is
* set.
*
* PRECISION:@n
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are not
* affected. Strings with more than precision characters are cut off. Just
* as with width, an "*" can be used used instead of a number. An integer
* value is then expected in parameters. When both width and precision are
* specified using "*", the first parameter is used for width and the
* second one for precision.
*
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are not
* affected. Strings with more than precision characters are cut off. Just
* as with width, an "*" can be used used instead of a number. An integer
* value is then expected in parameters. When both width and precision are
* specified using "*", the first parameter is used for width and the
* second one for precision.
*
* TYPE:@n
* - "hh" Signed or unsigned char.@n
* - "h" Signed or unsigned short.@n
* - "" Signed or unsigned int (default value).@n
* - "l" Signed or unsigned long int.@n
* - "ll" Signed or unsigned long long int.@n
*
*
* - "hh" Signed or unsigned char.@n
* - "h" Signed or unsigned short.@n
* - "" Signed or unsigned int (default value).@n
* - "l" Signed or unsigned long int.@n
* If conversion is "c", the character is wchar_t (wide character).@n
* If conversion is "s", the string is wchar_t * (wide string).@n
* - "ll" Signed or unsigned long long int.@n
*
* CONVERSION:@n
* - % Print percentile character itself.
* - % Print percentile character itself.
*
* - c Print single character.
* - c Print single character. The character is expected to be plain
* ASCII (e.g. only values 0 .. 127 are valid).@n
* If type is "l", then the character is expected to be wide character
* (e.g. values 0 .. 0x10ffff are valid).
*
* - s Print zero terminated string. If a NULL value is passed as
* value, "(NULL)" is printed instead.
*
* - P, p Print value of a pointer. Void * value is expected and it is
* printed in hexadecimal notation with prefix (as with \%#X / \%#x
* for 32-bit or \%#X / \%#x for 64-bit long pointers).
* - s Print zero terminated string. If a NULL value is passed as
* value, "(NULL)" is printed instead.@n
* If type is "l", then the string is expected to be wide string.
*
* - b Print value as unsigned binary number. Prefix is not printed by
* default. (Nonstandard extension.)
*
* - o Print value as unsigned octal number. Prefix is not printed by
* default.
* - P, p Print value of a pointer. Void * value is expected and it is
* printed in hexadecimal notation with prefix (as with \%#X / \%#x
* for 32-bit or \%#X / \%#x for 64-bit long pointers).
*
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
* - b Print value as unsigned binary number. Prefix is not printed by
* default. (Nonstandard extension.)
*
* - u Print unsigned decimal number.
* - o Print value as unsigned octal number. Prefix is not printed by
* default.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
* not printed by default.
*
* All other characters from fmt except the formatting directives are printed in
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
*
* - u Print unsigned decimal number.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
* not printed by default.
*
* All other characters from fmt except the formatting directives are printed
* verbatim.
*
* @param fmt Formatting NULL terminated string.
* @return Number of characters printed, negative value on failure.
* @param fmt Format NULL-terminated string.
*
* @return Number of characters printed, negative value on failure.
*
*/
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
{
int i = 0; /* index of the currently processed char from fmt */
int j = 0; /* index to the first not printed nonformating character */
int end;
int counter; /* counter of printed characters */
int retval; /* used to store return values from called functions */
char c;
qualifier_t qualifier; /* type of argument */
int base; /* base in which a numeric parameter will be printed */
uint64_t number; /* argument value */
size_t size; /* byte size of integer parameter */
int width, precision;
uint64_t flags;
size_t i; /* Index of the currently processed character from fmt */
size_t nxt = 0; /* Index of the next character from fmt */
size_t j = 0; /* Index to the first not printed nonformating character */
counter = 0;
size_t counter = 0; /* Number of characters printed */
int retval; /* Return values from nested functions */
while (true) {
i = nxt;
wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
while ((c = fmt[i])) {
/* control character */
if (c == '%') {
/* print common characters if any processed */
if (uc == 0)
break;
/* Control character */
if (uc == '%') {
/* Print common characters if any processed */
if (i > j) {
if ((retval = printf_putnchars(&fmt[j],
(size_t)(i - j), ps)) < 0) { /* error */
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
/* Error */
counter = -counter;
goto out;
}
counter += retval;
}
j = i;
/* parse modifiers */
flags = 0;
end = 0;
/* Parse modifiers */
uint32_t flags = 0;
bool end = false;
do {
++i;
switch (c = fmt[i]) {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
switch (uc) {
case '#':
flags |= __PRINTF_FLAG_PREFIX;
break;
519,116 → 641,145
flags |= __PRINTF_FLAG_ZEROPADDED;
break;
default:
end = 1;
};
} while (end == 0);
end = true;
};
} while (!end);
/* width & '*' operator */
width = 0;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
/* Width & '*' operator */
int width = 0;
if (isdigit(uc)) {
while (true) {
width *= 10;
width += fmt[i++] - '0';
width += uc - '0';
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
if (!isdigit(uc))
break;
}
} else if (fmt[i] == '*') {
/* get width value from argument list */
i++;
} else if (uc == '*') {
/* Get width value from argument list */
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
width = (int) va_arg(ap, int);
if (width < 0) {
/* negative width sets '-' flag */
/* Negative width sets '-' flag */
width *= -1;
flags |= __PRINTF_FLAG_LEFTALIGNED;
}
}
/* precision and '*' operator */
precision = 0;
if (fmt[i] == '.') {
++i;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
/* Precision and '*' operator */
int precision = 0;
if (uc == '.') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (isdigit(uc)) {
while (true) {
precision *= 10;
precision += fmt[i++] - '0';
precision += uc - '0';
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
if (!isdigit(uc))
break;
}
} else if (fmt[i] == '*') {
/*
* Get precision value from the argument
* list.
*/
i++;
} else if (uc == '*') {
/* Get precision value from the argument list */
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
precision = (int) va_arg(ap, int);
if (precision < 0) {
/* ignore negative precision */
/* Ignore negative precision */
precision = 0;
}
}
}
 
switch (fmt[i++]) {
/** @todo unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
qualifier_t qualifier;
switch (uc) {
/** @todo Unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
*/
case 'h': /* char or short */
case 'h':
/* Char or short */
qualifier = PrintfQualifierShort;
if (fmt[i] == 'h') {
i++;
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 'h') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
qualifier = PrintfQualifierByte;
}
break;
case 'l': /* long or long long*/
case 'l':
/* Long or long long */
qualifier = PrintfQualifierLong;
if (fmt[i] == 'l') {
i++;
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 'l') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
qualifier = PrintfQualifierLongLong;
}
break;
default:
/* default type */
qualifier = PrintfQualifierInt;
--i;
}
/* Default type */
qualifier = PrintfQualifierInt;
}
base = 10;
 
switch (c = fmt[i]) {
 
unsigned int base = 10;
switch (uc) {
/*
* String and character conversions.
*/
* String and character conversions.
*/
case 's':
if ((retval = print_string(va_arg(ap, char *),
width, precision, flags, ps)) < 0) {
if (qualifier == PrintfQualifierLong)
retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
else
retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
if (retval < 0) {
counter = -counter;
goto out;
};
 
}
counter += retval;
j = i + 1;
j = nxt;
goto next_char;
case 'c':
c = va_arg(ap, unsigned int);
retval = print_char(c, width, flags, ps);
if (qualifier == PrintfQualifierLong)
retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps);
else
retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
if (retval < 0) {
counter = -counter;
goto out;
};
counter += retval;
j = i + 1;
j = nxt;
goto next_char;
 
/*
/*
* Integer values
*/
case 'P': /* pointer */
case 'P':
/* Pointer */
flags |= __PRINTF_FLAG_BIGCHARS;
case 'p':
flags |= __PRINTF_FLAG_PREFIX;
base = 16;
qualifier = PrintfQualifierPointer;
break;
case 'b':
break;
case 'b':
base = 2;
break;
case 'o':
636,7 → 787,7
break;
case 'd':
case 'i':
flags |= __PRINTF_FLAG_SIGNED;
flags |= __PRINTF_FLAG_SIGNED;
case 'u':
break;
case 'X':
644,10 → 795,12
case 'x':
base = 16;
break;
/* percentile itself */
case '%':
/* Percentile itself */
case '%':
j = i;
goto next_char;
/*
* Bad formatting.
*/
656,12 → 809,12
* Unknown format. Now, j is the index of '%'
* so we will print whole bad format sequence.
*/
goto next_char;
goto next_char;
}
/* Print integers */
/* print number */
/* Print integers */
size_t size;
uint64_t number;
switch (qualifier) {
case PrintfQualifierByte:
size = sizeof(unsigned char);
687,7 → 840,8
size = sizeof(void *);
number = (uint64_t) (unsigned long) va_arg(ap, void *);
break;
default: /* Unknown qualifier */
default:
/* Unknown qualifier */
counter = -counter;
goto out;
}
695,7 → 849,7
if (flags & __PRINTF_FLAG_SIGNED) {
if (number & (0x1 << (size * 8 - 1))) {
flags |= __PRINTF_FLAG_NEGATIVE;
if (size == sizeof(uint64_t)) {
number = -((int64_t) number);
} else {
707,33 → 861,31
}
}
}
 
if ((retval = print_number(number, width, precision,
base, flags, ps)) < 0) {
counter = -counter;
goto out;
}
 
counter += retval;
j = i + 1;
}
j = nxt;
}
next_char:
++i;
;
}
if (i > j) {
if ((retval = printf_putnchars(&fmt[j], (unative_t) (i - j),
ps)) < 0) { /* error */
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
/* Error */
counter = -counter;
goto out;
}
counter += retval;
}
 
out:
return counter;
return ((int) counter);
}
 
/** @}
/branches/arm/kernel/generic/src/printf/vprintf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
39,36 → 39,66
#include <arch/asm.h>
#include <arch/types.h>
#include <typedefs.h>
#include <string.h>
 
SPINLOCK_INITIALIZE(printf_lock); /**< vprintf spinlock */
SPINLOCK_INITIALIZE(printf_lock); /**< vprintf spinlock */
 
static int vprintf_write(const char *str, size_t count, void *unused)
static int vprintf_str_write(const char *str, size_t size, void *data)
{
size_t i;
for (i = 0; i < count; i++)
putchar(str[i]);
return i;
size_t offset = 0;
size_t chars = 0;
while (offset < size) {
putchar(str_decode(str, &offset, size));
chars++;
}
return chars;
}
 
int puts(const char *s)
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
{
size_t i;
for (i = 0; s[i] != 0; i++)
putchar(s[i]);
return i;
size_t offset = 0;
size_t chars = 0;
while (offset < size) {
putchar(str[chars]);
chars++;
offset += sizeof(wchar_t);
}
return chars;
}
 
int puts(const char *str)
{
size_t offset = 0;
size_t chars = 0;
wchar_t uc;
while ((uc = str_decode(str, &offset, STR_NO_LIMIT)) != 0) {
putchar(uc);
chars++;
}
return chars;
}
 
int vprintf(const char *fmt, va_list ap)
{
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_write, NULL};
printf_spec_t ps = {
vprintf_str_write,
vprintf_wstr_write,
NULL
};
int irqpri = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&printf_lock);
int ret = printf_core(fmt, &ps, ap);
spinlock_unlock(&printf_lock);
interrupts_restore(irqpri);
interrupts_restore(ipl);
return ret;
}
/branches/arm/kernel/generic/src/printf/vsnprintf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
34,62 → 34,146
 
#include <print.h>
#include <printf/printf_core.h>
#include <string.h>
#include <memstr.h>
#include <errno.h>
 
struct vsnprintf_data {
size_t size; /* total space for string */
size_t len; /* count of currently used characters */
char *string; /* destination string */
};
typedef struct {
size_t size; /* Total size of the buffer (in bytes) */
size_t len; /* Number of already used bytes */
char *dst; /* Destination */
} vsnprintf_data_t;
 
/** Write string to given buffer.
* Write at most data->size characters including trailing zero. According to C99, snprintf() has to return number
* of characters that would have been written if enough space had been available. Hence the return value is not
* number of really printed characters but size of the input string. Number of really used characters
* is stored in data->len.
* @param str source string to print
* @param count size of source string
* @param data structure with destination string, counter of used space and total string size.
* @return number of characters to print (not characters really printed!)
*
* Write at most data->size plain characters including trailing zero.
* According to C99, snprintf() has to return number of characters that
* would have been written if enough space had been available. Hence
* the return value is not the number of actually printed characters
* but size of the input string.
*
* @param str Source string to print.
* @param size Number of plain characters in str.
* @param data Structure describing destination string, counter
* of used space and total string size.
*
* @return Number of characters to print (not characters actually
* printed).
*
*/
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data)
{
size_t i;
i = data->size - data->len;
 
if (i == 0) {
return count;
}
size_t left = data->size - data->len;
if (i == 1) {
/* We have only one free byte left in buffer => write there trailing zero */
data->string[data->size - 1] = 0;
if (left == 0)
return ((int) size);
if (left == 1) {
/* We have only one free byte left in buffer
* -> store trailing zero
*/
data->dst[data->size - 1] = 0;
data->len = data->size;
return count;
return ((int) size);
}
if (i <= count) {
/* We have not enought space for whole string with the trailing zero => print only a part of string */
memcpy((void *)(data->string + data->len), (void *)str, i - 1);
data->string[data->size - 1] = 0;
if (left <= size) {
/* We do not have enough space for the whole string
* with the trailing zero => print only a part
* of string
*/
size_t index = 0;
while (index < size) {
wchar_t uc = str_decode(str, &index, size);
if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
break;
}
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
/* Buffer is big enought to print the whole string */
memcpy((void *)(data->dst + data->len), (void *) str, size);
data->len += size;
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
 
/** Write wide string to given buffer.
*
* Write at most data->size plain characters including trailing zero.
* According to C99, snprintf() has to return number of characters that
* would have been written if enough space had been available. Hence
* the return value is not the number of actually printed characters
* but size of the input string.
*
* @param str Source wide string to print.
* @param size Number of bytes in str.
* @param data Structure describing destination string, counter
* of used space and total string size.
*
* @return Number of wide characters to print (not characters actually
* printed).
*
*/
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
{
size_t index = 0;
while (index < (size / sizeof(wchar_t))) {
size_t left = data->size - data->len;
if (left == 0)
return ((int) size);
if (left == 1) {
/* We have only one free byte left in buffer
* -> store trailing zero
*/
data->dst[data->size - 1] = 0;
data->len = data->size;
return count;
return ((int) size);
}
if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK)
break;
index++;
}
/* Buffer is big enought to print whole string */
memcpy((void *)(data->string + data->len), (void *)str, count);
data->len += count;
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */
data->string[data->len] = 0;
 
return count;
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
 
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
struct vsnprintf_data data = {size, 0, str};
struct printf_spec ps = {(int(*)(void *, size_t, void *))vsnprintf_write, &data};
 
vsnprintf_data_t data = {
size,
0,
str
};
printf_spec_t ps = {
(int(*) (const char *, size_t, void *)) vsnprintf_str_write,
(int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
&data
};
/* Print 0 at end of string - fix the case that nothing will be printed */
if (size > 0)
str[0] = 0;
/branches/arm/kernel/generic/src/printf/printf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
33,19 → 33,18
*/
 
#include <print.h>
int printf(const char *fmt, ...);
 
int printf(const char *fmt, ...)
{
int ret;
va_list args;
 
va_start(args, fmt);
 
ret = vprintf(fmt, args);
va_end(args);
 
return ret;
}
 
/branches/arm/kernel/generic/src/printf/snprintf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
42,9 → 42,9
va_start(args, fmt);
ret = vsnprintf(str, size, fmt, args);
 
va_end(args);
 
return ret;
}
 
/branches/arm/kernel/generic/src/synch/spinlock.c
32,9 → 32,9
 
/**
* @file
* @brief Spinlocks.
* @brief Spinlocks.
*/
 
#include <synch/spinlock.h>
#include <atomic.h>
#include <arch/barrier.h>
75,8 → 75,7
#ifdef CONFIG_DEBUG_SPINLOCK
void spinlock_lock_debug(spinlock_t *sl)
{
count_t i = 0;
char *symbol;
size_t i = 0;
bool deadlock_reported = false;
 
preemption_disable();
106,12 → 105,10
continue;
#endif
if (i++ > DEADLOCK_THRESHOLD) {
printf("cpu%u: looping on spinlock %" PRIp ":%s, caller=%" PRIp,
CPU->id, sl, sl->name, CALLER);
symbol = get_symtab_entry(CALLER);
if (symbol)
printf("(%s)", symbol);
printf("\n");
printf("cpu%u: looping on spinlock %" PRIp ":%s, "
"caller=%" PRIp "(%s)\n", CPU->id, sl, sl->name,
CALLER, symtab_fmt_name_lookup(CALLER));
i = 0;
deadlock_reported = true;
}
/branches/arm/kernel/generic/src/synch/waitq.c
415,7 → 415,7
void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode)
{
thread_t *t;
count_t count = 0;
size_t count = 0;
 
loop:
if (list_empty(&wq->head)) {
/branches/arm/kernel/generic/src/synch/futex.c
59,8 → 59,8
static void futex_initialize(futex_t *futex);
 
static futex_t *futex_find(uintptr_t paddr);
static index_t futex_ht_hash(unative_t *key);
static bool futex_ht_compare(unative_t *key, count_t keys, link_t *item);
static size_t futex_ht_hash(unative_t *key);
static bool futex_ht_compare(unative_t *key, size_t keys, link_t *item);
static void futex_ht_remove_callback(link_t *item);
 
/**
115,6 → 115,7
uintptr_t paddr;
pte_t *t;
ipl_t ipl;
int rc;
ipl = interrupts_disable();
 
134,9 → 135,17
interrupts_restore(ipl);
 
futex = futex_find(paddr);
return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags |
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = waitq_sleep_timeout(&futex->wq, usec, flags |
SYNCH_FLAGS_INTERRUPTIBLE);
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
return (unative_t) rc;
}
 
/** Wakeup one thread waiting in futex wait queue.
279,9 → 288,9
*
* @return Index into futex hash table.
*/
index_t futex_ht_hash(unative_t *key)
size_t futex_ht_hash(unative_t *key)
{
return *key & (FUTEX_HT_SIZE-1);
return (*key & (FUTEX_HT_SIZE - 1));
}
 
/** Compare futex hash table item with a key.
291,7 → 300,7
*
* @return True if the item matches the key. False otherwise.
*/
bool futex_ht_compare(unative_t *key, count_t keys, link_t *item)
bool futex_ht_compare(unative_t *key, size_t keys, link_t *item)
{
futex_t *futex;
 
/branches/arm/kernel/generic/src/synch/rwlock.c
231,10 → 231,10
interrupts_restore(ipl);
break;
case ESYNCH_OK_ATOMIC:
panic("_mutex_lock_timeout() == ESYNCH_OK_ATOMIC\n");
panic("_mutex_lock_timeout() == ESYNCH_OK_ATOMIC.");
break;
default:
panic("invalid ESYNCH\n");
panic("Invalid ESYNCH.");
break;
}
return rc;
/branches/arm/kernel/generic/src/debug/symtab.c
32,171 → 32,222
 
/**
* @file
* @brief Kernel symbol resolver.
* @brief Kernel symbol resolver.
*/
 
#include <symtab.h>
#include <byteorder.h>
#include <func.h>
#include <string.h>
#include <print.h>
#include <arch/types.h>
#include <typedefs.h>
#include <errno.h>
 
/** Return entry that seems most likely to correspond to argument.
/** Get name of a symbol that seems most likely to correspond to address.
*
* Return entry that seems most likely to correspond
* to address passed in the argument.
*
* @param addr Address.
* @param name Place to store pointer to the symbol name.
*
* @return Pointer to respective symbol string on success, NULL otherwise.
* @return Zero on success or negative error code, ENOENT if not found,
* ENOTSUP if symbol table not available.
*
*/
char * get_symtab_entry(unative_t addr)
int symtab_name_lookup(unative_t addr, char **name)
{
count_t i;
 
for (i = 1; symbol_table[i].address_le; ++i) {
#ifdef CONFIG_SYMTAB
size_t i;
for (i = 1; symbol_table[i].address_le; i++) {
if (addr < uint64_t_le2host(symbol_table[i].address_le))
break;
}
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le))
return symbol_table[i - 1].symbol_name;
return NULL;
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) {
*name = symbol_table[i - 1].symbol_name;
return EOK;
}
*name = NULL;
return ENOENT;
#else
*name = NULL;
return ENOTSUP;
#endif
}
 
/** Find symbols that match the parameter forward and print them.
/** Lookup symbol by address and format for display.
*
* @param name - search string
* @param startpos - starting position, changes to found position
* @return Pointer to the part of string that should be completed or NULL
* Returns name of closest corresponding symbol, "Not found" if none exists
* or "N/A" if no symbol information is available.
*
* @param addr Address.
* @param name Place to store pointer to the symbol name.
*
* @return Pointer to a human-readable string.
*
*/
static char * symtab_search_one(const char *name, int *startpos)
char *symtab_fmt_name_lookup(unative_t addr)
{
unsigned int namelen = strlen(name);
char *curname;
int i, j;
int colonoffset = -1;
char *name;
int rc = symtab_name_lookup(addr, &name);
switch (rc) {
case EOK:
return name;
case ENOENT:
return "Not found";
default:
return "N/A";
}
}
 
for (i = 0; name[i]; i++)
if (name[i] == ':') {
colonoffset = i;
break;
}
#ifdef CONFIG_SYMTAB
 
for (i = *startpos; symbol_table[i].address_le; ++i) {
/* Find a ':' in name */
curname = symbol_table[i].symbol_name;
for (j = 0; curname[j] && curname[j] != ':'; j++)
;
if (!curname[j])
/** Find symbols that match the parameter forward and print them.
*
* @param name Search string
* @param startpos Starting position, changes to found position
*
* @return Pointer to the part of string that should be completed or NULL.
*
*/
static const char *symtab_search_one(const char *name, size_t *startpos)
{
size_t namelen = str_length(name);
size_t pos;
for (pos = *startpos; symbol_table[pos].address_le; pos++) {
const char *curname = symbol_table[pos].symbol_name;
/* Find a ':' in curname */
const char *colon = str_chr(curname, ':');
if (colon == NULL)
continue;
j -= colonoffset;
curname += j;
if (strlen(curname) < namelen)
if (str_length(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
*startpos = i;
return curname + namelen;
if (str_lcmp(name, curname, namelen) == 0) {
*startpos = pos;
return (curname + str_lsize(curname, namelen));
}
}
return NULL;
}
 
/** Return address that corresponds to the entry
#endif
 
/** Return address that corresponds to the entry.
*
* Search symbol table, and if there is one match, return it
*
* @param name Name of the symbol
* @return 0 - Not found, -1 - Duplicate symbol, other - address of symbol
* @param addr Place to store symbol address
*
* @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate
* symbol, ENOTSUP - no symbol information available.
*
*/
uintptr_t get_symbol_addr(const char *name)
int symtab_addr_lookup(const char *name, uintptr_t *addr)
{
count_t found = 0;
uintptr_t addr = NULL;
char *hint;
int i;
 
i = 0;
while ((hint = symtab_search_one(name, &i))) {
if (!strlen(hint)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
#ifdef CONFIG_SYMTAB
size_t found = 0;
size_t pos = 0;
const char *hint;
while ((hint = symtab_search_one(name, &pos))) {
if (str_length(hint) == 0) {
*addr = uint64_t_le2host(symbol_table[pos].address_le);
found++;
}
i++;
pos++;
}
if (found > 1)
return ((uintptr_t) -1);
return addr;
return EOVERFLOW;
if (found < 1)
return ENOENT;
return EOK;
#else
return ENOTSUP;
#endif
}
 
/** Find symbols that match parameter and prints them */
/** Find symbols that match parameter and print them */
void symtab_print_search(const char *name)
{
int i;
uintptr_t addr;
char *realname;
 
 
i = 0;
while (symtab_search_one(name, &i)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
realname = symbol_table[i].symbol_name;
#ifdef CONFIG_SYMTAB
size_t pos = 0;
while (symtab_search_one(name, &pos)) {
uintptr_t addr = uint64_t_le2host(symbol_table[pos].address_le);
char *realname = symbol_table[pos].symbol_name;
printf("%p: %s\n", addr, realname);
i++;
pos++;
}
#else
printf("No symbol information available.\n");
#endif
}
 
/** Symtab completion
*
* @param input - Search string, completes to symbol name
* @returns - 0 - nothing found, 1 - success, >1 print duplicates
* @param input Search string, completes to symbol name
* @param size Input buffer size
*
* @return 0 - nothing found, 1 - success, >1 print duplicates
*
*/
int symtab_compl(char *input)
int symtab_compl(char *input, size_t size)
{
char output[MAX_SYMBOL_NAME + 1];
int startpos = 0;
char *foundtxt;
int found = 0;
int i;
char *name = input;
 
/* Allow completion of pointers */
if (name[0] == '*' || name[0] == '&')
#ifdef CONFIG_SYMTAB
const char *name = input;
/* Allow completion of pointers */
if ((name[0] == '*') || (name[0] == '&'))
name++;
 
/* Do not print everything */
if (!strlen(name))
/* Do not print all symbols */
if (str_length(name) == 0)
return 0;
 
output[0] = '\0';
 
while ((foundtxt = symtab_search_one(name, &startpos))) {
startpos++;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt) + 1);
else {
for (i = 0; output[i] && foundtxt[i] &&
output[i] == foundtxt[i]; i++)
;
output[i] = '\0';
}
size_t found = 0;
size_t pos = 0;
const char *hint;
char output[MAX_SYMBOL_NAME];
output[0] = 0;
while ((hint = symtab_search_one(name, &pos))) {
if ((found == 0) || (str_length(output) > str_length(hint)))
str_cpy(output, MAX_SYMBOL_NAME, hint);
pos++;
found++;
}
if (!found)
return 0;
 
if (found > 1 && !strlen(output)) {
if ((found > 1) && (str_length(output) != 0)) {
printf("\n");
startpos = 0;
while ((foundtxt = symtab_search_one(name, &startpos))) {
printf("%s\n", symbol_table[startpos].symbol_name);
startpos++;
pos = 0;
while ((hint = symtab_search_one(name, &pos))) {
printf("%s\n", symbol_table[pos].symbol_name);
pos++;
}
}
strncpy(input, output, MAX_SYMBOL_NAME);
if (found > 0)
str_cpy(input, size, output);
return found;
#else
return 0;
#endif
}
 
/** @}
/branches/arm/kernel/generic/src/time/clock.c
79,7 → 79,7
 
faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
if (!faddr)
panic("Cannot allocate page for clock");
panic("Cannot allocate page for clock.");
uptime = (uptime_t *) PA2KA(faddr);
88,9 → 88,7
uptime->useconds = 0;
 
clock_parea.pbase = (uintptr_t) faddr;
clock_parea.vbase = (uintptr_t) uptime;
clock_parea.frames = 1;
clock_parea.cacheable = true;
ddi_parea_register(&clock_parea);
 
/*
136,7 → 134,7
timeout_t *h;
timeout_handler_t f;
void *arg;
count_t missed_clock_ticks = CPU->missed_clock_ticks;
size_t missed_clock_ticks = CPU->missed_clock_ticks;
unsigned int i;
 
/*
189,7 → 187,19
spinlock_unlock(&THREAD->lock);
if (!ticks && !PREEMPTION_DISABLED) {
#ifdef CONFIG_UDEBUG
istate_t *istate;
#endif
scheduler();
#ifdef CONFIG_UDEBUG
/*
* Give udebug chance to stop the thread
* before it begins executing userspace code.
*/
istate = THREAD->udebug.uspace_state;
if (istate && istate_from_uspace(istate))
udebug_before_thread_runs();
#endif
}
}
 
/branches/arm/kernel/generic/src/time/timeout.c
113,7 → 113,7
spinlock_lock(&t->lock);
 
if (t->cpu)
panic("t->cpu != 0");
panic("Unexpected: t->cpu != 0.");
 
t->cpu = CPU;
t->ticks = us2ticks(time);
/branches/arm/kernel/generic/src/ddi/ddi.c
29,10 → 29,10
/** @addtogroup genericddi
* @{
*/
 
/**
* @file
* @brief Device Driver Interface functions.
* @brief Device Driver Interface functions.
*
* This file contains functions that comprise the Device Driver Interface.
* These are the functions for mapping physical memory and enabling I/O
68,82 → 68,100
*
* @param parea Pointer to physical area structure.
*
* @todo This function doesn't check for overlaps. It depends on the kernel to
* create disjunct physical memory areas.
*/
void ddi_parea_register(parea_t *parea)
{
ipl_t ipl;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&parea_lock);
/*
* TODO: we should really check for overlaps here.
* However, we should be safe because the kernel is pretty sane and
* memory of different devices doesn't overlap.
* We don't check for overlaps here as the kernel is pretty sane.
*/
btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL);
 
spinlock_unlock(&parea_lock);
interrupts_restore(ipl);
interrupts_restore(ipl);
}
 
/** Map piece of physical memory into virtual address space of current task.
*
* @param pf Physical address of the starting frame.
* @param vp Virtual address of the starting page.
* @param pf Physical address of the starting frame.
* @param vp Virtual address of the starting page.
* @param pages Number of pages to map.
* @param flags Address space area flags for the mapping.
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this
* syscall, ENOENT if there is no task matching the specified ID or the
* physical address space is not enabled for mapping and ENOMEM if there
* was a problem in creating address space area.
* syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there
* is no task matching the specified ID or the physical address space
* is not enabled for mapping and ENOMEM if there was a problem in
* creating address space area.
*
*/
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags)
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages, int flags)
{
ipl_t ipl;
cap_t caps;
mem_backend_data_t backend_data;
 
backend_data.base = pf;
backend_data.frames = pages;
ASSERT(TASK);
ASSERT((pf % FRAME_SIZE) == 0);
ASSERT((vp % PAGE_SIZE) == 0);
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
cap_t caps = cap_get(TASK);
if (!(caps & CAP_MEM_MANAGER))
return EPERM;
 
ipl = interrupts_disable();
 
/*
* Check if the physical memory area is enabled for mapping.
* If the architecture supports virtually indexed caches, intercept
* attempts to create an illegal address alias.
*/
spinlock_lock(&parea_lock);
parea_t *parea;
btree_node_t *nodep;
parea = (parea_t *) btree_search(&parea_btree, (btree_key_t) pf, &nodep);
if (!parea || parea->frames < pages || ((flags & AS_AREA_CACHEABLE) &&
!parea->cacheable) || (!(flags & AS_AREA_CACHEABLE) &&
parea->cacheable)) {
/*
* This physical memory area cannot be mapped.
mem_backend_data_t backend_data;
backend_data.base = pf;
backend_data.frames = pages;
ipl_t ipl = interrupts_disable();
/* Find the zone of the physical memory */
spinlock_lock(&zones.lock);
size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
if (znum == (size_t) -1) {
/* Frames not found in any zones
* -> assume it is hardware device and allow mapping
*/
spinlock_unlock(&zones.lock);
goto map;
}
if (zones.info[znum].flags & ZONE_FIRMWARE) {
/* Frames are part of firmware */
spinlock_unlock(&zones.lock);
goto map;
}
if (zone_flags_available(zones.info[znum].flags)) {
/* Frames are part of physical memory, check if the memory
* region is enabled for mapping.
*/
spinlock_unlock(&zones.lock);
spinlock_lock(&parea_lock);
btree_node_t *nodep;
parea_t *parea = (parea_t *) btree_search(&parea_btree,
(btree_key_t) pf, &nodep);
if ((!parea) || (parea->frames < pages))
goto err;
spinlock_unlock(&parea_lock);
interrupts_restore(ipl);
return ENOENT;
goto map;
}
spinlock_unlock(&parea_lock);
 
err:
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return ENOENT;
map:
spinlock_lock(&TASK->lock);
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
&phys_backend, &backend_data)) {
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
/*
* The address space area could not have been created.
* We report it using ENOMEM.
169,28 → 187,24
* @param size Size of the enabled I/O space..
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this
* syscall, ENOENT if there is no task matching the specified ID.
* syscall, ENOENT if there is no task matching the specified ID.
*
*/
static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
{
ipl_t ipl;
cap_t caps;
task_t *t;
int rc;
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
cap_t caps = cap_get(TASK);
if (!(caps & CAP_IO_MANAGER))
return EPERM;
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id(id);
task_t *task = task_find_by_id(id);
if ((!t) || (!context_check(CONTEXT, t->context))) {
if ((!task) || (!context_check(CONTEXT, task->context))) {
/*
* There is no task with the specified ID
* or the task belongs to a different security
200,15 → 214,16
interrupts_restore(ipl);
return ENOENT;
}
 
/* Lock the task and release the lock protecting tasks_btree. */
spinlock_lock(&t->lock);
spinlock_lock(&task->lock);
spinlock_unlock(&tasks_lock);
 
rc = ddi_iospace_enable_arch(t, ioaddr, size);
spinlock_unlock(&t->lock);
int rc = ddi_iospace_enable_arch(task, ioaddr, size);
spinlock_unlock(&task->lock);
interrupts_restore(ipl);
return rc;
}
 
220,13 → 235,14
* @param flags Flags of newly mapped pages
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
*
*/
unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base,
unative_t pages, unative_t flags)
{
return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,
FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),
(count_t) pages, (int) flags);
(size_t) pages, (int) flags);
}
 
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
234,16 → 250,15
* @param uspace_io_arg User space address of DDI argument structure.
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
*
*/
unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg)
{
ddi_ioarg_t arg;
int rc;
rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
if (rc != 0)
return (unative_t) rc;
return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id,
(uintptr_t) arg.ioaddr, (size_t) arg.size);
}
251,20 → 266,24
/** Disable or enable preemption.
*
* @param enable If non-zero, the preemption counter will be decremented,
* leading to potential enabling of preemption. Otherwise the preemption
* counter will be incremented, preventing preemption from occurring.
* leading to potential enabling of preemption. Otherwise
* the preemption counter will be incremented, preventing
* preemption from occurring.
*
* @return Zero on success or EPERM if callers capabilities are not sufficient.
*/
*
*/
unative_t sys_preempt_control(int enable)
{
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
}
 
/** @}
/branches/arm/kernel/generic/src/ddi/irq.c
39,7 → 39,8
*
* This code is designed to support:
* - multiple devices sharing single IRQ
* - multiple IRQs per signle device
* - multiple IRQs per single device
* - multiple instances of the same device
*
*
* Note about architectures.
68,8 → 69,11
 
#include <ddi/irq.h>
#include <adt/hash_table.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <synch/spinlock.h>
#include <console/console.h>
#include <memstr.h>
#include <arch.h>
 
#define KEY_INR 0
76,23 → 80,33
#define KEY_DEVNO 1
 
/**
* Spinlock protecting the hash table.
* Spinlock protecting the kernel IRQ hash table.
* This lock must be taken only when interrupts are disabled.
*/
SPINLOCK_INITIALIZE(irq_hash_table_lock);
static hash_table_t irq_hash_table;
SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock);
/** The kernel IRQ hash table. */
static hash_table_t irq_kernel_hash_table;
 
/**
* Spinlock protecting the uspace IRQ hash table.
* This lock must be taken only when interrupts are disabled.
*/
SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
/** The uspace IRQ hash table. */
hash_table_t irq_uspace_hash_table;
 
/**
* Hash table operations for cases when we know that
* there will be collisions between different keys.
*/
static index_t irq_ht_hash(unative_t *key);
static bool irq_ht_compare(unative_t *key, count_t keys, link_t *item);
static size_t irq_ht_hash(unative_t *key);
static bool irq_ht_compare(unative_t *key, size_t keys, link_t *item);
static void irq_ht_remove(link_t *item);
 
static hash_table_operations_t irq_ht_ops = {
.hash = irq_ht_hash,
.compare = irq_ht_compare,
.remove_callback = NULL /* not used */
.remove_callback = irq_ht_remove,
};
 
/**
101,22 → 115,27
* However, there might be still collisions among
* elements with single key (sharing of one IRQ).
*/
static index_t irq_lin_hash(unative_t *key);
static bool irq_lin_compare(unative_t *key, count_t keys, link_t *item);
static size_t irq_lin_hash(unative_t *key);
static bool irq_lin_compare(unative_t *key, size_t keys, link_t *item);
static void irq_lin_remove(link_t *item);
 
static hash_table_operations_t irq_lin_ops = {
.hash = irq_lin_hash,
.compare = irq_lin_compare,
.remove_callback = NULL /* not used */
.remove_callback = irq_lin_remove,
};
 
/** Number of buckets in either of the hash tables. */
static size_t buckets;
 
/** Initialize IRQ subsystem.
*
* @param inrs Numbers of unique IRQ numbers or INRs.
* @param chains Number of chains in the hash table.
*/
void irq_init(count_t inrs, count_t chains)
void irq_init(size_t inrs, size_t chains)
{
buckets = chains;
/*
* Be smart about the choice of the hash table operations.
* In cases in which inrs equals the requested number of
123,10 → 142,17
* chains (i.e. where there is no collision between
* different keys), we can use optimized set of operations.
*/
if (inrs == chains)
hash_table_create(&irq_hash_table, chains, 2, &irq_lin_ops);
else
hash_table_create(&irq_hash_table, chains, 2, &irq_ht_ops);
if (inrs == chains) {
hash_table_create(&irq_uspace_hash_table, chains, 2,
&irq_lin_ops);
hash_table_create(&irq_kernel_hash_table, chains, 2,
&irq_lin_ops);
} else {
hash_table_create(&irq_uspace_hash_table, chains, 2,
&irq_ht_ops);
hash_table_create(&irq_kernel_hash_table, chains, 2,
&irq_ht_ops);
}
}
 
/** Initialize one IRQ structure.
136,21 → 162,12
*/
void irq_initialize(irq_t *irq)
{
memsetb(irq, sizeof(irq_t), 0);
link_initialize(&irq->link);
spinlock_initialize(&irq->lock, "irq.lock");
irq->preack = false;
link_initialize(&irq->notif_cfg.link);
irq->inr = -1;
irq->devno = -1;
irq->trigger = (irq_trigger_t) 0;
irq->claim = NULL;
irq->handler = NULL;
irq->arg = NULL;
irq->notif_cfg.notify = false;
irq->notif_cfg.answerbox = NULL;
irq->notif_cfg.code = NULL;
irq->notif_cfg.method = 0;
irq->notif_cfg.counter = 0;
link_initialize(&irq->notif_cfg.link);
}
 
/** Register IRQ for device.
157,9 → 174,10
*
* The irq structure must be filled with information
* about the interrupt source and with the claim()
* function pointer and irq_handler() function pointer.
* function pointer and handler() function pointer.
*
* @param irq IRQ structure belonging to a device.
* @param irq IRQ structure belonging to a device.
* @return True on success, false on failure.
*/
void irq_register(irq_t *irq)
{
170,88 → 188,101
};
ipl = interrupts_disable();
spinlock_lock(&irq_hash_table_lock);
hash_table_insert(&irq_hash_table, key, &irq->link);
spinlock_unlock(&irq_hash_table_lock);
spinlock_lock(&irq_kernel_hash_table_lock);
spinlock_lock(&irq->lock);
hash_table_insert(&irq_kernel_hash_table, key, &irq->link);
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_kernel_hash_table_lock);
interrupts_restore(ipl);
}
 
/** Dispatch the IRQ.
/** Search and lock the uspace IRQ hash table.
*
* We assume this function is only called from interrupt
* context (i.e. that interrupts are disabled prior to
* this call).
*
* This function attempts to lookup a fitting IRQ
* structure. In case of success, return with interrupts
* disabled and holding the respective structure.
*
* @param inr Interrupt number (aka inr or irq).
*
* @return IRQ structure of the respective device or NULL.
*/
irq_t *irq_dispatch_and_lock(inr_t inr)
static irq_t *irq_dispatch_and_lock_uspace(inr_t inr)
{
link_t *lnk;
unative_t key[] = {
(unative_t) inr,
(unative_t) -1 /* search will use claim() instead of devno */
(unative_t) -1 /* search will use claim() instead of devno */
};
spinlock_lock(&irq_hash_table_lock);
 
lnk = hash_table_find(&irq_hash_table, key);
spinlock_lock(&irq_uspace_hash_table_lock);
lnk = hash_table_find(&irq_uspace_hash_table, key);
if (lnk) {
irq_t *irq;
irq = hash_table_get_instance(lnk, irq_t, link);
 
spinlock_unlock(&irq_hash_table_lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
return irq;
}
spinlock_unlock(&irq_uspace_hash_table_lock);
spinlock_unlock(&irq_hash_table_lock);
 
return NULL;
return NULL;
}
 
/** Find the IRQ structure corresponding to inr and devno.
/** Search and lock the kernel IRQ hash table.
*
* This functions attempts to lookup the IRQ structure
* corresponding to its arguments. On success, this
* function returns with interrups disabled, holding
* the lock of the respective IRQ structure.
*
* This function assumes interrupts are already disabled.
*
* @param inr INR being looked up.
* @param devno Devno being looked up.
*
* @return Locked IRQ structure on success or NULL on failure.
*/
irq_t *irq_find_and_lock(inr_t inr, devno_t devno)
static irq_t *irq_dispatch_and_lock_kernel(inr_t inr)
{
link_t *lnk;
unative_t keys[] = {
unative_t key[] = {
(unative_t) inr,
(unative_t) devno
(unative_t) -1 /* search will use claim() instead of devno */
};
spinlock_lock(&irq_hash_table_lock);
 
lnk = hash_table_find(&irq_hash_table, keys);
spinlock_lock(&irq_kernel_hash_table_lock);
lnk = hash_table_find(&irq_kernel_hash_table, key);
if (lnk) {
irq_t *irq;
irq = hash_table_get_instance(lnk, irq_t, link);
 
spinlock_unlock(&irq_hash_table_lock);
spinlock_unlock(&irq_kernel_hash_table_lock);
return irq;
}
spinlock_unlock(&irq_kernel_hash_table_lock);
spinlock_unlock(&irq_hash_table_lock);
return NULL;
}
 
return NULL;
/** Dispatch the IRQ.
*
* We assume this function is only called from interrupt
* context (i.e. that interrupts are disabled prior to
* this call).
*
* This function attempts to lookup a fitting IRQ
* structure. In case of success, return with interrupts
* disabled and holding the respective structure.
*
* @param inr Interrupt number (aka inr or irq).
*
* @return IRQ structure of the respective device or NULL.
*/
irq_t *irq_dispatch_and_lock(inr_t inr)
{
irq_t *irq;
/*
* If the kernel console is silenced,
* then try first the uspace handlers,
* eventually fall back to kernel handlers.
*
* If the kernel console is active,
* then do it the other way around.
*/
if (silent) {
irq = irq_dispatch_and_lock_uspace(inr);
if (irq)
return irq;
return irq_dispatch_and_lock_kernel(inr);
}
irq = irq_dispatch_and_lock_kernel(inr);
if (irq)
return irq;
return irq_dispatch_and_lock_uspace(inr);
}
 
/** Compute hash index for the key.
267,10 → 298,10
*
* @return Index into the hash table.
*/
index_t irq_ht_hash(unative_t key[])
size_t irq_ht_hash(unative_t key[])
{
inr_t inr = (inr_t) key[KEY_INR];
return inr % irq_hash_table.entries;
return inr % buckets;
}
 
/** Compare hash table element with a key.
293,7 → 324,7
*
* @return True on match or false otherwise.
*/
bool irq_ht_compare(unative_t key[], count_t keys, link_t *item)
bool irq_ht_compare(unative_t key[], size_t keys, link_t *item)
{
irq_t *irq = hash_table_get_instance(item, irq_t, link);
inr_t inr = (inr_t) key[KEY_INR];
304,7 → 335,8
spinlock_lock(&irq->lock);
if (devno == -1) {
/* Invoked by irq_dispatch_and_lock(). */
rv = ((irq->inr == inr) && (irq->claim() == IRQ_ACCEPT));
rv = ((irq->inr == inr) &&
(irq->claim(irq) == IRQ_ACCEPT));
} else {
/* Invoked by irq_find_and_lock(). */
rv = ((irq->inr == inr) && (irq->devno == devno));
317,6 → 349,17
return rv;
}
 
/** Unlock IRQ structure after hash_table_remove().
*
* @param lnk Link in the removed and locked IRQ structure.
*/
void irq_ht_remove(link_t *lnk)
{
irq_t *irq __attribute__((unused))
= hash_table_get_instance(lnk, irq_t, link);
spinlock_unlock(&irq->lock);
}
 
/** Compute hash index for the key.
*
* This function computes hash index into
328,7 → 371,7
*
* @return Index into the hash table.
*/
index_t irq_lin_hash(unative_t key[])
size_t irq_lin_hash(unative_t key[])
{
inr_t inr = (inr_t) key[KEY_INR];
return inr;
354,7 → 397,7
*
* @return True on match or false otherwise.
*/
bool irq_lin_compare(unative_t key[], count_t keys, link_t *item)
bool irq_lin_compare(unative_t key[], size_t keys, link_t *item)
{
irq_t *irq = list_get_instance(item, irq_t, link);
devno_t devno = (devno_t) key[KEY_DEVNO];
363,7 → 406,7
spinlock_lock(&irq->lock);
if (devno == -1) {
/* Invoked by irq_dispatch_and_lock() */
rv = (irq->claim() == IRQ_ACCEPT);
rv = (irq->claim(irq) == IRQ_ACCEPT);
} else {
/* Invoked by irq_find_and_lock() */
rv = (irq->devno == devno);
376,5 → 419,16
return rv;
}
 
/** Unlock IRQ structure after hash_table_remove().
*
* @param lnk Link in the removed and locked IRQ structure.
*/
void irq_lin_remove(link_t *lnk)
{
irq_t *irq __attribute__((unused))
= hash_table_get_instance(lnk, irq_t, link);
spinlock_unlock(&irq->lock);
}
 
/** @}
*/
/branches/arm/kernel/generic/src/ddi/device.c
31,7 → 31,7
*/
/**
* @file
* @brief Device numbers.
* @brief Device numbers.
*/
 
#include <arch/types.h>
47,13 → 47,16
*/
devno_t device_assign_devno(void)
{
devno_t devno;
 
devno = (devno_t) atomic_postinc(&last);
devno_t devno = (devno_t) atomic_postinc(&last);
ASSERT(devno >= 0);
 
return devno;
}
 
unative_t sys_device_assign_devno(void)
{
return (unative_t) device_assign_devno();
}
 
/** @}
*/
/branches/arm/kernel/generic/src/console/console.c
39,79 → 39,70
#include <synch/waitq.h>
#include <synch/spinlock.h>
#include <arch/types.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <ddi/ddi.h>
#include <ipc/event.h>
#include <ipc/irq.h>
#include <arch.h>
#include <func.h>
#include <print.h>
#include <putchar.h>
#include <atomic.h>
#include <syscall/copy.h>
#include <errno.h>
#include <string.h>
 
#define KLOG_SIZE PAGE_SIZE
#define KLOG_LATENCY 8
#define KLOG_PAGES 4
#define KLOG_LENGTH (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
#define KLOG_LATENCY 8
 
/**< Kernel log cyclic buffer */
static char klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
/** Kernel log cyclic buffer */
static wchar_t klog[KLOG_LENGTH] __attribute__ ((aligned (PAGE_SIZE)));
 
/**< Kernel log initialized */
/** Kernel log initialized */
static bool klog_inited = false;
/**< First kernel log characters */
static index_t klog_start = 0;
/**< Number of valid kernel log characters */
/** First kernel log characters */
static size_t klog_start = 0;
/** Number of valid kernel log characters */
static size_t klog_len = 0;
/**< Number of stored (not printed) kernel log characters */
/** Number of stored (not printed) kernel log characters */
static size_t klog_stored = 0;
/**< Number of stored kernel log characters for uspace */
/** Number of stored kernel log characters for uspace */
static size_t klog_uspace = 0;
 
/**< Kernel log spinlock */
/** Kernel log spinlock */
SPINLOCK_INITIALIZE(klog_lock);
 
/** Physical memory area used for klog buffer */
static parea_t klog_parea;
/*
* For now, we use 0 as INR.
* However, it is therefore desirable to have architecture specific
* definition of KLOG_VIRT_INR in the future.
*/
#define KLOG_VIRT_INR 0
 
static irq_t klog_irq;
 
static chardev_operations_t null_stdout_ops = {
.suspend = NULL,
.resume = NULL,
.write = NULL,
.read = NULL
static indev_operations_t stdin_ops = {
.poll = NULL
};
 
chardev_t null_stdout = {
.name = "null",
.op = &null_stdout_ops
};
/** Silence output */
bool silent = false;
 
/** Allways refuse IRQ ownership.
*
* This is not a real IRQ, so we always decline.
*
* @return Always returns IRQ_DECLINE.
*/
static irq_ownership_t klog_claim(void)
/** Standard input and output character devices */
indev_t *stdin = NULL;
outdev_t *stdout = NULL;
 
indev_t *stdin_wire(void)
{
return IRQ_DECLINE;
if (stdin == NULL) {
stdin = malloc(sizeof(indev_t), FRAME_ATOMIC);
if (stdin != NULL)
indev_initialize("stdin", stdin, &stdin_ops);
}
return stdin;
}
 
/** Standard input character device */
chardev_t *stdin = NULL;
chardev_t *stdout = &null_stdout;
 
/** Initialize kernel logging facility
*
* The shared area contains kernel cyclic buffer. Userspace application may
* be notified on new data with indication of position and size
* of the data within the circular buffer.
*
*/
void klog_init(void)
{
118,26 → 109,13
void *faddr = (void *) KA2PA(klog);
ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
ASSERT(KLOG_SIZE % FRAME_SIZE == 0);
 
devno_t devno = device_assign_devno();
klog_parea.pbase = (uintptr_t) faddr;
klog_parea.vbase = (uintptr_t) klog;
klog_parea.frames = SIZE2FRAMES(KLOG_SIZE);
klog_parea.cacheable = true;
klog_parea.frames = SIZE2FRAMES(sizeof(klog));
ddi_parea_register(&klog_parea);
 
sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr);
sysinfo_set_item_val("klog.pages", NULL, SIZE2FRAMES(KLOG_SIZE));
sysinfo_set_item_val("klog.devno", NULL, devno);
sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR);
 
irq_initialize(&klog_irq);
klog_irq.devno = devno;
klog_irq.inr = KLOG_VIRT_INR;
klog_irq.claim = klog_claim;
irq_register(&klog_irq);
sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
spinlock_lock(&klog_lock);
klog_inited = true;
144,91 → 122,88
spinlock_unlock(&klog_lock);
}
 
/** Get character from character device. Do not echo character.
*
* @param chardev Character device.
*
* @return Character read.
*/
uint8_t _getc(chardev_t *chardev)
void grab_console(void)
{
uint8_t ch;
ipl_t ipl;
bool prev = silent;
silent = false;
arch_grab_console();
/* Force the console to print the prompt */
if ((stdin) && (prev))
indev_push_character(stdin, '\n');
}
 
if (atomic_get(&haltstate)) {
/* If we are here, we are hopefully on the processor, that
* issued the 'halt' command, so proceed to read the character
* directly from input
*/
if (chardev->op->read)
return chardev->op->read(chardev);
/* no other way of interacting with user, halt */
if (CPU)
printf("cpu%u: ", CPU->id);
else
printf("cpu: ");
printf("halted - no kconsole\n");
cpu_halt();
}
void release_console(void)
{
silent = true;
arch_release_console();
}
 
waitq_sleep(&chardev->wq);
ipl = interrupts_disable();
spinlock_lock(&chardev->lock);
ch = chardev->buffer[(chardev->index - chardev->counter) % CHARDEV_BUFLEN];
chardev->counter--;
spinlock_unlock(&chardev->lock);
interrupts_restore(ipl);
/** Tell kernel to get keyboard/console access again */
unative_t sys_debug_enable_console(void)
{
#ifdef CONFIG_KCONSOLE
grab_console();
return true;
#else
return false;
#endif
}
 
chardev->op->resume(chardev);
 
return ch;
/** Tell kernel to relinquish keyboard/console access */
unative_t sys_debug_disable_console(void)
{
release_console();
return true;
}
 
/** Get string from character device.
/** Get string from input character device.
*
* Read characters from character device until first occurrence
* Read characters from input character device until first occurrence
* of newline character.
*
* @param chardev Character device.
* @param buf Buffer where to store string terminated by '\0'.
* @param indev Input character device.
* @param buf Buffer where to store string terminated by NULL.
* @param buflen Size of the buffer.
*
* @return Number of characters read.
*
*/
count_t gets(chardev_t *chardev, char *buf, size_t buflen)
size_t gets(indev_t *indev, char *buf, size_t buflen)
{
index_t index = 0;
char ch;
 
while (index < buflen) {
ch = _getc(chardev);
size_t offset = 0;
size_t count = 0;
buf[offset] = 0;
wchar_t ch;
while ((ch = indev_pop_character(indev)) != '\n') {
if (ch == '\b') {
if (index > 0) {
index--;
/* Space backspace, space */
if (count > 0) {
/* Space, backspace, space */
putchar('\b');
putchar(' ');
putchar('\b');
count--;
offset = str_lsize(buf, count);
buf[offset] = 0;
}
continue;
}
putchar(ch);
 
if (ch == '\n') { /* end of string => write 0, return */
buf[index] = '\0';
return (count_t) index;
}
buf[index++] = ch;
if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
putchar(ch);
count++;
buf[offset] = 0;
}
}
return (count_t) index;
return count;
}
 
/** Get character from device & echo it to screen */
uint8_t getc(chardev_t *chardev)
/** Get character from input device & echo it to screen */
wchar_t getc(indev_t *indev)
{
uint8_t ch;
 
ch = _getc(chardev);
wchar_t ch = indev_pop_character(indev);
putchar(ch);
return ch;
}
237,8 → 212,8
{
spinlock_lock(&klog_lock);
if ((klog_inited) && (klog_irq.notif_cfg.notify) && (klog_uspace > 0)) {
ipc_irq_send_msg_3(&klog_irq, klog_start, klog_len, klog_uspace);
if ((klog_inited) && (event_is_subscribed(EVENT_KLOG)) && (klog_uspace > 0)) {
event_notify_3(EVENT_KLOG, klog_start, klog_len, klog_uspace);
klog_uspace = 0;
}
245,27 → 220,27
spinlock_unlock(&klog_lock);
}
 
void putchar(char c)
void putchar(const wchar_t ch)
{
spinlock_lock(&klog_lock);
if ((klog_stored > 0) && (stdout->op->write)) {
if ((klog_stored > 0) && (stdout) && (stdout->op->write)) {
/* Print charaters stored in kernel log */
index_t i;
size_t i;
for (i = klog_len - klog_stored; i < klog_len; i++)
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE]);
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
klog_stored = 0;
}
/* Store character in the cyclic kernel log */
klog[(klog_start + klog_len) % KLOG_SIZE] = c;
if (klog_len < KLOG_SIZE)
klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
if (klog_len < KLOG_LENGTH)
klog_len++;
else
klog_start = (klog_start + 1) % KLOG_SIZE;
klog_start = (klog_start + 1) % KLOG_LENGTH;
if (stdout->op->write)
stdout->op->write(stdout, c);
if ((stdout) && (stdout->op->write))
stdout->op->write(stdout, ch, silent);
else {
/* The character is just in the kernel log */
if (klog_stored < klog_len)
278,7 → 253,7
/* Check notify uspace to update */
bool update;
if ((klog_uspace > KLOG_LATENCY) || (c == '\n'))
if ((klog_uspace > KLOG_LATENCY) || (ch == '\n'))
update = true;
else
update = false;
289,5 → 264,38
klog_update();
}
 
/** Print using kernel facility
*
* Print to kernel log.
*
*/
unative_t sys_klog(int fd, const void *buf, size_t size)
{
char *data;
int rc;
if (size > PAGE_SIZE)
return ELIMIT;
if (size > 0) {
data = (char *) malloc(size + 1, 0);
if (!data)
return ENOMEM;
rc = copy_from_uspace(data, buf, size);
if (rc) {
free(data);
return rc;
}
data[size] = 0;
printf("%s", data);
free(data);
} else
klog_update();
return size;
}
 
/** @}
*/
/branches/arm/kernel/generic/src/console/cmd.c
31,8 → 31,8
*/
 
/**
* @file cmd.c
* @brief Kernel console command wrappers.
* @file cmd.c
* @brief Kernel console command wrappers.
*
* This file is meant to contain all wrapper functions for
* all kconsole commands. The point is in separating
50,9 → 50,9
#include <arch.h>
#include <config.h>
#include <func.h>
#include <string.h>
#include <macros.h>
#include <debug.h>
#include <symtab.h>
#include <cpu.h>
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
64,6 → 64,9
#include <proc/task.h>
#include <ipc/ipc.h>
#include <ipc/irq.h>
#include <ipc/event.h>
#include <symtab.h>
#include <errno.h>
 
#ifdef CONFIG_TEST
#include <test.h>
78,12 → 81,6
.argc = 0
};
 
static cmd_info_t exit_info = {
.name = "exit",
.description = "Exit kconsole.",
.argc = 0
};
 
static int cmd_reboot(cmd_arg_t *argv);
static cmd_info_t reboot_info = {
.name = "reboot",
456,7 → 453,6
&continue_info,
&cpus_info,
&desc_info,
&exit_info,
&reboot_info,
&uptime_info,
&halt_info,
501,7 → 497,7
for (i = 0; basic_commands[i]; i++) {
cmd_initialize(basic_commands[i]);
if (!cmd_register(basic_commands[i]))
panic("could not register command %s\n", basic_commands[i]->name);
printf("Cannot register command %s\n", basic_commands[i]->name);
}
}
 
514,23 → 510,31
*/
int cmd_help(cmd_arg_t *argv)
{
link_t *cur;
 
spinlock_lock(&cmd_lock);
link_t *cur;
size_t len = 0;
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
if (str_length(hlp->name) > len)
len = str_length(hlp->name);
spinlock_unlock(&hlp->lock);
}
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
printf("%s - %s\n", hlp->name, hlp->description);
 
printf("%-*s %s\n", len, hlp->name, hlp->description);
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
 
spinlock_unlock(&cmd_lock);
return 1;
}
 
578,7 → 582,7
int cmd_desc(cmd_arg_t *argv)
{
link_t *cur;
 
spinlock_lock(&cmd_lock);
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
586,8 → 590,8
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
 
if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
if (str_lcmp(hlp->name, (const char *) argv->buffer, str_length(hlp->name)) == 0) {
printf("%s - %s\n", hlp->name, hlp->description);
if (hlp->help)
hlp->help();
594,12 → 598,12
spinlock_unlock(&hlp->lock);
break;
}
 
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
 
return 1;
}
 
616,33 → 620,26
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(void);
#ifdef ia64
struct {
unative_t f;
unative_t gp;
} fptr;
#endif
unative_t (*fnc)(void);
fncptr_t fptr;
int rc;
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
if (rc == ENOENT)
printf("Symbol %s not found.\n", symbol);
else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else if (rc == EOK) {
fnc = (unative_t (*)(void)) arch_construct_function(&fptr,
(void *) symaddr, (void *) cmd_call0);
printf("Calling %s() (%p)\n", symbol, symaddr);
printf("Result: %#" PRIxn "\n", fnc());
} else {
symbol = get_symtab_entry(symaddr);
printf("Calling %s() (%p)\n", symbol, symaddr);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(void)) &fptr;
#else
f = (unative_t (*)(void)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f());
printf("No symbol information available.\n");
}
return 1;
}
 
654,7 → 651,7
* call the function.
*/
count_t i;
size_t i;
for (i = 0; i < config.cpu_count; i++) {
if (!cpus[i].active)
continue;
680,35 → 677,27
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,...);
unative_t (*fnc)(unative_t, ...);
unative_t arg1 = argv[1].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
} fptr;
#endif
fncptr_t fptr;
int rc;
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
if (rc == ENOENT) {
printf("Symbol %s not found.\n", symbol);
} else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else if (rc == EOK) {
fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1);
printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
printf("Result: %#" PRIxn "\n", fnc(arg1));
} else {
symbol = get_symtab_entry(symaddr);
printf("No symbol information available.\n");
}
 
printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,...)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f(arg1));
}
return 1;
}
 
717,36 → 706,28
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,unative_t,...);
unative_t (*fnc)(unative_t, unative_t, ...);
unative_t arg1 = argv[1].intval;
unative_t arg2 = argv[2].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
fncptr_t fptr;
int rc;
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
if (rc == ENOENT) {
printf("Symbol %s not found.\n", symbol);
} else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
} else if (rc == EOK) {
fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2);
printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n",
arg1, arg2, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,unative_t,...)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f(arg1, arg2));
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
} else {
printf("No symbol information available.\n");
}
return 1;
}
 
755,37 → 736,29
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,unative_t,unative_t,...);
unative_t (*fnc)(unative_t, unative_t, unative_t, ...);
unative_t arg1 = argv[1].intval;
unative_t arg2 = argv[2].intval;
unative_t arg3 = argv[3].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
fncptr_t fptr;
int rc;
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
if (rc == ENOENT) {
printf("Symbol %s not found.\n", symbol);
} else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
} else if (rc == EOK) {
fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3);
printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n",
arg1, arg2, arg3, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f(arg1, arg2, arg3));
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
} else {
printf("No symbol information available.\n");
}
return 1;
}
 
835,30 → 808,34
/** Write 4 byte value to address */
int cmd_set4(cmd_arg_t *argv)
{
uint32_t *addr;
uintptr_t addr;
uint32_t arg1 = argv[1].intval;
bool pointer = false;
int rc;
 
if (((char *)argv->buffer)[0] == '*') {
addr = (uint32_t *) get_symbol_addr((char *) argv->buffer + 1);
rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr);
pointer = true;
} else if (((char *) argv->buffer)[0] >= '0' &&
((char *)argv->buffer)[0] <= '9')
addr = (uint32_t *)atoi((char *)argv->buffer);
else
addr = (uint32_t *)get_symbol_addr((char *) argv->buffer);
((char *)argv->buffer)[0] <= '9') {
rc = EOK;
addr = atoi((char *)argv->buffer);
} else {
rc = symtab_addr_lookup((char *) argv->buffer, &addr);
}
 
if (!addr)
if (rc == ENOENT)
printf("Symbol %s not found.\n", argv->buffer);
else if (addr == (uint32_t *) -1) {
else if (rc == EOVERFLOW) {
symtab_print_search((char *) argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
} else if (rc == EOK) {
if (pointer)
addr = (uint32_t *)(*(unative_t *)addr);
addr = *(uintptr_t *) addr;
printf("Writing %#" PRIx64 " -> %p\n", arg1, addr);
*addr = arg1;
*(uint32_t *) addr = arg1;
} else {
printf("No symbol information available.\n");
}
return 1;
976,8 → 953,11
int cmd_continue(cmd_arg_t *argv)
{
printf("The kernel will now relinquish the console.\n");
printf("Use userspace controls to redraw the screen.\n");
arch_release_console();
release_console();
event_notify_0(EVENT_KCONSOLE);
indev_pop_character(stdin);
return 1;
}
 
990,18 → 970,23
*/
int cmd_tests(cmd_arg_t *argv)
{
size_t len = 0;
test_t *test;
for (test = tests; test->name != NULL; test++) {
if (str_length(test->name) > len)
len = str_length(test->name);
}
for (test = tests; test->name != NULL; test++)
printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("*\t\tRun all safe tests\n");
printf("%-*s Run all safe tests\n", len, "*");
return 1;
}
 
static bool run_test(const test_t *test)
{
printf("%s\t\t%s\n", test->name, test->desc);
printf("%s (%s)\n", test->name, test->desc);
/* Update and read thread accounting
for benchmarking */
1012,7 → 997,8
interrupts_restore(ipl);
/* Execute the test */
char * ret = test->entry(false);
test_quiet = false;
char *ret = test->entry();
/* Update and read thread accounting */
ipl = interrupts_disable();
1064,7 → 1050,8
interrupts_restore(ipl);
/* Execute the test */
char * ret = test->entry(true);
test_quiet = true;
char * ret = test->entry();
/* Update and read thread accounting */
ipl = interrupts_disable();
1112,7 → 1099,7
{
test_t *test;
if (strcmp((char *) argv->buffer, "*") == 0) {
if (str_cmp((char *) argv->buffer, "*") == 0) {
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
printf("\n");
1124,7 → 1111,7
bool fnd = false;
for (test = tests; test->name != NULL; test++) {
if (strcmp(test->name, (char *) argv->buffer) == 0) {
if (str_cmp(test->name, (char *) argv->buffer) == 0) {
fnd = true;
run_test(test);
break;
1149,24 → 1136,33
test_t *test;
uint32_t cnt = argv[1].intval;
bool fnd = false;
for (test = tests; test->name != NULL; test++) {
if (strcmp(test->name, (char *) argv->buffer) == 0) {
fnd = true;
if (test->safe)
run_bench(test, cnt);
else
printf("Unsafe test\n");
break;
if (str_cmp((char *) argv->buffer, "*") == 0) {
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
if (!run_bench(test, cnt))
break;
}
}
} else {
bool fnd = false;
for (test = tests; test->name != NULL; test++) {
if (str_cmp(test->name, (char *) argv->buffer) == 0) {
fnd = true;
if (test->safe)
run_bench(test, cnt);
else
printf("Unsafe test\n");
break;
}
}
if (!fnd)
printf("Unknown test\n");
}
if (!fnd)
printf("Unknown test\n");
 
return 1;
}
 
/branches/arm/kernel/generic/src/console/kconsole.c
31,10 → 31,11
*/
 
/**
* @file kconsole.c
* @brief Kernel console.
* @file kconsole.c
* @brief Kernel console.
*
* This file contains kernel thread managing the kernel console.
*
*/
 
#include <console/kconsole.h>
49,8 → 50,14
#include <macros.h>
#include <debug.h>
#include <func.h>
#include <string.h>
#include <macros.h>
#include <sysinfo/sysinfo.h>
#include <ddi/device.h>
#include <symtab.h>
#include <macros.h>
#include <errno.h>
#include <putchar.h>
#include <string.h>
 
/** Simple kernel console.
*
59,7 → 66,7
* but makes it possible for other kernel subsystems to
* register their own commands.
*/
 
/** Locking.
*
* There is a list of cmd_info_t structures. This list
74,33 → 81,36
* When locking two cmd info structures, structure with
* lower address must be locked first.
*/
SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */
LIST_INITIALIZE(cmd_head); /**< Command list. */
 
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
static bool parse_argument(char *cmdline, size_t len, index_t *start,
index_t *end);
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */
LIST_INITIALIZE(cmd_head); /**< Command list. */
 
/** Initialize kconsole data structures. */
static wchar_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
static size_t history_pos = 0;
 
/** Initialize kconsole data structures
*
* This is the most basic initialization, almost no
* other kernel subsystem is ready yet.
*
*/
void kconsole_init(void)
{
int i;
 
unsigned int i;
cmd_init();
for (i = 0; i < KCONSOLE_HISTORY; i++)
history[i][0] = '\0';
history[i][0] = 0;
}
 
 
/** Register kconsole command.
*
* @param cmd Structure describing the command.
*
* @return 0 on failure, 1 on success.
* @return False on failure, true on success.
*
*/
int cmd_register(cmd_info_t *cmd)
bool cmd_register(cmd_info_t *cmd)
{
link_t *cur;
110,16 → 120,14
* Make sure the command is not already listed.
*/
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
hlp = list_get_instance(cur, cmd_info_t, link);
 
if (hlp == cmd) {
/* The command is already there. */
spinlock_unlock(&cmd_lock);
return 0;
return false;
}
 
/* Avoid deadlock. */
if (hlp < cmd) {
spinlock_lock(&hlp->lock);
128,13 → 136,13
spinlock_lock(&cmd->lock);
spinlock_lock(&hlp->lock);
}
if ((strncmp(hlp->name, cmd->name, max(strlen(cmd->name),
strlen(hlp->name))) == 0)) {
if (str_cmp(hlp->name, cmd->name) == 0) {
/* The command is already there. */
spinlock_unlock(&hlp->lock);
spinlock_unlock(&cmd->lock);
spinlock_unlock(&cmd_lock);
return 0;
return false;
}
spinlock_unlock(&hlp->lock);
147,294 → 155,274
list_append(&cmd->link, &cmd_head);
spinlock_unlock(&cmd_lock);
return 1;
return true;
}
 
/** Print count times a character */
static void rdln_print_c(char ch, int count)
static void print_cc(wchar_t ch, size_t count)
{
int i;
size_t i;
for (i = 0; i < count; i++)
putchar(ch);
}
 
/** Insert character to string */
static void insert_char(char *str, char ch, int pos)
/** Try to find a command beginning with prefix */
static const char *cmdtab_search_one(const char *name, link_t **startpos)
{
int i;
size_t namelen = str_length(name);
for (i = strlen(str); i > pos; i--)
str[i] = str[i - 1];
str[pos] = ch;
}
 
/** Try to find a command beginning with prefix */
static const char *cmdtab_search_one(const char *name,link_t **startpos)
{
size_t namelen = strlen(name);
const char *curname;
 
spinlock_lock(&cmd_lock);
 
if (!*startpos)
if (*startpos == NULL)
*startpos = cmd_head.next;
 
for (; *startpos != &cmd_head; *startpos = (*startpos)->next) {
cmd_info_t *hlp;
hlp = list_get_instance(*startpos, cmd_info_t, link);
 
curname = hlp->name;
if (strlen(curname) < namelen)
cmd_info_t *hlp = list_get_instance(*startpos, cmd_info_t, link);
const char *curname = hlp->name;
if (str_length(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
spinlock_unlock(&cmd_lock);
return curname+namelen;
if (str_lcmp(curname, name, namelen) == 0) {
spinlock_unlock(&cmd_lock);
return (curname + str_lsize(curname, namelen));
}
}
spinlock_unlock(&cmd_lock);
spinlock_unlock(&cmd_lock);
return NULL;
}
 
 
/** Command completion of the commands
/** Command completion of the commands
*
* @param name - string to match, changed to hint on exit
* @return number of found matches
* @param name String to match, changed to hint on exit
* @param size Input buffer size
*
* @return Number of found matches
*
*/
static int cmdtab_compl(char *name)
static int cmdtab_compl(char *input, size_t size)
{
static char output[MAX_SYMBOL_NAME + 1];
link_t *startpos = NULL;
const char *foundtxt;
int found = 0;
int i;
 
output[0] = '\0';
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
startpos = startpos->next;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt) + 1);
else {
for (i = 0; output[i] && foundtxt[i] &&
output[i] == foundtxt[i]; i++)
;
output[i] = '\0';
}
const char *name = input;
size_t found = 0;
link_t *pos = NULL;
const char *hint;
char output[MAX_CMDLINE];
output[0] = 0;
while ((hint = cmdtab_search_one(name, &pos))) {
if ((found == 0) || (str_length(output) > str_length(hint)))
str_cpy(output, MAX_CMDLINE, hint);
pos = pos->next;
found++;
}
if (!found)
return 0;
 
if (found > 1 && !strlen(output)) {
if ((found > 1) && (str_length(output) != 0)) {
printf("\n");
startpos = NULL;
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
cmd_info_t *hlp;
hlp = list_get_instance(startpos, cmd_info_t, link);
printf("%s - %s\n", hlp->name, hlp->description);
startpos = startpos->next;
pos = NULL;
while ((hint = cmdtab_search_one(name, &pos))) {
cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
printf("%s (%s)\n", hlp->name, hlp->description);
pos = pos->next;
}
}
strncpy(name, output, MAX_SYMBOL_NAME);
if (found > 0)
str_cpy(input, size, output);
return found;
}
 
static char *clever_readline(const char *prompt, chardev_t *input)
static wchar_t *clever_readline(const char *prompt, indev_t *indev)
{
static int histposition = 0;
 
static char tmp[MAX_CMDLINE + 1];
int curlen = 0, position = 0;
char *current = history[histposition];
int i;
char mod; /* Command Modifier */
char c;
 
printf("%s> ", prompt);
while (1) {
c = _getc(input);
if (c == '\n') {
putchar(c);
size_t position = 0;
wchar_t *current = history[history_pos];
current[0] = 0;
while (true) {
wchar_t ch = indev_pop_character(indev);
if (ch == '\n') {
/* Enter */
putchar(ch);
break;
}
if (c == '\b') { /* Backspace */
if (ch == '\b') {
/* Backspace */
if (position == 0)
continue;
for (i = position; i < curlen; i++)
current[i - 1] = current[i];
curlen--;
position--;
putchar('\b');
for (i = position; i < curlen; i++)
putchar(current[i]);
putchar(' ');
rdln_print_c('\b', curlen - position + 1);
continue;
if (wstr_remove(current, position - 1)) {
position--;
putchar('\b');
printf("%ls ", current + position);
print_cc('\b', wstr_length(current) - position + 1);
continue;
}
}
if (c == '\t') { /* Tabulator */
int found;
 
if (ch == '\t') {
/* Tab completion */
/* Move to the end of the word */
for (; position < curlen && current[position] != ' ';
for (; (current[position] != 0) && (!isspace(current[position]));
position++)
putchar(current[position]);
/* Copy to tmp last word */
for (i = position - 1; i >= 0 && current[i] != ' '; i--)
;
/* If word begins with * or &, skip it */
if (tmp[0] == '*' || tmp[0] == '&')
for (i = 1; tmp[i]; i++)
tmp[i - 1] = tmp[i];
i++; /* I is at the start of the word */
strncpy(tmp, current + i, position - i + 1);
 
if (i == 0) { /* Command completion */
found = cmdtab_compl(tmp);
} else { /* Symtab completion */
found = symtab_compl(tmp);
if (position == 0)
continue;
/* Find the beginning of the word
and copy it to tmp */
size_t beg;
for (beg = position - 1; (beg > 0) && (!isspace(current[beg]));
beg--);
if (isspace(current[beg]))
beg++;
char tmp[STR_BOUNDS(MAX_CMDLINE)];
wstr_nstr(tmp, current + beg, position - beg + 1);
int found;
if (beg == 0) {
/* Command completion */
found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
} else {
/* Symbol completion */
found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
}
 
if (found == 0)
if (found == 0)
continue;
for (i = 0; tmp[i] && curlen < MAX_CMDLINE;
i++, curlen++)
insert_char(current, tmp[i], i + position);
 
if (strlen(tmp) || found == 1) { /* If we have a hint */
for (i = position; i < curlen; i++)
putchar(current[i]);
position += strlen(tmp);
/* Add space to end */
if (found == 1 && position == curlen &&
curlen < MAX_CMDLINE) {
current[position] = ' ';
curlen++;
if (found > 1) {
/* No unique hint, list was printed */
printf("%s> ", prompt);
printf("%ls", current);
print_cc('\b', wstr_length(current) - position);
continue;
}
/* We have a hint */
size_t off = 0;
size_t i = 0;
while ((ch = str_decode(tmp, &off, STR_NO_LIMIT)) != 0) {
if (!wstr_linsert(current, ch, position + i, MAX_CMDLINE))
break;
i++;
}
printf("%ls", current + position);
position += str_length(tmp);
print_cc('\b', wstr_length(current) - position);
if (position == wstr_length(current)) {
/* Insert a space after the last completed argument */
if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) {
printf("%ls", current + position);
position++;
putchar(' ');
}
} else { /* No hint, table was printed */
printf("%s> ", prompt);
for (i = 0; i < curlen; i++)
putchar(current[i]);
position += strlen(tmp);
}
rdln_print_c('\b', curlen - position);
continue;
}
if (c == 0x1b) { /* Special command */
mod = _getc(input);
c = _getc(input);
 
if (mod != 0x5b && mod != 0x4f)
continue;
 
if (c == 0x33 && _getc(input) == 0x7e) {
/* Delete */
if (position == curlen)
continue;
for (i = position + 1; i < curlen; i++) {
putchar(current[i]);
current[i - 1] = current[i];
}
putchar(' ');
rdln_print_c('\b', curlen - position);
curlen--;
} else if (c == 0x48) { /* Home */
rdln_print_c('\b', position);
position = 0;
} else if (c == 0x46) { /* End */
for (i = position; i < curlen; i++)
putchar(current[i]);
position = curlen;
} else if (c == 0x44) { /* Left */
if (position > 0) {
putchar('\b');
position--;
}
continue;
} else if (c == 0x43) { /* Right */
if (position < curlen) {
putchar(current[position]);
position++;
}
continue;
} else if (c == 0x41 || c == 0x42) {
/* Up, down */
rdln_print_c('\b', position);
rdln_print_c(' ', curlen);
rdln_print_c('\b', curlen);
if (c == 0x41) /* Up */
histposition--;
if (ch == U_LEFT_ARROW) {
/* Left */
if (position > 0) {
putchar('\b');
position--;
}
continue;
}
if (ch == U_RIGHT_ARROW) {
/* Right */
if (position < wstr_length(current)) {
putchar(current[position]);
position++;
}
continue;
}
if ((ch == U_UP_ARROW) || (ch == U_DOWN_ARROW)) {
/* Up, down */
print_cc('\b', position);
print_cc(' ', wstr_length(current));
print_cc('\b', wstr_length(current));
if (ch == U_UP_ARROW) {
/* Up */
if (history_pos == 0)
history_pos = KCONSOLE_HISTORY - 1;
else
histposition++;
if (histposition < 0) {
histposition = KCONSOLE_HISTORY - 1;
} else {
histposition =
histposition % KCONSOLE_HISTORY;
}
current = history[histposition];
printf("%s", current);
curlen = strlen(current);
position = curlen;
history_pos--;
} else {
/* Down */
history_pos++;
history_pos = history_pos % KCONSOLE_HISTORY;
}
current = history[history_pos];
printf("%ls", current);
position = wstr_length(current);
continue;
}
if (ch == U_HOME_ARROW) {
/* Home */
print_cc('\b', position);
position = 0;
continue;
}
if (ch == U_END_ARROW) {
/* End */
printf("%ls", current + position);
position = wstr_length(current);
continue;
}
if (ch == U_DELETE) {
/* Delete */
if (position == wstr_length(current))
continue;
if (wstr_remove(current, position)) {
printf("%ls ", current + position);
print_cc('\b', wstr_length(current) - position + 1);
}
continue;
}
if (curlen >= MAX_CMDLINE)
continue;
 
insert_char(current, c, position);
 
curlen++;
for (i = position; i < curlen; i++)
putchar(current[i]);
position++;
rdln_print_c('\b',curlen - position);
}
if (curlen) {
histposition++;
histposition = histposition % KCONSOLE_HISTORY;
if (wstr_linsert(current, ch, position, MAX_CMDLINE)) {
printf("%ls", current + position);
position++;
print_cc('\b', wstr_length(current) - position);
}
}
current[curlen] = '\0';
if (wstr_length(current) > 0) {
history_pos++;
history_pos = history_pos % KCONSOLE_HISTORY;
}
return current;
}
 
/** Kernel console managing thread.
*
* @param prompt Kernel console prompt (e.g kconsole/panic).
*/
void kconsole(void *prompt)
bool kconsole_check_poll(void)
{
cmd_info_t *cmd_info;
count_t len;
char *cmdline;
 
if (!stdin) {
printf("%s: no stdin\n", __func__);
return;
}
while (true) {
cmdline = clever_readline((char *) prompt, stdin);
len = strlen(cmdline);
if (!len)
continue;
cmd_info = parse_cmdline(cmdline, len);
if (!cmd_info)
continue;
if (strncmp(cmd_info->name, "exit",
min(strlen(cmd_info->name), 5)) == 0)
break;
(void) cmd_info->func(cmd_info->argv);
}
return check_poll(stdin);
}
 
static int parse_int_arg(char *text, size_t len, unative_t *result)
static bool parse_int_arg(const char *text, size_t len, unative_t *result)
{
static char symname[MAX_SYMBOL_NAME];
uintptr_t symaddr;
bool isaddr = false;
bool isptr = false;
448,63 → 436,113
text++;
len--;
}
if (text[0] < '0' || text[0] > '9') {
strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME));
symaddr = get_symbol_addr(symname);
if (!symaddr) {
if ((text[0] < '0') || (text[0] > '9')) {
char symname[MAX_SYMBOL_NAME];
str_ncpy(symname, MAX_SYMBOL_NAME, text, len + 1);
uintptr_t symaddr;
int rc = symtab_addr_lookup(symname, &symaddr);
switch (rc) {
case ENOENT:
printf("Symbol %s not found.\n", symname);
return -1;
}
if (symaddr == (uintptr_t) -1) {
return false;
case EOVERFLOW:
printf("Duplicate symbol %s.\n", symname);
symtab_print_search(symname);
return -1;
return false;
case ENOTSUP:
printf("No symbol information available.\n");
return false;
}
if (isaddr)
*result = (unative_t)symaddr;
*result = (unative_t) symaddr;
else if (isptr)
*result = **((unative_t **)symaddr);
*result = **((unative_t **) symaddr);
else
*result = *((unative_t *)symaddr);
} else { /* It's a number - convert it */
*result = *((unative_t *) symaddr);
} else {
/* It's a number - convert it */
*result = atoi(text);
if (isptr)
*result = *((unative_t *)*result);
*result = *((unative_t *) *result);
}
return true;
}
 
return 0;
/** Parse argument.
*
* Find start and end positions of command line argument.
*
* @param cmdline Command line as read from the input device.
* @param size Size (in bytes) of the string.
* @param start On entry, 'start' contains pointer to the offset
* of the first unprocessed character of cmdline.
* On successful exit, it marks beginning of the next argument.
* @param end Undefined on entry. On exit, 'end' is the offset of the first
* character behind the next argument.
*
* @return False on failure, true on success.
*
*/
static bool parse_argument(const char *cmdline, size_t size, size_t *start, size_t *end)
{
ASSERT(start != NULL);
ASSERT(end != NULL);
bool found_start = false;
size_t offset = *start;
size_t prev = *start;
wchar_t ch;
while ((ch = str_decode(cmdline, &offset, size)) != 0) {
if (!found_start) {
if (!isspace(ch)) {
*start = prev;
found_start = true;
}
} else {
if (isspace(ch))
break;
}
prev = offset;
}
*end = prev;
return found_start;
}
 
/** Parse command line.
*
* @param cmdline Command line as read from input device.
* @param len Command line length.
* @param cmdline Command line as read from input device.
* @param size Size (in bytes) of the string.
*
* @return Structure describing the command.
*
*/
cmd_info_t *parse_cmdline(char *cmdline, size_t len)
static cmd_info_t *parse_cmdline(const char *cmdline, size_t size)
{
index_t start = 0, end = 0;
cmd_info_t *cmd = NULL;
link_t *cur;
count_t i;
int error = 0;
if (!parse_argument(cmdline, len, &start, &end)) {
size_t start = 0;
size_t end = 0;
if (!parse_argument(cmdline, size, &start, &end)) {
/* Command line did not contain alphanumeric word. */
return NULL;
}
 
spinlock_lock(&cmd_lock);
cmd_info_t *cmd = NULL;
link_t *cur;
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
if (strncmp(hlp->name, &cmdline[start], max(strlen(hlp->name),
end - start + 1)) == 0) {
if (str_lcmp(hlp->name, cmdline + start,
max(str_length(hlp->name),
str_nlength(cmdline + start, (size_t) (end - start) - 1))) == 0) {
cmd = hlp;
break;
}
512,7 → 550,7
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
spinlock_unlock(&cmd_lock);
if (!cmd) {
/* Unknown command. */
519,7 → 557,7
printf("Unknown command.\n");
return NULL;
}
 
/* cmd == hlp is locked */
/*
528,52 → 566,54
* converted to those specified in the cmd info
* structure.
*/
 
bool error = false;
size_t i;
for (i = 0; i < cmd->argc; i++) {
char *buf;
start = end + 1;
if (!parse_argument(cmdline, len, &start, &end)) {
start = end;
if (!parse_argument(cmdline, size, &start, &end)) {
printf("Too few arguments.\n");
spinlock_unlock(&cmd->lock);
return NULL;
}
error = 0;
char *buf;
switch (cmd->argv[i].type) {
case ARG_TYPE_STRING:
buf = (char *) cmd->argv[i].buffer;
strncpy(buf, (const char *) &cmdline[start],
min((end - start) + 2, cmd->argv[i].len));
buf[min((end - start) + 1, cmd->argv[i].len - 1)] =
'\0';
str_ncpy(buf, cmd->argv[i].len, cmdline + start,
end - start);
break;
case ARG_TYPE_INT:
if (parse_int_arg(cmdline + start, end - start + 1,
case ARG_TYPE_INT:
if (!parse_int_arg(cmdline + start, end - start,
&cmd->argv[i].intval))
error = 1;
error = true;
break;
case ARG_TYPE_VAR:
if (start != end && cmdline[start] == '"' &&
cmdline[end] == '"') {
buf = (char *) cmd->argv[i].buffer;
strncpy(buf, (const char *) &cmdline[start + 1],
min((end-start), cmd->argv[i].len));
buf[min((end - start), cmd->argv[i].len - 1)] =
'\0';
cmd->argv[i].intval = (unative_t) buf;
cmd->argv[i].vartype = ARG_TYPE_STRING;
} else if (!parse_int_arg(cmdline + start,
end - start + 1, &cmd->argv[i].intval)) {
if ((start < end - 1) && (cmdline[start] == '"')) {
if (cmdline[end - 1] == '"') {
buf = (char *) cmd->argv[i].buffer;
str_ncpy(buf, cmd->argv[i].len,
cmdline + start + 1,
(end - start) - 1);
cmd->argv[i].intval = (unative_t) buf;
cmd->argv[i].vartype = ARG_TYPE_STRING;
} else {
printf("Wrong synxtax.\n");
error = true;
}
} else if (parse_int_arg(cmdline + start,
end - start, &cmd->argv[i].intval)) {
cmd->argv[i].vartype = ARG_TYPE_INT;
} else {
printf("Unrecognized variable argument.\n");
error = 1;
error = true;
}
break;
case ARG_TYPE_INVALID:
default:
printf("invalid argument type\n");
error = 1;
printf("Invalid argument type\n");
error = true;
break;
}
}
583,8 → 623,8
return NULL;
}
start = end + 1;
if (parse_argument(cmdline, len, &start, &end)) {
start = end;
if (parse_argument(cmdline, size, &start, &end)) {
printf("Too many arguments.\n");
spinlock_unlock(&cmd->lock);
return NULL;
594,42 → 634,55
return cmd;
}
 
/** Parse argument.
/** Kernel console prompt.
*
* Find start and end positions of command line argument.
* @param prompt Kernel console prompt (e.g kconsole/panic).
* @param msg Message to display in the beginning.
* @param kcon Wait for keypress to show the prompt
* and never exit.
*
* @param cmdline Command line as read from the input device.
* @param len Number of characters in cmdline.
* @param start On entry, 'start' contains pointer to the index
* of first unprocessed character of cmdline.
* On successful exit, it marks beginning of the next argument.
* @param end Undefined on entry. On exit, 'end' points to the last character
* of the next argument.
*
* @return false on failure, true on success.
*/
bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end)
void kconsole(char *prompt, char *msg, bool kcon)
{
index_t i;
bool found_start = false;
if (!stdin) {
LOG("No stdin for kernel console");
return;
}
ASSERT(start != NULL);
ASSERT(end != NULL);
if (msg)
printf("%s", msg);
for (i = *start; i < len; i++) {
if (!found_start) {
if (isspace(cmdline[i]))
(*start)++;
else
found_start = true;
} else {
if (isspace(cmdline[i]))
break;
}
if (kcon)
indev_pop_character(stdin);
else
printf("Type \"exit\" to leave the console.\n");
while (true) {
wchar_t *tmp = clever_readline((char *) prompt, stdin);
size_t len = wstr_length(tmp);
if (!len)
continue;
char cmdline[STR_BOUNDS(MAX_CMDLINE)];
wstr_nstr(cmdline, tmp, STR_BOUNDS(MAX_CMDLINE));
if ((!kcon) && (len == 4) && (str_lcmp(cmdline, "exit", 4) == 0))
break;
cmd_info_t *cmd_info = parse_cmdline(cmdline, STR_BOUNDS(MAX_CMDLINE));
if (!cmd_info)
continue;
(void) cmd_info->func(cmd_info->argv);
}
*end = i - 1;
}
 
return found_start;
/** Kernel console managing thread.
*
*/
void kconsole_thread(void *data)
{
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true);
}
 
/** @}
/branches/arm/kernel/generic/src/console/chardev.c
33,46 → 33,119
*/
 
#include <console/chardev.h>
#include <putchar.h>
#include <synch/waitq.h>
#include <synch/spinlock.h>
#include <print.h>
#include <func.h>
#include <arch.h>
 
/** Initialize character device.
/** Initialize input character device.
*
* @param chardev Character device.
* @param op Implementation of character device operations.
* @param indev Input character device.
* @param op Implementation of input character device operations.
*
*/
void chardev_initialize(char *name, chardev_t *chardev,
chardev_operations_t *op)
void indev_initialize(char *name, indev_t *indev,
indev_operations_t *op)
{
chardev->name = name;
 
waitq_initialize(&chardev->wq);
spinlock_initialize(&chardev->lock, "chardev");
chardev->counter = 0;
chardev->index = 0;
chardev->op = op;
indev->name = name;
waitq_initialize(&indev->wq);
spinlock_initialize(&indev->lock, "indev");
indev->counter = 0;
indev->index = 0;
indev->op = op;
}
 
/** Push character read from input character device.
*
* @param chardev Character device.
* @param ch Character being pushed.
* @param indev Input character device.
* @param ch Character being pushed.
*
*/
void chardev_push_character(chardev_t *chardev, uint8_t ch)
void indev_push_character(indev_t *indev, wchar_t ch)
{
spinlock_lock(&chardev->lock);
chardev->counter++;
if (chardev->counter == CHARDEV_BUFLEN - 1) {
/* buffer full => disable device interrupt */
chardev->op->suspend(chardev);
ASSERT(indev);
spinlock_lock(&indev->lock);
if (indev->counter == INDEV_BUFLEN - 1) {
/* Buffer full */
spinlock_unlock(&indev->lock);
return;
}
chardev->buffer[chardev->index++] = ch;
chardev->index = chardev->index % CHARDEV_BUFLEN; /* index modulo size of buffer */
waitq_wakeup(&chardev->wq, WAKEUP_FIRST);
spinlock_unlock(&chardev->lock);
indev->counter++;
indev->buffer[indev->index++] = ch;
/* Index modulo size of buffer */
indev->index = indev->index % INDEV_BUFLEN;
waitq_wakeup(&indev->wq, WAKEUP_FIRST);
spinlock_unlock(&indev->lock);
}
 
/** Pop character from input character device.
*
* @param indev Input character device.
*
* @return Character read.
*
*/
wchar_t indev_pop_character(indev_t *indev)
{
if (atomic_get(&haltstate)) {
/* If we are here, we are hopefully on the processor that
* issued the 'halt' command, so proceed to read the character
* directly from input
*/
if (check_poll(indev))
return indev->op->poll(indev);
/* No other way of interacting with user */
interrupts_disable();
if (CPU)
printf("cpu%u: ", CPU->id);
else
printf("cpu: ");
printf("halted (no polling input)\n");
cpu_halt();
}
waitq_sleep(&indev->wq);
ipl_t ipl = interrupts_disable();
spinlock_lock(&indev->lock);
wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN];
indev->counter--;
spinlock_unlock(&indev->lock);
interrupts_restore(ipl);
return ch;
}
 
/** Initialize output character device.
*
* @param outdev Output character device.
* @param op Implementation of output character device operations.
*
*/
void outdev_initialize(char *name, outdev_t *outdev,
outdev_operations_t *op)
{
outdev->name = name;
spinlock_initialize(&outdev->lock, "outdev");
outdev->op = op;
}
 
bool check_poll(indev_t *indev)
{
if (indev == NULL)
return false;
if (indev->op == NULL)
return false;
return (indev->op->poll != NULL);
}
 
/** @}
*/
/branches/arm/kernel/generic/src/proc/scheduler.c
451,7 → 451,7
/*
* Entering state is unexpected.
*/
panic("tid%" PRIu64 ": unexpected state %s\n",
panic("tid%" PRIu64 ": unexpected state %s.",
THREAD->tid, thread_states[THREAD->state]);
break;
}
708,7 → 708,7
continue;
 
spinlock_lock(&cpus[cpu].lock);
printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIc "\n",
printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
cpus[cpu].needs_relink);
/branches/arm/kernel/generic/src/proc/task.c
52,7 → 52,10
#include <print.h>
#include <errno.h>
#include <func.h>
#include <string.h>
#include <syscall/copy.h>
#include <macros.h>
#include <ipc/event.h>
 
/** Spinlock protecting the tasks_tree AVL tree. */
SPINLOCK_INITIALIZE(tasks_lock);
130,7 → 133,7
/** Create new task with no threads.
*
* @param as Task's address space.
* @param name Symbolic name.
* @param name Symbolic name (a copy is made).
*
* @return New task's structure.
*
148,7 → 151,10
spinlock_initialize(&ta->lock, "task_ta_lock");
list_initialize(&ta->th_head);
ta->as = as;
ta->name = name;
 
memcpy(ta->name, name, TASK_NAME_BUFLEN);
ta->name[TASK_NAME_BUFLEN - 1] = 0;
 
atomic_set(&ta->refcount, 0);
atomic_set(&ta->lifecount, 0);
ta->context = CONTEXT;
161,10 → 167,10
udebug_task_init(&ta->udebug);
 
/* Init kbox stuff */
ipc_answerbox_init(&ta->kernel_box, ta);
ta->kb_thread = NULL;
mutex_initialize(&ta->kb_cleanup_lock, MUTEX_PASSIVE);
ta->kb_finished = false;
ipc_answerbox_init(&ta->kb.box, ta);
ta->kb.thread = NULL;
mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
ta->kb.finished = false;
#endif
 
ipc_answerbox_init(&ta->answerbox, ta);
192,7 → 198,14
avltree_insert(&tasks_tree, &ta->tasks_tree_node);
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
 
/*
* Notify about task creation.
*/
if (event_is_subscribed(EVENT_WAIT))
event_notify_3(EVENT_WAIT, TASK_CREATE, LOWER32(ta->taskid),
UPPER32(ta->taskid));
return ta;
}
 
225,6 → 238,13
if (atomic_predec(&t->as->refcount) == 0)
as_destroy(t->as);
/*
* Notify about task destruction.
*/
if (event_is_subscribed(EVENT_WAIT))
event_notify_3(EVENT_WAIT, TASK_DESTROY, LOWER32(t->taskid),
UPPER32(t->taskid));
free(t);
TASK = NULL;
}
246,6 → 266,35
sizeof(TASK->taskid));
}
 
/** Syscall for setting the task name.
*
* The name simplifies identifying the task in the task list.
*
* @param name The new name for the task. (typically the same
* as the command used to execute it).
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_task_set_name(const char *uspace_name, size_t name_len)
{
int rc;
char namebuf[TASK_NAME_BUFLEN];
 
/* Cap length of name and copy it from userspace. */
 
if (name_len > TASK_NAME_BUFLEN - 1)
name_len = TASK_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return (unative_t) rc;
 
namebuf[name_len] = '\0';
str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
 
return EOK;
}
 
/** Find task structure corresponding to task ID.
*
* The tasks_lock must be already held by the caller of this function and
336,7 → 385,7
bool sleeping = false;
thr = list_get_instance(cur, thread_t, th_link);
spinlock_lock(&thr->lock);
thr->interrupted = true;
if (thr->state == Sleeping)
364,13 → 413,13
order(task_get_accounting(t), &cycles, &suffix);
 
#ifdef __32_BITS__
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64
printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
#endif
 
#ifdef __64_BITS__
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64
printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
#endif
395,16 → 444,16
spinlock_lock(&tasks_lock);
 
#ifdef __32_BITS__
printf("taskid name ctx address as "
printf("taskid name ctx address as "
"cycles threads calls callee\n");
printf("------ ---------- --- ---------- ---------- "
printf("------ ------------ --- ---------- ---------- "
"---------- ------- ------ ------>\n");
#endif
 
#ifdef __64_BITS__
printf("taskid name ctx address as "
printf("taskid name ctx address as "
"cycles threads calls callee\n");
printf("------ ---------- --- ------------------ ------------------ "
printf("------ ------------ --- ------------------ ------------------ "
"---------- ------- ------ ------>\n");
#endif
 
/branches/arm/kernel/generic/src/proc/program.c
67,9 → 67,10
*
* @param as Address space containing a binary program image.
* @param entry_addr Program entry-point address in program address space.
* @param name Name to set for the program's task.
* @param p Buffer for storing program information.
*/
void program_create(as_t *as, uintptr_t entry_addr, program_t *p)
void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p)
{
as_area_t *a;
uspace_arg_t *kernel_uarg;
81,7 → 82,7
kernel_uarg->uspace_thread_arg = NULL;
kernel_uarg->uspace_uarg = NULL;
p->task = task_create(as, "app");
p->task = task_create(as, name);
ASSERT(p->task);
 
/*
106,6 → 107,7
* executable image. The task is returned in *task.
*
* @param image_addr Address of an executable program image.
* @param name Name to set for the program's task.
* @param p Buffer for storing program info. If image_addr
* points to a loader image, p->task will be set to
* NULL and EOK will be returned.
112,7 → 114,7
*
* @return EOK on success or negative error code.
*/
int program_create_from_image(void *image_addr, program_t *p)
int program_create_from_image(void *image_addr, char *name, program_t *p)
{
as_t *as;
unsigned int rc;
131,12 → 133,12
/* Register image as the program loader */
ASSERT(program_loader == NULL);
program_loader = image_addr;
printf("Registered program loader at 0x%" PRIp "\n",
LOG("Registered program loader at 0x%" PRIp "\n",
image_addr);
return EOK;
}
 
program_create(as, ((elf_header_t *) image_addr)->e_entry, p);
program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p);
 
return EOK;
}
143,10 → 145,12
 
/** Create a task from the program loader image.
*
* @param p Buffer for storing program info.
* @param p Buffer for storing program info.
* @param name Name to set for the program's task.
*
* @return EOK on success or negative error code.
*/
int program_create_loader(program_t *p)
int program_create_loader(program_t *p, char *name)
{
as_t *as;
unsigned int rc;
167,7 → 171,8
return ENOENT;
}
 
program_create(as, ((elf_header_t *) program_loader)->e_entry, p);
program_create(as, ((elf_header_t *) program_loader)->e_entry,
name, p);
 
return EOK;
}
185,48 → 190,37
 
/** Syscall for creating a new loader instance from userspace.
*
* Creates a new task from the program loader image, connects a phone
* to it and stores the phone id into the provided buffer.
* Creates a new task from the program loader image and sets
* the task name.
*
* @param uspace_phone_id Userspace address where to store the phone id.
* @param name Name to set on the new task (typically the same
* as the command used to execute it).
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_program_spawn_loader(int *uspace_phone_id)
unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
{
program_t p;
int fake_id;
int rc;
int phone_id;
char namebuf[TASK_NAME_BUFLEN];
 
fake_id = 0;
/* Cap length of name and copy it from userspace. */
 
/* Before we even try creating the task, see if we can write the id */
rc = (unative_t) copy_to_uspace(uspace_phone_id, &fake_id,
sizeof(fake_id));
if (name_len > TASK_NAME_BUFLEN - 1)
name_len = TASK_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return rc;
return (unative_t) rc;
 
phone_id = phone_alloc();
if (phone_id < 0)
return ELIMIT;
namebuf[name_len] = 0;
 
rc = program_create_loader(&p);
/* Spawn the new task. */
 
rc = program_create_loader(&p, namebuf);
if (rc != 0)
return rc;
 
phone_connect(phone_id, &p.task->answerbox);
 
/* No need to aquire lock before task_ready() */
rc = (unative_t) copy_to_uspace(uspace_phone_id, &phone_id,
sizeof(phone_id));
if (rc != 0) {
/* Ooops */
ipc_phone_hangup(&TASK->phones[phone_id]);
task_kill(p.task->taskid);
return rc;
}
 
// FIXME: control the capabilities
cap_set(p.task, cap_get(TASK));
 
/branches/arm/kernel/generic/src/proc/thread.c
102,7 → 102,7
thread_id_t last_tid = 0;
 
static slab_cache_t *thread_slab;
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
slab_cache_t *fpu_context_slab;
#endif
 
161,7 → 161,7
/* call the architecture-specific part of the constructor */
thr_constructor_arch(t);
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
#ifdef CONFIG_FPU_LAZY
t->saved_fpu_context = NULL;
#else
169,11 → 169,11
if (!t->saved_fpu_context)
return -1;
#endif
#endif
#endif
 
t->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
if (!t->kstack) {
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
if (t->saved_fpu_context)
slab_free(fpu_context_slab, t->saved_fpu_context);
#endif
196,7 → 196,7
thr_destructor_arch(t);
 
frame_free(KA2PA(t->kstack));
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
if (t->saved_fpu_context)
slab_free(fpu_context_slab, t->saved_fpu_context);
#endif
211,11 → 211,11
void thread_init(void)
{
THREAD = NULL;
atomic_set(&nrdy,0);
atomic_set(&nrdy, 0);
thread_slab = slab_cache_create("thread_slab", sizeof(thread_t), 0,
thr_constructor, thr_destructor, 0);
 
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
fpu_context_slab = slab_cache_create("fpu_slab", sizeof(fpu_context_t),
FPU_CONTEXT_ALIGN, NULL, NULL, 0);
#endif
279,7 → 279,7
* guarantee that the task won't cease to exist during the
* call. The task's lock may not be held.
* @param flags Thread flags.
* @param name Symbolic name.
* @param name Symbolic name (a copy is made).
* @param uncounted Thread's accounting doesn't affect accumulated task
* accounting.
*
316,6 → 316,7
interrupts_restore(ipl);
memcpy(t->name, name, THREAD_NAME_BUFLEN);
t->name[THREAD_NAME_BUFLEN - 1] = 0;
t->thread_code = func;
t->thread_arg = arg;
708,7 → 709,7
*
*/
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name,
thread_id_t *uspace_thread_id)
size_t name_len, thread_id_t *uspace_thread_id)
{
thread_t *t;
char namebuf[THREAD_NAME_BUFLEN];
715,10 → 716,15
uspace_arg_t *kernel_uarg;
int rc;
 
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
if (name_len > THREAD_NAME_BUFLEN - 1)
name_len = THREAD_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return (unative_t) rc;
 
namebuf[name_len] = 0;
 
/*
* In case of failure, kernel_uarg will be deallocated in this function.
* In case of success, kernel_uarg will be freed in uinit().
757,14 → 763,20
return (unative_t) rc;
}
}
#ifdef CONFIG_UDEBUG
/*
* Generate udebug THREAD_B event and attach the thread.
* This must be done atomically (with the debug locks held),
* otherwise we would either miss some thread or receive
* THREAD_B events for threads that already existed
* and could be detected with THREAD_READ before.
*/
udebug_thread_b_event_attach(t, TASK);
#else
thread_attach(t, TASK);
#endif
thread_ready(t);
 
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_B event */
udebug_thread_b_event(t);
#endif
 
return 0;
} else
free(kernel_uarg);
/branches/arm/kernel/generic/src/proc/tasklet.c
51,7 → 51,7
tasklet_list = malloc(sizeof(tasklet_descriptor_t *) * config.cpu_count, 0);
if (!tasklet_list)
panic("Error initializing tasklets");
panic("Error initializing tasklets.");
for (i = 0; i < config.cpu_count; i++)
tasklet_list[i] = NULL;
/branches/arm/kernel/generic/src/lib/string.c
0,0 → 1,712
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup generic
* @{
*/
 
/**
* @file
* @brief String functions.
*
* Strings and characters use the Universal Character Set (UCS). The standard
* strings, called just strings are encoded in UTF-8. Wide strings (encoded
* in UTF-32) are supported to a limited degree. A single character is
* represented as wchar_t.@n
*
* Overview of the terminology:@n
*
* Term Meaning
* -------------------- ----------------------------------------------------
* byte 8 bits stored in uint8_t (unsigned 8 bit integer)
*
* character UTF-32 encoded Unicode character, stored in wchar_t
* (signed 32 bit integer), code points 0 .. 1114111
* are valid
*
* ASCII character 7 bit encoded ASCII character, stored in char
* (usually signed 8 bit integer), code points 0 .. 127
* are valid
*
* string UTF-8 encoded NULL-terminated Unicode string, char *
*
* wide string UTF-32 encoded NULL-terminated Unicode string,
* wchar_t *
*
* [wide] string size number of BYTES in a [wide] string (excluding
* the NULL-terminator), size_t
*
* [wide] string length number of CHARACTERS in a [wide] string (excluding
* the NULL-terminator), size_t
*
* [wide] string width number of display cells on a monospace display taken
* by a [wide] string, size_t
*
*
* Overview of string metrics:@n
*
* Metric Abbrev. Type Meaning
* ------ ------ ------ -------------------------------------------------
* size n size_t number of BYTES in a string (excluding the
* NULL-terminator)
*
* length l size_t number of CHARACTERS in a string (excluding the
* null terminator)
*
* width w size_t number of display cells on a monospace display
* taken by a string
*
*
* Function naming prefixes:@n
*
* chr_ operate on characters
* ascii_ operate on ASCII characters
* str_ operate on strings
* wstr_ operate on wide strings
*
* [w]str_[n|l|w] operate on a prefix limited by size, length
* or width
*
*
* A specific character inside a [wide] string can be referred to by:@n
*
* pointer (char *, wchar_t *)
* byte offset (size_t)
* character index (size_t)
*
*/
 
#include <string.h>
#include <print.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
#include <errno.h>
#include <align.h>
#include <debug.h>
 
/** Byte mask consisting of lowest @n bits (out of 8) */
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of lowest @n bits (out of 32) */
#define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of highest @n bits (out of 8) */
#define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))
 
/** Number of data bits in a UTF-8 continuation byte */
#define CONT_BITS 6
 
/** Decode a single character from a string.
*
* Decode a single character from a string of size @a size. Decoding starts
* at @a offset and this offset is moved to the beginning of the next
* character. In case of decoding error, offset generally advances at least
* by one. However, offset is never moved beyond size.
*
* @param str String (not necessarily NULL-terminated).
* @param offset Byte offset in string where to start decoding.
* @param size Size of the string (in bytes).
*
* @return Value of decoded character, U_SPECIAL on decoding error or
* NULL if attempt to decode beyond @a size.
*
*/
wchar_t str_decode(const char *str, size_t *offset, size_t size)
{
if (*offset + 1 > size)
return 0;
/* First byte read from string */
uint8_t b0 = (uint8_t) str[(*offset)++];
/* Determine code length */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((b0 & 0x80) == 0) {
/* 0xxxxxxx (Plain ASCII) */
b0_bits = 7;
cbytes = 0;
} else if ((b0 & 0xe0) == 0xc0) {
/* 110xxxxx 10xxxxxx */
b0_bits = 5;
cbytes = 1;
} else if ((b0 & 0xf0) == 0xe0) {
/* 1110xxxx 10xxxxxx 10xxxxxx */
b0_bits = 4;
cbytes = 2;
} else if ((b0 & 0xf8) == 0xf0) {
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
b0_bits = 3;
cbytes = 3;
} else {
/* 10xxxxxx -- unexpected continuation byte */
return U_SPECIAL;
}
if (*offset + cbytes > size)
return U_SPECIAL;
wchar_t ch = b0 & LO_MASK_8(b0_bits);
/* Decode continuation bytes */
while (cbytes > 0) {
uint8_t b = (uint8_t) str[(*offset)++];
/* Must be 10xxxxxx */
if ((b & 0xc0) != 0x80)
return U_SPECIAL;
/* Shift data bits to ch */
ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
cbytes--;
}
return ch;
}
 
/** Encode a single character to string representation.
*
* Encode a single character to string representation (i.e. UTF-8) and store
* it into a buffer at @a offset. Encoding starts at @a offset and this offset
* is moved to the position where the next character can be written to.
*
* @param ch Input character.
* @param str Output buffer.
* @param offset Byte offset where to start writing.
* @param size Size of the output buffer (in bytes).
*
* @return EOK if the character was encoded successfully, EOVERFLOW if there
* was not enough space in the output buffer or EINVAL if the character
* code was invalid.
*/
int chr_encode(wchar_t ch, char *str, size_t *offset, size_t size)
{
if (*offset >= size)
return EOVERFLOW;
if (!chr_check(ch))
return EINVAL;
/* Unsigned version of ch (bit operations should only be done
on unsigned types). */
uint32_t cc = (uint32_t) ch;
/* Determine how many continuation bytes are needed */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((cc & ~LO_MASK_32(7)) == 0) {
b0_bits = 7;
cbytes = 0;
} else if ((cc & ~LO_MASK_32(11)) == 0) {
b0_bits = 5;
cbytes = 1;
} else if ((cc & ~LO_MASK_32(16)) == 0) {
b0_bits = 4;
cbytes = 2;
} else if ((cc & ~LO_MASK_32(21)) == 0) {
b0_bits = 3;
cbytes = 3;
} else {
/* Codes longer than 21 bits are not supported */
return EINVAL;
}
/* Check for available space in buffer */
if (*offset + cbytes >= size)
return EOVERFLOW;
/* Encode continuation bytes */
unsigned int i;
for (i = cbytes; i > 0; i--) {
str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
cc = cc >> CONT_BITS;
}
/* Encode first byte */
str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
/* Advance offset */
*offset += cbytes + 1;
return EOK;
}
 
/** Get size of string.
*
* Get the number of bytes which are used by the string @a str (excluding the
* NULL-terminator).
*
* @param str String to consider.
*
* @return Number of bytes used by the string
*
*/
size_t str_size(const char *str)
{
size_t size = 0;
while (*str++ != 0)
size++;
return size;
}
 
/** Get size of wide string.
*
* Get the number of bytes which are used by the wide string @a str (excluding the
* NULL-terminator).
*
* @param str Wide string to consider.
*
* @return Number of bytes used by the wide string
*
*/
size_t wstr_size(const wchar_t *str)
{
return (wstr_length(str) * sizeof(wchar_t));
}
 
/** Get size of string with length limit.
*
* Get the number of bytes which are used by up to @a max_len first
* characters in the string @a str. If @a max_len is greater than
* the length of @a str, the entire string is measured (excluding the
* NULL-terminator).
*
* @param str String to consider.
* @param max_len Maximum number of characters to measure.
*
* @return Number of bytes used by the characters.
*
*/
size_t str_lsize(const char *str, size_t max_len)
{
size_t len = 0;
size_t offset = 0;
while (len < max_len) {
if (str_decode(str, &offset, STR_NO_LIMIT) == 0)
break;
len++;
}
return offset;
}
 
/** Get size of wide string with length limit.
*
* Get the number of bytes which are used by up to @a max_len first
* wide characters in the wide string @a str. If @a max_len is greater than
* the length of @a str, the entire wide string is measured (excluding the
* NULL-terminator).
*
* @param str Wide string to consider.
* @param max_len Maximum number of wide characters to measure.
*
* @return Number of bytes used by the wide characters.
*
*/
size_t wstr_lsize(const wchar_t *str, size_t max_len)
{
return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
}
 
/** Get number of characters in a string.
*
* @param str NULL-terminated string.
*
* @return Number of characters in string.
*
*/
size_t str_length(const char *str)
{
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, STR_NO_LIMIT) != 0)
len++;
return len;
}
 
/** Get number of characters in a wide string.
*
* @param str NULL-terminated wide string.
*
* @return Number of characters in @a str.
*
*/
size_t wstr_length(const wchar_t *wstr)
{
size_t len = 0;
while (*wstr++ != 0)
len++;
return len;
}
 
/** Get number of characters in a string with size limit.
*
* @param str NULL-terminated string.
* @param size Maximum number of bytes to consider.
*
* @return Number of characters in string.
*
*/
size_t str_nlength(const char *str, size_t size)
{
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, size) != 0)
len++;
return len;
}
 
/** Get number of characters in a string with size limit.
*
* @param str NULL-terminated string.
* @param size Maximum number of bytes to consider.
*
* @return Number of characters in string.
*
*/
size_t wstr_nlength(const wchar_t *str, size_t size)
{
size_t len = 0;
size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
size_t offset = 0;
while ((offset < limit) && (*str++ != 0)) {
len++;
offset += sizeof(wchar_t);
}
return len;
}
 
/** Check whether character is plain ASCII.
*
* @return True if character is plain ASCII.
*
*/
bool ascii_check(wchar_t ch)
{
if ((ch >= 0) && (ch <= 127))
return true;
return false;
}
 
/** Check whether character is valid
*
* @return True if character is a valid Unicode code point.
*
*/
bool chr_check(wchar_t ch)
{
if ((ch >= 0) && (ch <= 1114111))
return true;
return false;
}
 
/** Compare two NULL terminated strings.
*
* Do a char-by-char comparison of two NULL-terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths.
*
* @param s1 First string to compare.
* @param s2 Second string to compare.
*
* @return 0 if the strings are equal, -1 if first is smaller,
* 1 if second smaller.
*
*/
int str_cmp(const char *s1, const char *s2)
{
wchar_t c1 = 0;
wchar_t c2 = 0;
size_t off1 = 0;
size_t off2 = 0;
 
while (true) {
c1 = str_decode(s1, &off1, STR_NO_LIMIT);
c2 = str_decode(s2, &off2, STR_NO_LIMIT);
 
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
 
if (c1 == 0 || c2 == 0)
break;
}
 
return 0;
}
 
/** Compare two NULL terminated strings with length limit.
*
* Do a char-by-char comparison of two NULL-terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths and the length limit.
*
* @param s1 First string to compare.
* @param s2 Second string to compare.
* @param max_len Maximum number of characters to consider.
*
* @return 0 if the strings are equal, -1 if first is smaller,
* 1 if second smaller.
*
*/
int str_lcmp(const char *s1, const char *s2, size_t max_len)
{
wchar_t c1 = 0;
wchar_t c2 = 0;
size_t off1 = 0;
size_t off2 = 0;
size_t len = 0;
 
while (true) {
if (len >= max_len)
break;
 
c1 = str_decode(s1, &off1, STR_NO_LIMIT);
c2 = str_decode(s2, &off2, STR_NO_LIMIT);
 
if (c1 < c2)
return -1;
 
if (c1 > c2)
return 1;
 
if (c1 == 0 || c2 == 0)
break;
 
++len;
}
 
return 0;
 
}
 
/** Copy string.
*
* Copy source string @a src to destination buffer @a dest.
* No more than @a size bytes are written. If the size of the output buffer
* is at least one byte, the output string will always be well-formed, i.e.
* null-terminated and containing only complete characters.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer (must be > 0).
* @param src Source string.
*/
void str_cpy(char *dest, size_t size, const char *src)
{
wchar_t ch;
size_t src_off;
size_t dest_off;
 
/* There must be space for a null terminator in the buffer. */
ASSERT(size > 0);
src_off = 0;
dest_off = 0;
 
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
break;
}
 
dest[dest_off] = '\0';
}
 
/** Copy size-limited substring.
*
* Copy prefix of string @a src of max. size @a size to destination buffer
* @a dest. No more than @a size bytes are written. The output string will
* always be well-formed, i.e. null-terminated and containing only complete
* characters.
*
* No more than @a n bytes are read from the input string, so it does not
* have to be null-terminated.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer (must be > 0).
* @param src Source string.
* @param n Maximum number of bytes to read from @a src.
*/
void str_ncpy(char *dest, size_t size, const char *src, size_t n)
{
wchar_t ch;
size_t src_off;
size_t dest_off;
 
/* There must be space for a null terminator in the buffer. */
ASSERT(size > 0);
src_off = 0;
dest_off = 0;
 
while ((ch = str_decode(src, &src_off, n)) != 0) {
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
break;
}
 
dest[dest_off] = '\0';
}
 
/** Copy NULL-terminated wide string to string
*
* Copy source wide string @a src to destination buffer @a dst.
* No more than @a size bytes are written. NULL-terminator is always
* written after the last succesfully copied character (i.e. if the
* destination buffer is has at least 1 byte, it will be always
* NULL-terminated).
*
* @param src Source wide string.
* @param dst Destination buffer.
* @param count Size of the destination buffer.
*
*/
void wstr_nstr(char *dst, const wchar_t *src, size_t size)
{
/* No space for the NULL-terminator in the buffer */
if (size == 0)
return;
wchar_t ch;
size_t src_idx = 0;
size_t dst_off = 0;
while ((ch = src[src_idx++]) != 0) {
if (chr_encode(ch, dst, &dst_off, size) != EOK)
break;
}
if (dst_off >= size)
dst[size - 1] = 0;
else
dst[dst_off] = 0;
}
 
/** Find first occurence of character in string.
*
* @param str String to search.
* @param ch Character to look for.
*
* @return Pointer to character in @a str or NULL if not found.
*
*/
const char *str_chr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
size_t last = 0;
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (str + last);
last = off;
}
return NULL;
}
 
/** Insert a wide character into a wide string.
*
* Insert a wide character into a wide string at position
* @a pos. The characters after the position are shifted.
*
* @param str String to insert to.
* @param ch Character to insert to.
* @param pos Character index where to insert.
@ @param max_pos Characters in the buffer.
*
* @return True if the insertion was sucessful, false if the position
* is out of bounds.
*
*/
bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
{
size_t len = wstr_length(str);
if ((pos > len) || (pos + 1 > max_pos))
return false;
size_t i;
for (i = len; i + 1 > pos; i--)
str[i + 1] = str[i];
str[pos] = ch;
return true;
}
 
/** Remove a wide character from a wide string.
*
* Remove a wide character from a wide string at position
* @a pos. The characters after the position are shifted.
*
* @param str String to remove from.
* @param pos Character index to remove.
*
* @return True if the removal was sucessful, false if the position
* is out of bounds.
*
*/
bool wstr_remove(wchar_t *str, size_t pos)
{
size_t len = wstr_length(str);
if (pos >= len)
return false;
size_t i;
for (i = pos + 1; i <= len; i++)
str[i - 1] = str[i];
return true;
}
 
/** @}
*/
/branches/arm/kernel/generic/src/lib/sort.c
45,8 → 45,8
 
#define EBUFSIZE 32
 
void _qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
void _bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
 
/** Quicksort wrapper
*
61,7 → 61,7
* @param cmp Comparator function.
*
*/
void qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b))
void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
{
uint8_t buf_tmp[EBUFSIZE];
uint8_t buf_pivot[EBUFSIZE];
93,7 → 93,7
* @param pivot Pointer to scratch memory buffer e_size bytes long.
*
*/
void _qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
{
if (n > 4) {
unsigned int i = 0, j = n - 1;
133,7 → 133,7
* @param cmp Comparator function.
*
*/
void bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b))
void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
{
uint8_t buf_slot[EBUFSIZE];
void * slot = buf_slot;
160,7 → 160,7
* @param slot Pointer to scratch memory buffer e_size bytes long.
*
*/
void _bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
{
bool done = false;
void * p;
/branches/arm/kernel/generic/src/lib/func.c
47,7 → 47,7
 
/** Halt wrapper
*
* Set halt flag and halt the cpu.
* Set halt flag and halt the CPU.
*
*/
void halt()
54,9 → 54,7
{
#ifdef CONFIG_DEBUG
bool rundebugger = false;
 
// TODO test_and_set not defined on all arches
// if (!test_and_set(&haltstate))
if (!atomic_get(&haltstate)) {
atomic_set(&haltstate, 1);
rundebugger = true;
64,118 → 62,22
#else
atomic_set(&haltstate, 1);
#endif
 
interrupts_disable();
#ifdef CONFIG_DEBUG
if (rundebugger) {
printf("\n");
kconsole("panic"); /* Run kconsole as a last resort to user */
}
#endif
#if (defined(CONFIG_DEBUG)) && (defined(CONFIG_KCONSOLE))
if ((rundebugger) && (kconsole_check_poll()))
kconsole("panic", "\nLast resort kernel console ready.\n", false);
#endif
if (CPU)
printf("cpu%u: halted\n", CPU->id);
else
printf("cpu: halted\n");
cpu_halt();
}
 
/** Return number of characters in a string.
*
* @param str NULL terminated string.
*
* @return Number of characters in str.
*/
size_t strlen(const char *str)
{
int i;
for (i = 0; str[i]; i++)
;
return i;
}
 
/** Compare two NULL terminated strings
*
* Do a char-by-char comparison of two NULL terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths.
*
* @param src First string to compare.
* @param dst Second string to compare.
*
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
*
*/
int strcmp(const char *src, const char *dst)
{
for (; *src && *dst; src++, dst++) {
if (*src < *dst)
return -1;
if (*src > *dst)
return 1;
}
if (*src == *dst)
return 0;
if (!*src)
return -1;
return 1;
}
 
 
/** Compare two NULL terminated strings
*
* Do a char-by-char comparison of two NULL terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths and specified maximal
* length.
*
* @param src First string to compare.
* @param dst Second string to compare.
* @param len Maximal length for comparison.
*
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
*
*/
int strncmp(const char *src, const char *dst, size_t len)
{
unsigned int i;
for (i = 0; (*src) && (*dst) && (i < len); src++, dst++, i++) {
if (*src < *dst)
return -1;
if (*src > *dst)
return 1;
}
if (i == len || *src == *dst)
return 0;
if (!*src)
return -1;
return 1;
}
 
 
 
/** Copy NULL terminated string.
*
* Copy at most 'len' characters from string 'src' to 'dest'.
* If 'src' is shorter than 'len', '\0' is inserted behind the
* last copied character.
*
* @param src Source string.
* @param dest Destination buffer.
* @param len Size of destination buffer.
*/
void strncpy(char *dest, const char *src, size_t len)
{
unsigned int i;
for (i = 0; i < len; i++) {
if (!(dest[i] = src[i]))
return;
}
dest[i-1] = '\0';
}
 
/** Convert ascii representation to unative_t
*
* Supports 0x for hexa & 0 for octal notation.
/branches/arm/kernel/generic/src/lib/memstr.c
1,5 → 1,6
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
76,6 → 77,51
return (char *) dst;
}
 
/** Move memory block with possible overlapping.
*
* Copy cnt bytes from src address to dst address. The source and destination
* memory areas may overlap.
*
* @param src Source address to copy from.
* @param dst Destination address to copy to.
* @param cnt Number of bytes to copy.
*
* @return Destination address.
*/
void *memmove(void *dst, const void *src, size_t n)
{
const uint8_t *sp;
uint8_t *dp;
 
/* Nothing to do? */
if (src == dst)
return dst;
 
/* Non-overlapping? */
if (dst >= src + n || src >= dst + n) {
return memcpy(dst, src, n);
}
 
/* Which direction? */
if (src > dst) {
/* Forwards. */
sp = src;
dp = dst;
 
while (n-- != 0)
*dp++ = *sp++;
} else {
/* Backwards. */
sp = src + (n - 1);
dp = dst + (n - 1);
 
while (n-- != 0)
*dp-- = *sp--;
}
 
return dst;
}
 
/** Fill block of memory
*
* Fill cnt bytes at dst address with the value x. The filling is done
114,25 → 160,5
p[i] = x;
}
 
/** Copy string.
*
* Copy string from src address to dst address. The copying is done
* char-by-char until the null character. The source and destination memory
* areas cannot overlap.
*
* @param src Source string to copy from.
* @param dst Destination string to copy to.
*
* @return Address of the destination string.
*/
char *strcpy(char *dest, const char *src)
{
char *orig = dest;
while ((*(dest++) = *(src++)))
;
return orig;
}
 
/** @}
*/
/branches/arm/kernel/generic/src/lib/rd.c
88,9 → 88,7
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize),
FRAME_SIZE);
rd_parea.vbase = (uintptr_t) ((void *) header + hsize);
rd_parea.frames = SIZE2FRAMES(dsize);
rd_parea.cacheable = true;
ddi_parea_register(&rd_parea);
 
sysinfo_set_item_val("rd", NULL, true);
/branches/arm/kernel/generic/src/adt/btree.c
63,9 → 63,9
static void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key);
static btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median);
static btree_node_t *node_combine(btree_node_t *node);
static index_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, index_t idx);
static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, index_t idx);
static size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
static bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static bool try_rotation_from_left(btree_node_t *rnode);
124,7 → 124,7
lnode = leaf_node;
if (!lnode) {
if (btree_search(t, key, &lnode)) {
panic("B-tree %p already contains key %" PRIu64 "\n", t, key);
panic("B-tree %p already contains key %" PRIu64 ".", t, key);
}
}
137,7 → 137,7
*/
void btree_destroy_subtree(btree_node_t *root)
{
count_t i;
size_t i;
 
if (root->keys) {
for (i = 0; i < root->keys + 1; i++) {
224,7 → 224,7
lnode = leaf_node;
if (!lnode) {
if (!btree_search(t, key, &lnode)) {
panic("B-tree %p does not contain key %" PRIu64 "\n", t, key);
panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
}
}
269,7 → 269,7
}
if (node->keys > FILL_FACTOR) {
count_t i;
size_t i;
 
/*
* The key can be immediatelly removed.
285,7 → 285,7
}
} else {
index_t idx;
size_t idx;
btree_node_t *rnode, *parent;
 
/*
335,7 → 335,7
continue;
} else {
void *val;
count_t i;
size_t i;
/*
* Now if the key is smaller than cur->key[i]
442,11 → 442,11
*/
void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree)
{
count_t i;
size_t i;
 
for (i = 0; i < node->keys; i++) {
if (key < node->key[i]) {
count_t j;
size_t j;
for (j = node->keys; j > i; j--) {
node->key[j] = node->key[j - 1];
478,11 → 478,11
*/
void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree)
{
count_t i;
size_t i;
 
for (i = 0; i < node->keys; i++) {
if (key < node->key[i]) {
count_t j;
size_t j;
for (j = node->keys; j > i; j--) {
node->key[j] = node->key[j - 1];
510,7 → 510,7
*/
void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key)
{
count_t i, j;
size_t i, j;
for (i = 0; i < node->keys; i++) {
if (key == node->key[i]) {
524,7 → 524,7
return;
}
}
panic("node %p does not contain key %" PRIu64 "\n", node, key);
panic("Node %p does not contain key %" PRIu64 ".", node, key);
}
 
/** Remove key and its right subtree pointer from B-tree node.
538,7 → 538,7
*/
void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key)
{
count_t i, j;
size_t i, j;
for (i = 0; i < node->keys; i++) {
if (key == node->key[i]) {
551,7 → 551,7
return;
}
}
panic("node %p does not contain key %" PRIu64 "\n", node, key);
panic("Node %p does not contain key %" PRIu64 ".", node, key);
}
 
/** Split full B-tree node and insert new key-value-right-subtree triplet.
576,7 → 576,7
btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median)
{
btree_node_t *rnode;
count_t i, j;
size_t i, j;
 
ASSERT(median);
ASSERT(node->keys == BTREE_MAX_KEYS);
603,7 → 603,7
* Copy big keys, values and subtree pointers to the new right sibling.
* If this is an index node, do not copy the median.
*/
i = (count_t) INDEX_NODE(node);
i = (size_t) INDEX_NODE(node);
for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
rnode->key[j] = node->key[i];
rnode->value[j] = node->value[i];
636,9 → 636,9
*/
btree_node_t *node_combine(btree_node_t *node)
{
index_t idx;
size_t idx;
btree_node_t *rnode;
count_t i;
size_t i;
 
ASSERT(!ROOT_NODE(node));
685,15 → 685,15
*
* @return Index of the key associated with the subtree.
*/
index_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
{
count_t i;
size_t i;
for (i = 0; i < node->keys + 1; i++) {
if (subtree == node->subtree[i])
return i - (int) (right != false);
}
panic("node %p does not contain subtree %p\n", node, subtree);
panic("Node %p does not contain subtree %p.", node, subtree);
}
 
/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
706,7 → 706,7
* @param rnode Right sibling.
* @param idx Index of the parent node key that is taking part in the rotation.
*/
void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, index_t idx)
void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
{
btree_key_t key;
 
743,7 → 743,7
* @param rnode Right sibling.
* @param idx Index of the parent node key that is taking part in the rotation.
*/
void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, index_t idx)
void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
{
btree_key_t key;
 
786,7 → 786,7
*/
bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
{
index_t idx;
size_t idx;
btree_node_t *lnode;
 
/*
833,7 → 833,7
*/
bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
{
index_t idx;
size_t idx;
btree_node_t *rnode;
 
/*
872,7 → 872,7
*/
bool try_rotation_from_left(btree_node_t *rnode)
{
index_t idx;
size_t idx;
btree_node_t *lnode;
 
/*
907,7 → 907,7
*/
bool try_rotation_from_right(btree_node_t *lnode)
{
index_t idx;
size_t idx;
btree_node_t *rnode;
 
/*
940,7 → 940,7
*/
void btree_print(btree_t *t)
{
count_t i;
size_t i;
int depth = t->root->depth;
link_t head, *cur;
 
/branches/arm/kernel/generic/src/adt/hash_table.c
32,7 → 32,7
 
/**
* @file
* @brief Implementation of generic chained hash table.
* @brief Implementation of generic chained hash table.
*
* This file contains implementation of generic chained hash table.
*/
51,18 → 51,20
* @param max_keys Maximal number of keys needed to identify an item.
* @param op Hash table operations structure.
*/
void hash_table_create(hash_table_t *h, count_t m, count_t max_keys, hash_table_operations_t *op)
void hash_table_create(hash_table_t *h, size_t m, size_t max_keys, hash_table_operations_t *op)
{
index_t i;
size_t i;
 
ASSERT(h);
ASSERT(op && op->hash && op->compare);
ASSERT(op);
ASSERT(op->hash);
ASSERT(op->compare);
ASSERT(max_keys > 0);
h->entry = (link_t *) malloc(m * sizeof(link_t), 0);
if (!h->entry) {
panic("cannot allocate memory for hash table\n");
}
if (!h->entry)
panic("Cannot allocate memory for hash table.");
memsetb(h->entry, m * sizeof(link_t), 0);
for (i = 0; i < m; i++)
81,11 → 83,14
*/
void hash_table_insert(hash_table_t *h, unative_t key[], link_t *item)
{
index_t chain;
 
size_t chain;
ASSERT(item);
ASSERT(h && h->op && h->op->hash && h->op->compare);
 
ASSERT(h);
ASSERT(h->op);
ASSERT(h->op->hash);
ASSERT(h->op->compare);
chain = h->op->hash(key);
ASSERT(chain < h->entries);
102,10 → 107,13
link_t *hash_table_find(hash_table_t *h, unative_t key[])
{
link_t *cur;
index_t chain;
 
ASSERT(h && h->op && h->op->hash && h->op->compare);
 
size_t chain;
ASSERT(h);
ASSERT(h->op);
ASSERT(h->op->hash);
ASSERT(h->op->compare);
chain = h->op->hash(key);
ASSERT(chain < h->entries);
123,22 → 131,25
 
/** Remove all matching items from hash table.
*
* For each removed item, h->remove_callback() is called.
* For each removed item, h->remove_callback() is called (if not NULL).
*
* @param h Hash table.
* @param key Array of keys that will be compared against items of the hash table.
* @param keys Number of keys in the key array.
*/
void hash_table_remove(hash_table_t *h, unative_t key[], count_t keys)
void hash_table_remove(hash_table_t *h, unative_t key[], size_t keys)
{
index_t chain;
size_t chain;
link_t *cur;
 
ASSERT(h && h->op && h->op->hash && h->op->compare && h->op->remove_callback);
ASSERT(h);
ASSERT(h->op);
ASSERT(h->op->hash);
ASSERT(h->op->compare);
ASSERT(keys <= h->max_keys);
if (keys == h->max_keys) {
 
/*
* All keys are known, hash_table_find() can be used to find the entry.
*/
146,7 → 157,8
cur = hash_table_find(h, key);
if (cur) {
list_remove(cur);
h->op->remove_callback(cur);
if (h->op->remove_callback)
h->op->remove_callback(cur);
}
return;
}
164,7 → 176,8
cur = cur->prev;
list_remove(hlp);
h->op->remove_callback(hlp);
if (h->op->remove_callback)
h->op->remove_callback(hlp);
continue;
}
/branches/arm/kernel/generic/src/adt/bitmap.c
54,7 → 54,7
* @param map Address of the memory used to hold the map.
* @param bits Number of bits stored in bitmap.
*/
void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, count_t bits)
void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, size_t bits)
{
bitmap->map = map;
bitmap->bits = bits;
66,13 → 66,13
* @param start Starting bit.
* @param bits Number of bits to set.
*/
void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits)
void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t bits)
{
index_t i=0;
index_t aligned_start;
count_t lub; /* leading unaligned bits */
count_t amb; /* aligned middle bits */
count_t tab; /* trailing aligned bits */
size_t i = 0;
size_t aligned_start;
size_t lub; /* leading unaligned bits */
size_t amb; /* aligned middle bits */
size_t tab; /* trailing aligned bits */
ASSERT(start + bits <= bitmap->bits);
116,13 → 116,13
* @param start Starting bit.
* @param bits Number of bits to clear.
*/
void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits)
void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t bits)
{
index_t i=0;
index_t aligned_start;
count_t lub; /* leading unaligned bits */
count_t amb; /* aligned middle bits */
count_t tab; /* trailing aligned bits */
size_t i = 0;
size_t aligned_start;
size_t lub; /* leading unaligned bits */
size_t amb; /* aligned middle bits */
size_t tab; /* trailing aligned bits */
ASSERT(start + bits <= bitmap->bits);
168,9 → 168,9
* @param src Source bitmap.
* @param bits Number of bits to copy.
*/
void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits)
void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t bits)
{
index_t i;
size_t i;
ASSERT(bits <= dst->bits);
ASSERT(bits <= src->bits);
/branches/arm/kernel/generic/src/adt/avl.c
43,7 → 43,7
*
* Every node has a pointer to its parent which allows insertion of multiple
* identical keys into the tree.
*
*
* Be careful when using this tree because of the base atribute which is added
* to every inserted node key. There is no rule in which order nodes with the
* same key are visited.
/branches/arm/kernel/generic/src/mm/slab.c
129,7 → 129,7
static slab_cache_t *slab_extern_cache;
/** Caches for malloc */
static slab_cache_t *malloc_caches[SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1];
char *malloc_names[] = {
static char *malloc_names[] = {
"malloc-16",
"malloc-32",
"malloc-64",
144,7 → 144,11
"malloc-32K",
"malloc-64K",
"malloc-128K",
"malloc-256K"
"malloc-256K",
"malloc-512K",
"malloc-1M",
"malloc-2M",
"malloc-4M"
};
 
/** Slab descriptor */
152,8 → 156,8
slab_cache_t *cache; /**< Pointer to parent cache. */
link_t link; /**< List of full/partial slabs. */
void *start; /**< Start address of first available item. */
count_t available; /**< Count of available items in this slab. */
index_t nextavail; /**< The index of next available item. */
size_t available; /**< Count of available items in this slab. */
size_t nextavail; /**< The index of next available item. */
} slab_t;
 
#ifdef CONFIG_DEBUG
173,7 → 177,7
slab_t *slab;
size_t fsize;
unsigned int i;
unsigned int zone = 0;
size_t zone = 0;
data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone);
if (!data) {
211,7 → 215,7
*
* @return number of freed frames
*/
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
{
frame_free(KA2PA(slab->start));
if (! (cache->flags & SLAB_CACHE_SLINSIDE))
239,7 → 243,7
*
* @return Number of freed pages
*/
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj, slab_t *slab)
static size_t slab_obj_destroy(slab_cache_t *cache, void *obj, slab_t *slab)
{
int freed = 0;
 
367,10 → 371,10
*
* @return Number of freed pages
*/
static count_t magazine_destroy(slab_cache_t *cache, slab_magazine_t *mag)
static size_t magazine_destroy(slab_cache_t *cache, slab_magazine_t *mag)
{
unsigned int i;
count_t frames = 0;
size_t frames = 0;
 
for (i = 0; i < mag->busy; i++) {
frames += slab_obj_destroy(cache, mag->objs[i], NULL);
645,11 → 649,11
* @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
* @return Number of freed pages
*/
static count_t _slab_reclaim(slab_cache_t *cache, int flags)
static size_t _slab_reclaim(slab_cache_t *cache, int flags)
{
unsigned int i;
slab_magazine_t *mag;
count_t frames = 0;
size_t frames = 0;
int magcount;
if (cache->flags & SLAB_CACHE_NOMAGAZINE)
767,11 → 771,11
}
 
/* Go through all caches and reclaim what is possible */
count_t slab_reclaim(int flags)
size_t slab_reclaim(int flags)
{
slab_cache_t *cache;
link_t *cur;
count_t frames = 0;
size_t frames = 0;
 
spinlock_lock(&slab_cache_lock);
 
932,7 → 936,7
void *malloc(unsigned int size, int flags)
{
ASSERT(_slab_initialized);
ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W));
ASSERT(size <= (1 << SLAB_MAX_MALLOC_W));
if (size < (1 << SLAB_MIN_MALLOC_W))
size = (1 << SLAB_MIN_MALLOC_W);
/branches/arm/kernel/generic/src/mm/tlb.c
79,7 → 79,7
* @param count Number of pages, if required by type.
*/
void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
uintptr_t page, count_t count)
uintptr_t page, size_t count)
{
unsigned int i;
 
108,7 → 108,7
/*
* Enqueue the message.
*/
index_t idx = cpu->tlb_messages_count++;
size_t idx = cpu->tlb_messages_count++;
cpu->tlb_messages[idx].type = type;
cpu->tlb_messages[idx].asid = asid;
cpu->tlb_messages[idx].page = page;
143,7 → 143,7
tlb_invalidate_type_t type;
asid_t asid;
uintptr_t page;
count_t count;
size_t count;
unsigned int i;
ASSERT(CPU);
173,7 → 173,7
tlb_invalidate_pages(asid, page, count);
break;
default:
panic("unknown type (%d)\n", type);
panic("Unknown type (%d).", type);
break;
}
if (type == TLB_INVL_ALL)
/branches/arm/kernel/generic/src/mm/backend_anon.c
152,7 → 152,7
*/
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
return AS_PF_OK;
}
195,7 → 195,7
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t base = node->key[i];
count_t count = (count_t) node->value[i];
size_t count = (size_t) node->value[i];
unsigned int j;
for (j = 0; j < count; j++) {
/branches/arm/kernel/generic/src/mm/as.c
122,7 → 122,7
int rc;
 
link_initialize(&as->inactive_as_with_asid_link);
mutex_initialize(&as->lock, MUTEX_PASSIVE);
mutex_initialize(&as->lock, MUTEX_PASSIVE);
rc = as_constructor_arch(as, flags);
146,8 → 146,12
AS_KERNEL = as_create(FLAG_AS_KERNEL);
if (!AS_KERNEL)
panic("can't create kernel address space\n");
panic("Cannot create kernel address space.");
/* Make sure the kernel address space
* reference count never drops to zero.
*/
atomic_set(&AS_KERNEL->refcount, 1);
}
 
/** Create address space.
176,7 → 180,7
#else
page_table_create(flags);
#endif
 
return as;
}
 
414,8 → 418,8
btree_node_t, leaf_link);
if ((cond = (bool) node->keys)) {
uintptr_t b = node->key[node->keys - 1];
count_t c =
(count_t) node->value[node->keys - 1];
size_t c =
(size_t) node->value[node->keys - 1];
unsigned int i = 0;
if (overlaps(b, c * PAGE_SIZE, area->base,
440,8 → 444,8
i = (start_free - b) >> PAGE_WIDTH;
if (!used_space_remove(area, start_free,
c - i))
panic("Could not remove used "
"space.\n");
panic("Cannot remove used "
"space.");
} else {
/*
* The interval of used space can be
448,8 → 452,8
* completely removed.
*/
if (!used_space_remove(area, b, c))
panic("Could not remove used "
"space.\n");
panic("Cannot remove used "
"space.");
}
for (; i < c; i++) {
551,10 → 555,10
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
size_t j;
pte_t *pte;
for (j = 0; j < (count_t) node->value[i]; j++) {
for (j = 0; j < (size_t) node->value[i]; j++) {
page_table_lock(as, false);
pte = page_mapping_find(as, b + j * PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) &&
769,11 → 773,12
* In order for this to work properly, this may copy the data
* into private anonymous memory (unless it's already there).
*
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address withing the area to be changed.
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address within the area to be changed.
*
* @return Zero on success or a value from @ref errno.h on failure.
* @return Zero on success or a value from @ref errno.h on failure.
*
*/
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
{
783,9 → 788,9
ipl_t ipl;
int page_flags;
uintptr_t *old_frame;
index_t frame_idx;
count_t used_pages;
 
size_t frame_idx;
size_t used_pages;
/* Flags for the new memory mapping */
page_flags = area_flags_to_page_flags(flags);
 
799,7 → 804,7
return ENOENT;
}
 
if (area->sh_info || area->backend != &anon_backend) {
if ((area->sh_info) || (area->backend != &anon_backend)) {
/* Copying shared areas not supported yet */
/* Copying non-anonymous memory not supported yet */
mutex_unlock(&area->lock);
822,7 → 827,7
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
used_pages += (count_t) node->value[i];
used_pages += (size_t) node->value[i];
}
}
 
848,10 → 853,10
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
size_t j;
pte_t *pte;
for (j = 0; j < (count_t) node->value[i]; j++) {
for (j = 0; j < (size_t) node->value[i]; j++) {
page_table_lock(as, false);
pte = page_mapping_find(as, b + j * PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) &&
870,6 → 875,7
*/
 
tlb_invalidate_pages(as->asid, area->base, area->pages);
/*
* Invalidate potential software translation caches (e.g. TSB on
* sparc64).
897,9 → 903,9
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
size_t j;
for (j = 0; j < (count_t) node->value[i]; j++) {
for (j = 0; j < (size_t) node->value[i]; j++) {
page_table_lock(as, false);
 
/* Insert the new mapping */
1391,16 → 1397,16
*
* @return Zero on failure and non-zero on success.
*/
int used_space_insert(as_area_t *a, uintptr_t page, count_t count)
int used_space_insert(as_area_t *a, uintptr_t page, size_t count)
{
btree_node_t *leaf, *node;
count_t pages;
size_t pages;
unsigned int i;
 
ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
ASSERT(count);
 
pages = (count_t) btree_search(&a->used_space, page, &leaf);
pages = (size_t) btree_search(&a->used_space, page, &leaf);
if (pages) {
/*
* We hit the beginning of some used space.
1417,8 → 1423,8
if (node) {
uintptr_t left_pg = node->key[node->keys - 1];
uintptr_t right_pg = leaf->key[0];
count_t left_cnt = (count_t) node->value[node->keys - 1];
count_t right_cnt = (count_t) leaf->value[0];
size_t left_cnt = (size_t) node->value[node->keys - 1];
size_t right_cnt = (size_t) leaf->value[0];
/*
* Examine the possibility that the interval fits
1472,7 → 1478,7
}
} else if (page < leaf->key[0]) {
uintptr_t right_pg = leaf->key[0];
count_t right_cnt = (count_t) leaf->value[0];
size_t right_cnt = (size_t) leaf->value[0];
/*
* Investigate the border case in which the left neighbour does
1507,8 → 1513,8
if (node) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
uintptr_t right_pg = node->key[0];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
count_t right_cnt = (count_t) node->value[0];
size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
size_t right_cnt = (size_t) node->value[0];
/*
* Examine the possibility that the interval fits
1562,7 → 1568,7
}
} else if (page >= leaf->key[leaf->keys - 1]) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
/*
* Investigate the border case in which the right neighbour
1600,8 → 1606,8
if (page < leaf->key[i]) {
uintptr_t left_pg = leaf->key[i - 1];
uintptr_t right_pg = leaf->key[i];
count_t left_cnt = (count_t) leaf->value[i - 1];
count_t right_cnt = (count_t) leaf->value[i];
size_t left_cnt = (size_t) leaf->value[i - 1];
size_t right_cnt = (size_t) leaf->value[i];
 
/*
* The interval fits between left_pg and right_pg.
1659,8 → 1665,8
}
}
 
panic("Inconsistency detected while adding %" PRIc " pages of used "
"space at %p.\n", count, page);
panic("Inconsistency detected while adding %" PRIs " pages of used "
"space at %p.", count, page);
}
 
/** Mark portion of address space area as unused.
1673,16 → 1679,16
*
* @return Zero on failure and non-zero on success.
*/
int used_space_remove(as_area_t *a, uintptr_t page, count_t count)
int used_space_remove(as_area_t *a, uintptr_t page, size_t count)
{
btree_node_t *leaf, *node;
count_t pages;
size_t pages;
unsigned int i;
 
ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
ASSERT(count);
 
pages = (count_t) btree_search(&a->used_space, page, &leaf);
pages = (size_t) btree_search(&a->used_space, page, &leaf);
if (pages) {
/*
* We are lucky, page is the beginning of some interval.
1711,7 → 1717,7
node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
if (node && page < leaf->key[0]) {
uintptr_t left_pg = node->key[node->keys - 1];
count_t left_cnt = (count_t) node->value[node->keys - 1];
size_t left_cnt = (size_t) node->value[node->keys - 1];
 
if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
count * PAGE_SIZE)) {
1727,7 → 1733,7
return 1;
} else if (page + count * PAGE_SIZE <
left_pg + left_cnt*PAGE_SIZE) {
count_t new_cnt;
size_t new_cnt;
/*
* The interval is contained in the rightmost
1751,7 → 1757,7
if (page > leaf->key[leaf->keys - 1]) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
 
if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
count * PAGE_SIZE)) {
1766,7 → 1772,7
return 1;
} else if (page + count * PAGE_SIZE < left_pg +
left_cnt * PAGE_SIZE) {
count_t new_cnt;
size_t new_cnt;
/*
* The interval is contained in the rightmost
1793,7 → 1799,7
for (i = 1; i < leaf->keys - 1; i++) {
if (page < leaf->key[i]) {
uintptr_t left_pg = leaf->key[i - 1];
count_t left_cnt = (count_t) leaf->value[i - 1];
size_t left_cnt = (size_t) leaf->value[i - 1];
 
/*
* Now the interval is between intervals corresponding
1813,7 → 1819,7
return 1;
} else if (page + count * PAGE_SIZE <
left_pg + left_cnt * PAGE_SIZE) {
count_t new_cnt;
size_t new_cnt;
/*
* The interval is contained in the
1838,8 → 1844,8
}
 
error:
panic("Inconsistency detected while removing %" PRIc " pages of used "
"space from %p.\n", count, page);
panic("Inconsistency detected while removing %" PRIs " pages of used "
"space from %p.", count, page);
}
 
/** Remove reference to address space area share info.
1937,7 → 1943,7
as_area_t *area = node->value[i];
mutex_lock(&area->lock);
printf("as_area: %p, base=%p, pages=%" PRIc
printf("as_area: %p, base=%p, pages=%" PRIs
" (%p - %p)\n", area, area->base, area->pages,
area->base, area->base + FRAMES2SIZE(area->pages));
mutex_unlock(&area->lock);
/branches/arm/kernel/generic/src/mm/frame.c
1,6 → 1,7
/*
* Copyright (c) 2001-2005 Jakub Jermar
* Copyright (c) 2005 Sergey Bondari
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
33,7 → 34,7
 
/**
* @file
* @brief Physical frame allocator.
* @brief Physical frame allocator.
*
* This file contains the physical frame allocator and memory zone management.
* The frame allocator is built on top of the buddy allocator.
41,16 → 42,6
* @see buddy.c
*/
 
/*
* Locking order
*
* In order to access particular zone, the process must first lock
* the zones.lock, then lock the zone and then unlock the zones.lock.
* This insures, that we can fiddle with the zones in runtime without
* affecting the processes.
*
*/
 
#include <arch/types.h>
#include <mm/frame.h>
#include <mm/as.h>
57,7 → 48,6
#include <panic.h>
#include <debug.h>
#include <adt/list.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <synch/condvar.h>
#include <arch/asm.h>
69,72 → 59,37
#include <macros.h>
#include <config.h>
 
typedef struct {
count_t refcount; /**< tracking of shared frames */
uint8_t buddy_order; /**< buddy system block order */
link_t buddy_link; /**< link to the next free block inside one
order */
void *parent; /**< If allocated by slab, this points there */
} frame_t;
zones_t zones;
 
typedef struct {
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
pfn_t base; /**< frame_no of the first frame in the frames
array */
count_t count; /**< Size of zone */
 
frame_t *frames; /**< array of frame_t structures in this
zone */
count_t free_count; /**< number of free frame_t structures */
count_t busy_count; /**< number of busy frame_t structures */
buddy_system_t *buddy_system; /**< buddy system for the zone */
int flags;
} zone_t;
 
/*
* The zoneinfo.lock must be locked when accessing zoneinfo structure.
* Some of the attributes in zone_t structures are 'read-only'
*/
 
typedef struct {
SPINLOCK_DECLARE(lock);
unsigned int count;
zone_t *info[ZONES_MAX];
} zones_t;
 
static zones_t zones;
 
/*
* Synchronization primitives used to sleep when there is no memory
* available.
*/
mutex_t mem_avail_mtx;
condvar_t mem_avail_cv;
unsigned long mem_avail_frames = 0; /**< Number of available frames. */
unsigned long mem_avail_gen = 0; /**< Generation counter. */
size_t mem_avail_req = 0; /**< Number of frames requested. */
size_t mem_avail_gen = 0; /**< Generation counter. */
 
/********************/
/* Helper functions */
/********************/
 
static inline index_t frame_index(zone_t *zone, frame_t *frame)
static inline size_t frame_index(zone_t *zone, frame_t *frame)
{
return (index_t) (frame - zone->frames);
return (size_t) (frame - zone->frames);
}
 
static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
{
return (index_t) (frame - zone->frames) + zone->base;
return (size_t) (frame - zone->frames) + zone->base;
}
 
static inline int frame_index_valid(zone_t *zone, index_t index)
static inline bool frame_index_valid(zone_t *zone, size_t index)
{
return (index < zone->count);
}
 
/** Compute pfn_t from frame_t pointer & zone pointer */
static index_t make_frame_index(zone_t *zone, frame_t *frame)
static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
{
return (frame - zone->frames);
}
141,7 → 96,8
 
/** Initialize frame structure.
*
* @param frame Frame structure to be initialized.
* @param frame Frame structure to be initialized.
*
*/
static void frame_initialize(frame_t *frame)
{
149,153 → 105,145
frame->buddy_order = 0;
}
 
/**********************/
/* Zoneinfo functions */
/**********************/
/*******************/
/* Zones functions */
/*******************/
 
/** Insert-sort zone into zones list.
*
* @param newzone New zone to be inserted into zone list.
* @return Zone number on success, -1 on error.
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param base Base frame of the newly inserted zone.
* @param count Number of frames of the newly inserted zone.
*
* @return Zone number on success, -1 on error.
*
*/
static int zones_add_zone(zone_t *newzone)
static size_t zones_insert_zone(pfn_t base, size_t count)
{
unsigned int i, j;
ipl_t ipl;
zone_t *z;
 
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/* Try to merge */
if (zones.count + 1 == ZONES_MAX) {
printf("Maximum zone count %u exceeded!\n", ZONES_MAX);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return -1;
return (size_t) -1;
}
size_t i;
for (i = 0; i < zones.count; i++) {
/* Check for overflow */
z = zones.info[i];
if (overlaps(newzone->base, newzone->count, z->base,
z->count)) {
/* Check for overlap */
if (overlaps(base, count,
zones.info[i].base, zones.info[i].count)) {
printf("Zones overlap!\n");
return -1;
return (size_t) -1;
}
if (newzone->base < z->base)
if (base < zones.info[i].base)
break;
}
/* Move other zones up */
for (j = i; j < zones.count; j++)
zones.info[j + 1] = zones.info[j];
size_t j;
for (j = zones.count; j > i; j--) {
zones.info[j] = zones.info[j - 1];
zones.info[j].buddy_system->data =
(void *) &zones.info[j - 1];
}
zones.info[i] = newzone;
zones.count++;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
return i;
}
 
/** Try to find a zone where can we find the frame.
/** Get total available frames.
*
* Assume interrupts are disabled.
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param frame Frame number contained in zone.
* @param pzone If not null, it is used as zone hint. Zone index is
* filled into the variable on success.
* @return Pointer to locked zone containing frame.
* @return Total number of available frames.
*
*/
static zone_t *find_zone_and_lock(pfn_t frame, unsigned int *pzone)
#ifdef CONFIG_DEBUG
static size_t total_frames_free(void)
{
unsigned int i;
unsigned int hint = pzone ? *pzone : 0;
zone_t *z;
size_t total = 0;
size_t i;
for (i = 0; i < zones.count; i++)
total += zones.info[i].free_count;
spinlock_lock(&zones.lock);
return total;
}
#endif
 
/** Find a zone with a given frames.
*
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param frame Frame number contained in zone.
* @param count Number of frames to look for.
* @param hint Used as zone hint.
*
* @return Zone index or -1 if not found.
*
*/
size_t find_zone(pfn_t frame, size_t count, size_t hint)
{
if (hint >= zones.count)
hint = 0;
i = hint;
size_t i = hint;
do {
z = zones.info[i];
spinlock_lock(&z->lock);
if (z->base <= frame && z->base + z->count > frame) {
/* Unlock the global lock */
spinlock_unlock(&zones.lock);
if (pzone)
*pzone = i;
return z;
}
spinlock_unlock(&z->lock);
 
if ((zones.info[i].base <= frame)
&& (zones.info[i].base + zones.info[i].count >= frame + count))
return i;
i++;
if (i >= zones.count)
i = 0;
} while (i != hint);
 
spinlock_unlock(&zones.lock);
return NULL;
return (size_t) -1;
}
 
/** @return True if zone can allocate specified order */
static int zone_can_alloc(zone_t *z, uint8_t order)
static bool zone_can_alloc(zone_t *zone, uint8_t order)
{
return buddy_system_can_alloc(z->buddy_system, order);
return (zone_flags_available(zone->flags)
&& buddy_system_can_alloc(zone->buddy_system, order));
}
 
/** Find and lock zone that can allocate order frames.
/** Find a zone that can allocate order frames.
*
* Assume interrupts are disabled.
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param order Size (2^order) of free space we are trying to find.
* @param flags Required flags of the target zone.
* @param pzone Pointer to preferred zone or NULL, on return contains
* zone number.
* @param order Size (2^order) of free space we are trying to find.
* @param flags Required flags of the target zone.
* @param hind Preferred zone.
*
*/
static zone_t *
find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone)
static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
{
unsigned int i;
zone_t *z;
unsigned int hint = pzone ? *pzone : 0;
/* Mask off flags that are not applicable. */
flags &= FRAME_LOW_4_GiB;
 
spinlock_lock(&zones.lock);
if (hint >= zones.count)
hint = 0;
i = hint;
size_t i = hint;
do {
z = zones.info[i];
spinlock_lock(&z->lock);
 
/*
* Check whether the zone meets the search criteria.
*/
if ((z->flags & flags) == flags) {
if ((zones.info[i].flags & flags) == flags) {
/*
* Check if the zone has 2^order frames area available.
*/
if (zone_can_alloc(z, order)) {
spinlock_unlock(&zones.lock);
if (pzone)
*pzone = i;
return z;
}
if (zone_can_alloc(&zones.info[i], order))
return i;
}
spinlock_unlock(&z->lock);
if (++i >= zones.count)
i++;
if (i >= zones.count)
i = 0;
} while (i != hint);
spinlock_unlock(&zones.lock);
return NULL;
return (size_t) -1;
}
 
/**************************/
307,82 → 255,73
* Find block that is parent of current list.
* That means go to lower addresses, until such block is found
*
* @param order Order of parent must be different then this
* parameter!!
* @param order Order of parent must be different then this
* parameter!!
*
*/
static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child,
static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
uint8_t order)
{
frame_t *frame;
zone_t *zone;
index_t index;
frame_t *frame = list_get_instance(child, frame_t, buddy_link);
zone_t *zone = (zone_t *) buddy->data;
frame = list_get_instance(child, frame_t, buddy_link);
zone = (zone_t *) b->data;
 
index = frame_index(zone, frame);
size_t index = frame_index(zone, frame);
do {
if (zone->frames[index].buddy_order != order) {
if (zone->frames[index].buddy_order != order)
return &zone->frames[index].buddy_link;
}
} while(index-- > 0);
} while (index-- > 0);
return NULL;
}
 
/** Buddy system find_buddy implementation.
*
* @param b Buddy system.
* @param block Block for which buddy should be found.
* @param buddy Buddy system.
* @param block Block for which buddy should be found.
*
* @return Buddy for given block if found.
* @return Buddy for given block if found.
*
*/
static link_t *zone_buddy_find_buddy(buddy_system_t *b, link_t *block)
static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block)
{
frame_t *frame;
zone_t *zone;
index_t index;
bool is_left, is_right;
 
frame = list_get_instance(block, frame_t, buddy_link);
zone = (zone_t *) b->data;
frame_t *frame = list_get_instance(block, frame_t, buddy_link);
zone_t *zone = (zone_t *) buddy->data;
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),
frame->buddy_order));
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
 
ASSERT(is_left ^ is_right);
bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
size_t index;
if (is_left) {
index = (frame_index(zone, frame)) +
(1 << frame->buddy_order);
} else { /* if (is_right) */
} else { /* is_right */
index = (frame_index(zone, frame)) -
(1 << frame->buddy_order);
}
if (frame_index_valid(zone, index)) {
if (zone->frames[index].buddy_order == frame->buddy_order &&
zone->frames[index].refcount == 0) {
if ((zone->frames[index].buddy_order == frame->buddy_order) &&
(zone->frames[index].refcount == 0)) {
return &zone->frames[index].buddy_link;
}
}
 
return NULL;
return NULL;
}
 
/** Buddy system bisect implementation.
*
* @param b Buddy system.
* @param block Block to bisect.
* @param buddy Buddy system.
* @param block Block to bisect.
*
* @return Right block.
* @return Right block.
*
*/
static link_t *zone_buddy_bisect(buddy_system_t *b, link_t *block)
static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
{
frame_t *frame_l, *frame_r;
 
frame_l = list_get_instance(block, frame_t, buddy_link);
frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
return &frame_r->buddy_link;
}
389,75 → 328,68
 
/** Buddy system coalesce implementation.
*
* @param b Buddy system.
* @param block_1 First block.
* @param block_2 First block's buddy.
* @param buddy Buddy system.
* @param block_1 First block.
* @param block_2 First block's buddy.
*
* @return Coalesced block (actually block that represents lower
* address).
* @return Coalesced block (actually block that represents lower
* address).
*
*/
static link_t *zone_buddy_coalesce(buddy_system_t *b, link_t *block_1,
link_t *block_2)
static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1,
link_t *block_2)
{
frame_t *frame1, *frame2;
frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link);
frame1 = list_get_instance(block_1, frame_t, buddy_link);
frame2 = list_get_instance(block_2, frame_t, buddy_link);
return frame1 < frame2 ? block_1 : block_2;
return ((frame1 < frame2) ? block_1 : block_2);
}
 
/** Buddy system set_order implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param order Order to set.
* @param buddy Buddy system.
* @param block Buddy system block.
* @param order Order to set.
*
*/
static void zone_buddy_set_order(buddy_system_t *b, link_t *block,
static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
uint8_t order)
{
frame_t *frame;
frame = list_get_instance(block, frame_t, buddy_link);
frame->buddy_order = order;
list_get_instance(block, frame_t, buddy_link)->buddy_order = order;
}
 
/** Buddy system get_order implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param buddy Buddy system.
* @param block Buddy system block.
*
* @return Order of block.
* @return Order of block.
*
*/
static uint8_t zone_buddy_get_order(buddy_system_t *b, link_t *block)
static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
{
frame_t *frame;
frame = list_get_instance(block, frame_t, buddy_link);
return frame->buddy_order;
return list_get_instance(block, frame_t, buddy_link)->buddy_order;
}
 
/** Buddy system mark_busy implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param buddy Buddy system.
* @param block Buddy system block.
*
*/
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block)
static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block)
{
frame_t * frame;
 
frame = list_get_instance(block, frame_t, buddy_link);
frame->refcount = 1;
list_get_instance(block, frame_t, buddy_link)->refcount = 1;
}
 
/** Buddy system mark_available implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param buddy Buddy system.
* @param block Buddy system block.
*/
static void zone_buddy_mark_available(buddy_system_t *b, link_t *block)
static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
{
frame_t *frame;
frame = list_get_instance(block, frame_t, buddy_link);
frame->refcount = 0;
list_get_instance(block, frame_t, buddy_link)->refcount = 0;
}
 
static buddy_system_operations_t zone_buddy_system_operations = {
477,60 → 409,57
 
/** Allocate frame in particular zone.
*
* Assume zone is locked.
* Assume zone is locked and is available for allocation.
* Panics if allocation is impossible.
*
* @param zone Zone to allocate from.
* @param order Allocate exactly 2^order frames.
* @param zone Zone to allocate from.
* @param order Allocate exactly 2^order frames.
*
* @return Frame index in zone.
* @return Frame index in zone.
*
*/
static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
{
pfn_t v;
link_t *tmp;
frame_t *frame;
 
ASSERT(zone_flags_available(zone->flags));
/* Allocate frames from zone buddy system */
tmp = buddy_system_alloc(zone->buddy_system, order);
link_t *link = buddy_system_alloc(zone->buddy_system, order);
ASSERT(tmp);
ASSERT(link);
/* Update zone information. */
zone->free_count -= (1 << order);
zone->busy_count += (1 << order);
 
/* Frame will be actually a first frame of the block. */
frame = list_get_instance(tmp, frame_t, buddy_link);
frame_t *frame = list_get_instance(link, frame_t, buddy_link);
/* get frame address */
v = make_frame_index(zone, frame);
return v;
/* Get frame address */
return make_frame_index(zone, frame);
}
 
/** Free frame from zone.
*
* Assume zone is locked.
* Assume zone is locked and is available for deallocation.
*
* @param zone Pointer to zone from which the frame is to be freed.
* @param frame_idx Frame index relative to zone.
* @param zone Pointer to zone from which the frame is to be freed.
* @param frame_idx Frame index relative to zone.
*
*/
static void zone_frame_free(zone_t *zone, index_t frame_idx)
static void zone_frame_free(zone_t *zone, size_t frame_idx)
{
frame_t *frame;
uint8_t order;
 
frame = &zone->frames[frame_idx];
ASSERT(zone_flags_available(zone->flags));
/* remember frame order */
order = frame->buddy_order;
 
frame_t *frame = &zone->frames[frame_idx];
/* Remember frame order */
uint8_t order = frame->buddy_order;
ASSERT(frame->refcount);
 
if (!--frame->refcount) {
buddy_system_free(zone->buddy_system, &frame->buddy_link);
/* Update zone information. */
zone->free_count += (1 << order);
zone->busy_count -= (1 << order);
538,7 → 467,7
}
 
/** Return frame from zone. */
static frame_t *zone_get_frame(zone_t *zone, index_t frame_idx)
static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
{
ASSERT(frame_idx < zone->count);
return &zone->frames[frame_idx];
545,569 → 474,648
}
 
/** Mark frame in zone unavailable to allocation. */
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
{
frame_t *frame;
link_t *link;
 
frame = zone_get_frame(zone, frame_idx);
ASSERT(zone_flags_available(zone->flags));
frame_t *frame = zone_get_frame(zone, frame_idx);
if (frame->refcount)
return;
link_t *link __attribute__ ((unused));
link = buddy_system_alloc_block(zone->buddy_system,
&frame->buddy_link);
ASSERT(link);
zone->free_count--;
 
mutex_lock(&mem_avail_mtx);
mem_avail_frames--;
mutex_unlock(&mem_avail_mtx);
}
 
/** Join two zones.
/** Merge two zones.
*
* Expect zone_t *z to point to space at least zone_conf_size large.
* Expect buddy to point to space at least zone_conf_size large.
* Assume z1 & z2 are locked and compatible and zones lock is
* locked.
*
* Assume z1 & z2 are locked.
* @param z1 First zone to merge.
* @param z2 Second zone to merge.
* @param old_z1 Original date of the first zone.
* @param buddy Merged zone buddy.
*
* @param z Target zone structure pointer.
* @param z1 Zone to merge.
* @param z2 Zone to merge.
*/
static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2)
static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
{
uint8_t max_order;
unsigned int i;
int z2idx;
pfn_t frame_idx;
frame_t *frame;
 
ASSERT(!overlaps(z1->base, z1->count, z2->base, z2->count));
ASSERT(z1->base < z2->base);
 
spinlock_initialize(&z->lock, "zone_lock");
z->base = z1->base;
z->count = z2->base + z2->count - z1->base;
z->flags = z1->flags & z2->flags;
 
z->free_count = z1->free_count + z2->free_count;
z->busy_count = z1->busy_count + z2->busy_count;
ASSERT(zone_flags_available(zones.info[z1].flags));
ASSERT(zone_flags_available(zones.info[z2].flags));
ASSERT(zones.info[z1].flags == zones.info[z2].flags);
ASSERT(zones.info[z1].base < zones.info[z2].base);
ASSERT(!overlaps(zones.info[z1].base, zones.info[z1].count,
zones.info[z2].base, zones.info[z2].count));
max_order = fnzb(z->count);
 
z->buddy_system = (buddy_system_t *) &z[1];
buddy_system_create(z->buddy_system, max_order,
&zone_buddy_system_operations, (void *) z);
 
z->frames = (frame_t *)((uint8_t *) z->buddy_system +
buddy_conf_size(max_order));
for (i = 0; i < z->count; i++) {
/* This marks all frames busy */
frame_initialize(&z->frames[i]);
}
/* Difference between zone bases */
pfn_t base_diff = zones.info[z2].base - zones.info[z1].base;
zones.info[z1].count = base_diff + zones.info[z2].count;
zones.info[z1].free_count += zones.info[z2].free_count;
zones.info[z1].busy_count += zones.info[z2].busy_count;
zones.info[z1].buddy_system = buddy;
uint8_t order = fnzb(zones.info[z1].count);
buddy_system_create(zones.info[z1].buddy_system, order,
&zone_buddy_system_operations, (void *) &zones.info[z1]);
zones.info[z1].frames =
(frame_t *) ((uint8_t *) zones.info[z1].buddy_system
+ buddy_conf_size(order));
/* This marks all frames busy */
size_t i;
for (i = 0; i < zones.info[z1].count; i++)
frame_initialize(&zones.info[z1].frames[i]);
/* Copy frames from both zones to preserve full frame orders,
* parents etc. Set all free frames with refcount=0 to 1, because
* we add all free frames to buddy allocator later again, clear
* order to 0. Don't set busy frames with refcount=0, as they
* parents etc. Set all free frames with refcount = 0 to 1, because
* we add all free frames to buddy allocator later again, clearing
* order to 0. Don't set busy frames with refcount = 0, as they
* will not be reallocated during merge and it would make later
* problems with allocation/free.
*/
for (i = 0; i < z1->count; i++)
z->frames[i] = z1->frames[i];
for (i = 0; i < z2->count; i++) {
z2idx = i + (z2->base - z1->base);
z->frames[z2idx] = z2->frames[i];
}
for (i = 0; i < old_z1->count; i++)
zones.info[z1].frames[i] = old_z1->frames[i];
for (i = 0; i < zones.info[z2].count; i++)
zones.info[z1].frames[base_diff + i]
= zones.info[z2].frames[i];
i = 0;
while (i < z->count) {
if (z->frames[i].refcount) {
/* skip busy frames */
i += 1 << z->frames[i].buddy_order;
} else { /* Free frames, set refcount=1 */
/* All free frames have refcount=0, we need not
* to check the order */
z->frames[i].refcount = 1;
z->frames[i].buddy_order = 0;
while (i < zones.info[z1].count) {
if (zones.info[z1].frames[i].refcount) {
/* Skip busy frames */
i += 1 << zones.info[z1].frames[i].buddy_order;
} else {
/* Free frames, set refcount = 1
* (all free frames have refcount == 0, we need not
* to check the order)
*/
zones.info[z1].frames[i].refcount = 1;
zones.info[z1].frames[i].buddy_order = 0;
i++;
}
}
/* Add free blocks from the 2 original zones */
while (zone_can_alloc(z1, 0)) {
frame_idx = zone_frame_alloc(z1, 0);
frame = &z->frames[frame_idx];
/* Add free blocks from the original zone z1 */
while (zone_can_alloc(old_z1, 0)) {
/* Allocate from the original zone */
pfn_t frame_idx = zone_frame_alloc(old_z1, 0);
/* Free the frame from the merged zone */
frame_t *frame = &zones.info[z1].frames[frame_idx];
frame->refcount = 0;
buddy_system_free(z->buddy_system, &frame->buddy_link);
buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
}
while (zone_can_alloc(z2, 0)) {
frame_idx = zone_frame_alloc(z2, 0);
frame = &z->frames[frame_idx + (z2->base - z1->base)];
/* Add free blocks from the original zone z2 */
while (zone_can_alloc(&zones.info[z2], 0)) {
/* Allocate from the original zone */
pfn_t frame_idx = zone_frame_alloc(&zones.info[z2], 0);
/* Free the frame from the merged zone */
frame_t *frame = &zones.info[z1].frames[base_diff + frame_idx];
frame->refcount = 0;
buddy_system_free(z->buddy_system, &frame->buddy_link);
buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
}
}
 
/** Return old configuration frames into the zone.
*
* We have several cases
* - the conf. data is outside of zone -> exit, shall we call frame_free??
* - the conf. data was created by zone_create or
* updated with reduce_region -> free every frame
* We have two cases:
* - The configuration data is outside the zone
* -> do nothing (perhaps call frame_free?)
* - The configuration data was created by zone_create
* or updated by reduce_region -> free every frame
*
* @param newzone The actual zone where freeing should occur.
* @param oldzone Pointer to old zone configuration data that should
* be freed from new zone.
* @param znum The actual zone where freeing should occur.
* @param pfn Old zone configuration frame.
* @param count Old zone frame count.
*
*/
static void return_config_frames(zone_t *newzone, zone_t *oldzone)
static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
{
pfn_t pfn;
frame_t *frame;
count_t cframes;
unsigned int i;
 
pfn = ADDR2PFN((uintptr_t)KA2PA(oldzone));
cframes = SIZE2FRAMES(zone_conf_size(oldzone->count));
ASSERT(zone_flags_available(zones.info[znum].flags));
if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
size_t cframes = SIZE2FRAMES(zone_conf_size(count));
if ((pfn < zones.info[znum].base)
|| (pfn >= zones.info[znum].base + zones.info[znum].count))
return;
frame_t *frame __attribute__ ((unused));
 
frame = &newzone->frames[pfn - newzone->base];
frame = &zones.info[znum].frames[pfn - zones.info[znum].base];
ASSERT(!frame->buddy_order);
 
size_t i;
for (i = 0; i < cframes; i++) {
newzone->busy_count++;
zone_frame_free(newzone, pfn+i-newzone->base);
zones.info[znum].busy_count++;
zone_frame_free(&zones.info[znum],
pfn - zones.info[znum].base + i);
}
}
 
/** Reduce allocated block to count of order 0 frames.
*
* The allocated block need 2^order frames of space. Reduce all frames
* in block to order 0 and free the unneeded frames. This means, that
* when freeing the previously allocated block starting with frame_idx,
* The allocated block needs 2^order frames. Reduce all frames
* in the block to order 0 and free the unneeded frames. This means that
* when freeing the previously allocated block starting with frame_idx,
* you have to free every frame.
*
* @param zone
* @param frame_idx Index to block.
* @param count Allocated space in block.
* @param znum Zone.
* @param frame_idx Index the first frame of the block.
* @param count Allocated frames in block.
*
*/
static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count)
static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
{
count_t i;
uint8_t order;
frame_t *frame;
ASSERT(zone_flags_available(zones.info[znum].flags));
ASSERT(frame_idx + count < zones.info[znum].count);
ASSERT(frame_idx + count < zone->count);
 
order = zone->frames[frame_idx].buddy_order;
ASSERT((count_t) (1 << order) >= count);
 
uint8_t order = zones.info[znum].frames[frame_idx].buddy_order;
ASSERT((size_t) (1 << order) >= count);
/* Reduce all blocks to order 0 */
for (i = 0; i < (count_t) (1 << order); i++) {
frame = &zone->frames[i + frame_idx];
size_t i;
for (i = 0; i < (size_t) (1 << order); i++) {
frame_t *frame = &zones.info[znum].frames[i + frame_idx];
frame->buddy_order = 0;
if (!frame->refcount)
frame->refcount = 1;
ASSERT(frame->refcount == 1);
}
/* Free unneeded frames */
for (i = count; i < (count_t) (1 << order); i++) {
zone_frame_free(zone, i + frame_idx);
}
for (i = count; i < (size_t) (1 << order); i++)
zone_frame_free(&zones.info[znum], i + frame_idx);
}
 
/** Merge zones z1 and z2.
*
* - the zones must be 2 zones with no zone existing in between,
* which means that z2 = z1+1
* The merged zones must be 2 zones with no zone existing in between
* (which means that z2 = z1 + 1). Both zones must be available zones
* with the same flags.
*
* - When you create a new zone, the frame allocator configuration does
* not to be 2^order size. Once the allocator is running it is no longer
* possible, merged configuration data occupies more space :-/
* When you create a new zone, the frame allocator configuration does
* not to be 2^order size. Once the allocator is running it is no longer
* possible, merged configuration data occupies more space :-/
*
* The function uses
*
*/
void zone_merge(unsigned int z1, unsigned int z2)
bool zone_merge(size_t z1, size_t z2)
{
ipl_t ipl;
zone_t *zone1, *zone2, *newzone;
unsigned int cframes;
uint8_t order;
unsigned int i;
pfn_t pfn;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
 
if ((z1 >= zones.count) || (z2 >= zones.count))
bool ret = true;
/* We can join only 2 zones with none existing inbetween,
* the zones have to be available and with the same
* set of flags
*/
if ((z1 >= zones.count) || (z2 >= zones.count)
|| (z2 - z1 != 1)
|| (!zone_flags_available(zones.info[z1].flags))
|| (!zone_flags_available(zones.info[z2].flags))
|| (zones.info[z1].flags != zones.info[z2].flags)) {
ret = false;
goto errout;
/* We can join only 2 zones with none existing inbetween */
if (z2 - z1 != 1)
goto errout;
 
zone1 = zones.info[z1];
zone2 = zones.info[z2];
spinlock_lock(&zone1->lock);
spinlock_lock(&zone2->lock);
 
cframes = SIZE2FRAMES(zone_conf_size(zone2->base + zone2->count -
zone1->base));
}
pfn_t cframes = SIZE2FRAMES(zone_conf_size(
zones.info[z2].base - zones.info[z1].base
+ zones.info[z2].count));
uint8_t order;
if (cframes == 1)
order = 0;
else
else
order = fnzb(cframes - 1) + 1;
 
/* Allocate zonedata inside one of the zones */
if (zone_can_alloc(zone1, order))
pfn = zone1->base + zone_frame_alloc(zone1, order);
else if (zone_can_alloc(zone2, order))
pfn = zone2->base + zone_frame_alloc(zone2, order);
else
goto errout2;
 
newzone = (zone_t *) PA2KA(PFN2ADDR(pfn));
 
_zone_merge(newzone, zone1, zone2);
 
/* Allocate merged zone data inside one of the zones */
pfn_t pfn;
if (zone_can_alloc(&zones.info[z1], order)) {
pfn = zones.info[z1].base + zone_frame_alloc(&zones.info[z1], order);
} else if (zone_can_alloc(&zones.info[z2], order)) {
pfn = zones.info[z2].base + zone_frame_alloc(&zones.info[z2], order);
} else {
ret = false;
goto errout;
}
/* Preserve original data from z1 */
zone_t old_z1 = zones.info[z1];
old_z1.buddy_system->data = (void *) &old_z1;
/* Do zone merging */
buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(pfn));
zone_merge_internal(z1, z2, &old_z1, buddy);
/* Free unneeded config frames */
zone_reduce_region(newzone, pfn - newzone->base, cframes);
zone_reduce_region(z1, pfn - zones.info[z1].base, cframes);
/* Subtract zone information from busy frames */
newzone->busy_count -= cframes;
 
/* Replace existing zones in zoneinfo list */
zones.info[z1] = newzone;
for (i = z2 + 1; i < zones.count; i++)
zones.info[z1].busy_count -= cframes;
/* Free old zone information */
return_config_frames(z1,
ADDR2PFN(KA2PA((uintptr_t) old_z1.frames)), old_z1.count);
return_config_frames(z1,
ADDR2PFN(KA2PA((uintptr_t) zones.info[z2].frames)),
zones.info[z2].count);
/* Move zones down */
size_t i;
for (i = z2 + 1; i < zones.count; i++) {
zones.info[i - 1] = zones.info[i];
zones.info[i - 1].buddy_system->data =
(void *) &zones.info[i - 1];
}
zones.count--;
 
/* Free old zone information */
return_config_frames(newzone, zone1);
return_config_frames(newzone, zone2);
errout2:
/* Nobody is allowed to enter to zone, so we are safe
* to touch the spinlocks last time */
spinlock_unlock(&zone1->lock);
spinlock_unlock(&zone2->lock);
errout:
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return ret;
}
 
/** Merge all zones into one big zone.
/** Merge all mergeable zones into one big zone.
*
* It is reasonable to do this on systems whose bios reports parts in chunks,
* so that we could have 1 zone (it's faster).
* It is reasonable to do this on systems where
* BIOS reports parts in chunks, so that we could
* have 1 zone (it's faster).
*
*/
void zone_merge_all(void)
{
int count = zones.count;
 
while (zones.count > 1 && --count) {
zone_merge(0, 1);
break;
size_t i = 0;
while (i < zones.count) {
if (!zone_merge(i, i + 1))
i++;
}
}
 
/** Create new frame zone.
*
* @param start Physical address of the first frame within the zone.
* @param count Count of frames in zone.
* @param z Address of configuration information of zone.
* @param flags Zone flags.
* @param zone Zone to construct.
* @param buddy Address of buddy system configuration information.
* @param start Physical address of the first frame within the zone.
* @param count Count of frames in zone.
* @param flags Zone flags.
*
* @return Initialized zone.
* @return Initialized zone.
*
*/
static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags)
static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags)
{
unsigned int i;
uint8_t max_order;
 
spinlock_initialize(&z->lock, "zone_lock");
z->base = start;
z->count = count;
 
/* Mask off flags that are calculated automatically. */
flags &= ~FRAME_LOW_4_GiB;
/* Determine calculated flags. */
if (z->base + count < (1ULL << (32 - FRAME_WIDTH))) /* 4 GiB */
flags |= FRAME_LOW_4_GiB;
 
z->flags = flags;
 
z->free_count = count;
z->busy_count = 0;
 
/*
* Compute order for buddy system, initialize
*/
max_order = fnzb(count);
z->buddy_system = (buddy_system_t *)&z[1];
zone->base = start;
zone->count = count;
zone->flags = flags;
zone->free_count = count;
zone->busy_count = 0;
zone->buddy_system = buddy;
buddy_system_create(z->buddy_system, max_order,
&zone_buddy_system_operations, (void *) z);
/* Allocate frames _after_ the conframe */
/* Check sizes */
z->frames = (frame_t *)((uint8_t *) z->buddy_system +
buddy_conf_size(max_order));
for (i = 0; i < count; i++) {
frame_initialize(&z->frames[i]);
}
/* Stuffing frames */
for (i = 0; i < count; i++) {
z->frames[i].refcount = 0;
buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
}
if (zone_flags_available(flags)) {
/*
* Compute order for buddy system and initialize
*/
uint8_t order = fnzb(count);
buddy_system_create(zone->buddy_system, order,
&zone_buddy_system_operations, (void *) zone);
/* Allocate frames _after_ the confframe */
/* Check sizes */
zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system +
buddy_conf_size(order));
size_t i;
for (i = 0; i < count; i++)
frame_initialize(&zone->frames[i]);
/* Stuffing frames */
for (i = 0; i < count; i++) {
zone->frames[i].refcount = 0;
buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link);
}
} else
zone->frames = NULL;
}
 
/** Compute configuration data size for zone.
*
* @param count Size of zone in frames.
* @return Size of zone configuration info (in bytes).
* @param count Size of zone in frames.
*
* @return Size of zone configuration info (in bytes).
*
*/
uintptr_t zone_conf_size(count_t count)
uintptr_t zone_conf_size(size_t count)
{
int size = sizeof(zone_t) + count * sizeof(frame_t);
int max_order;
 
max_order = fnzb(count);
size += buddy_conf_size(max_order);
return size;
return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
}
 
/** Create and add zone to system.
*
* @param start First frame number (absolute).
* @param count Size of zone in frames.
* @param confframe Where configuration frames are supposed to be.
* Automatically checks, that we will not disturb the
* kernel and possibly init. If confframe is given
* _outside_ this zone, it is expected, that the area is
* already marked BUSY and big enough to contain
* zone_conf_size() amount of data. If the confframe is
* inside the area, the zone free frame information is
* modified not to include it.
* @param start First frame number (absolute).
* @param count Size of zone in frames.
* @param confframe Where configuration frames are supposed to be.
* Automatically checks, that we will not disturb the
* kernel and possibly init. If confframe is given
* _outside_ this zone, it is expected, that the area is
* already marked BUSY and big enough to contain
* zone_conf_size() amount of data. If the confframe is
* inside the area, the zone free frame information is
* modified not to include it.
*
* @return Zone number or -1 on error.
* @return Zone number or -1 on error.
*
*/
int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
size_t zone_create(pfn_t start, size_t count, pfn_t confframe, zone_flags_t flags)
{
zone_t *z;
uintptr_t addr;
count_t confcount;
unsigned int i;
int znum;
 
/* Theoretically we could have here 0, practically make sure
* nobody tries to do that. If some platform requires, remove
* the assert
*/
ASSERT(confframe);
/* If conframe is supposed to be inside our zone, then make sure
* it does not span kernel & init
*/
confcount = SIZE2FRAMES(zone_conf_size(count));
if (confframe >= start && confframe < start + count) {
for (; confframe < start + count; confframe++) {
addr = PFN2ADDR(confframe);
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.base), config.kernel_size))
continue;
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.stack_base), config.stack_size))
continue;
bool overlap = false;
count_t i;
for (i = 0; i < init.cnt; i++)
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (zone_flags_available(flags)) { /* Create available zone */
/* Theoretically we could have NULL here, practically make sure
* nobody tries to do that. If some platform requires, remove
* the assert
*/
ASSERT(confframe != NULL);
/* If confframe is supposed to be inside our zone, then make sure
* it does not span kernel & init
*/
size_t confcount = SIZE2FRAMES(zone_conf_size(count));
if ((confframe >= start) && (confframe < start + count)) {
for (; confframe < start + count; confframe++) {
uintptr_t addr = PFN2ADDR(confframe);
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(init.tasks[i].addr),
init.tasks[i].size)) {
overlap = true;
break;
}
if (overlap)
continue;
KA2PA(config.base), config.kernel_size))
continue;
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.stack_base), config.stack_size))
continue;
bool overlap = false;
size_t i;
for (i = 0; i < init.cnt; i++)
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(init.tasks[i].addr),
init.tasks[i].size)) {
overlap = true;
break;
}
if (overlap)
continue;
break;
}
break;
if (confframe >= start + count)
panic("Cannot find configuration data for zone.");
}
if (confframe >= start + count)
panic("Cannot find configuration data for zone.");
size_t znum = zones_insert_zone(start, count);
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return (size_t) -1;
}
buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe));
zone_construct(&zones.info[znum], buddy, start, count, flags);
/* If confdata in zone, mark as unavailable */
if ((confframe >= start) && (confframe < start + count)) {
size_t i;
for (i = confframe; i < confframe + confcount; i++)
zone_mark_unavailable(&zones.info[znum],
i - zones.info[znum].base);
}
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return znum;
}
 
z = (zone_t *) PA2KA(PFN2ADDR(confframe));
zone_construct(start, count, z, flags);
znum = zones_add_zone(z);
if (znum == -1)
return -1;
 
mutex_lock(&mem_avail_mtx);
mem_avail_frames += count;
mutex_unlock(&mem_avail_mtx);
 
/* If confdata in zone, mark as unavailable */
if (confframe >= start && confframe < start + count)
for (i = confframe; i < confframe + confcount; i++) {
zone_mark_unavailable(z, i - z->base);
}
/* Non-available zone */
size_t znum = zones_insert_zone(start, count);
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return (size_t) -1;
}
zone_construct(&zones.info[znum], NULL, start, count, flags);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return znum;
}
 
/***************************************/
/*******************/
/* Frame functions */
/*******************/
 
/** Set parent of frame. */
void frame_set_parent(pfn_t pfn, void *data, unsigned int hint)
void frame_set_parent(pfn_t pfn, void *data, size_t hint)
{
zone_t *zone = find_zone_and_lock(pfn, &hint);
 
ASSERT(zone);
 
zone_get_frame(zone, pfn - zone->base)->parent = data;
spinlock_unlock(&zone->lock);
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
size_t znum = find_zone(pfn, 1, hint);
ASSERT(znum != (size_t) -1);
zone_get_frame(&zones.info[znum],
pfn - zones.info[znum].base)->parent = data;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
void *frame_get_parent(pfn_t pfn, unsigned int hint)
void *frame_get_parent(pfn_t pfn, size_t hint)
{
zone_t *zone = find_zone_and_lock(pfn, &hint);
void *res;
 
ASSERT(zone);
res = zone_get_frame(zone, pfn - zone->base)->parent;
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
spinlock_unlock(&zone->lock);
size_t znum = find_zone(pfn, 1, hint);
ASSERT(znum != (size_t) -1);
void *res = zone_get_frame(&zones.info[znum],
pfn - zones.info[znum].base)->parent;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return res;
}
 
/** Allocate power-of-two frames of physical memory.
*
* @param order Allocate exactly 2^order frames.
* @param flags Flags for host zone selection and address processing.
* @param pzone Preferred zone.
* @param order Allocate exactly 2^order frames.
* @param flags Flags for host zone selection and address processing.
* @param pzone Preferred zone.
*
* @return Physical address of the allocated frame.
* @return Physical address of the allocated frame.
*
*/
void *frame_alloc_generic(uint8_t order, int flags, unsigned int *pzone)
void *frame_alloc_generic(uint8_t order, frame_flags_t flags, size_t *pzone)
{
size_t size = ((size_t) 1) << order;
ipl_t ipl;
int freed;
pfn_t v;
zone_t *zone;
unsigned long gen = 0;
size_t hint = pzone ? (*pzone) : 0;
loop:
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/*
* First, find suitable frame zone.
*/
zone = find_free_zone_and_lock(order, flags, pzone);
size_t znum = find_free_zone(order,
FRAME_TO_ZONE_FLAGS(flags), hint);
/* If no memory, reclaim some slab memory,
if it does not help, reclaim all */
if (!zone && !(flags & FRAME_NO_RECLAIM)) {
freed = slab_reclaim(0);
if (freed)
zone = find_free_zone_and_lock(order, flags, pzone);
if (!zone) {
if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
size_t freed = slab_reclaim(0);
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (freed > 0)
znum = find_free_zone(order,
FRAME_TO_ZONE_FLAGS(flags), hint);
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
freed = slab_reclaim(SLAB_RECLAIM_ALL);
if (freed)
zone = find_free_zone_and_lock(order, flags,
pzone);
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (freed > 0)
znum = find_free_zone(order,
FRAME_TO_ZONE_FLAGS(flags), hint);
}
}
if (!zone) {
/*
* Sleep until some frames are available again.
*/
if (znum == (size_t) -1) {
if (flags & FRAME_ATOMIC) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return 0;
return NULL;
}
#ifdef CONFIG_DEBUG
unsigned long avail;
 
mutex_lock(&mem_avail_mtx);
avail = mem_avail_frames;
mutex_unlock(&mem_avail_mtx);
 
printf("Thread %" PRIu64 " waiting for %u frames, "
"%u available.\n", THREAD->tid, 1ULL << order, avail);
size_t avail = total_frames_free();
#endif
 
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
/*
* Sleep until some frames are available again.
*/
#ifdef CONFIG_DEBUG
printf("Thread %" PRIu64 " waiting for %" PRIs " frames, "
"%" PRIs " available.\n", THREAD->tid, size, avail);
#endif
mutex_lock(&mem_avail_mtx);
while ((mem_avail_frames < (1ULL << order)) ||
gen == mem_avail_gen)
if (mem_avail_req > 0)
mem_avail_req = min(mem_avail_req, size);
else
mem_avail_req = size;
size_t gen = mem_avail_gen;
while (gen == mem_avail_gen)
condvar_wait(&mem_avail_cv, &mem_avail_mtx);
gen = mem_avail_gen;
mutex_unlock(&mem_avail_mtx);
 
#ifdef CONFIG_DEBUG
mutex_lock(&mem_avail_mtx);
avail = mem_avail_frames;
mutex_unlock(&mem_avail_mtx);
 
printf("Thread %" PRIu64 " woken up, %u frames available.\n",
THREAD->tid, avail);
printf("Thread %" PRIu64 " woken up.\n", THREAD->tid);
#endif
 
interrupts_restore(ipl);
goto loop;
}
v = zone_frame_alloc(zone, order);
v += zone->base;
 
spinlock_unlock(&zone->lock);
pfn_t pfn = zone_frame_alloc(&zones.info[znum], order)
+ zones.info[znum].base;
mutex_lock(&mem_avail_mtx);
mem_avail_frames -= (1ULL << order);
mutex_unlock(&mem_avail_mtx);
 
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
if (pzone)
*pzone = znum;
if (flags & FRAME_KA)
return (void *)PA2KA(PFN2ADDR(v));
return (void *)PFN2ADDR(v);
return (void *) PA2KA(PFN2ADDR(pfn));
return (void *) PFN2ADDR(pfn);
}
 
/** Free a frame.
*
* Find respective frame structure for supplied physical frame address.
* Decrement frame reference count.
* If it drops to zero, move the frame structure to free list.
* Decrement frame reference count. If it drops to zero, move the frame
* structure to free list.
*
* @param frame Physical Address of of the frame to be freed.
* @param frame Physical Address of of the frame to be freed.
*
*/
void frame_free(uintptr_t frame)
{
ipl_t ipl;
zone_t *zone;
pfn_t pfn = ADDR2PFN(frame);
 
ipl = interrupts_disable();
 
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/*
* First, find host frame zone for addr.
*/
zone = find_zone_and_lock(pfn, NULL);
ASSERT(zone);
pfn_t pfn = ADDR2PFN(frame);
size_t znum = find_zone(pfn, 1, NULL);
zone_frame_free(zone, pfn - zone->base);
ASSERT(znum != (size_t) -1);
spinlock_unlock(&zone->lock);
zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
/*
* Signal that some memory has been freed.
*/
mutex_lock(&mem_avail_mtx);
mem_avail_frames++;
mem_avail_gen++;
condvar_broadcast(&mem_avail_cv);
if (mem_avail_req > 0)
mem_avail_req--;
if (mem_avail_req == 0) {
mem_avail_gen++;
condvar_broadcast(&mem_avail_cv);
}
mutex_unlock(&mem_avail_mtx);
 
interrupts_restore(ipl);
}
 
/** Add reference to frame.
1115,44 → 1123,45
* Find respective frame structure for supplied PFN and
* increment frame reference count.
*
* @param pfn Frame number of the frame to be freed.
* @param pfn Frame number of the frame to be freed.
*
*/
void frame_reference_add(pfn_t pfn)
{
ipl_t ipl;
zone_t *zone;
frame_t *frame;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/*
* First, find host frame zone for addr.
*/
zone = find_zone_and_lock(pfn, NULL);
ASSERT(zone);
size_t znum = find_zone(pfn, 1, NULL);
frame = &zone->frames[pfn - zone->base];
frame->refcount++;
ASSERT(znum != (size_t) -1);
spinlock_unlock(&zone->lock);
zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/** Mark given range unavailable in frame zones. */
void frame_mark_unavailable(pfn_t start, count_t count)
void frame_mark_unavailable(pfn_t start, size_t count)
{
unsigned int i;
zone_t *zone;
unsigned int prefzone = 0;
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
size_t i;
for (i = 0; i < count; i++) {
zone = find_zone_and_lock(start + i, &prefzone);
if (!zone) /* PFN not found */
size_t znum = find_zone(start + i, 1, 0);
if (znum == (size_t) -1) /* PFN not found */
continue;
zone_mark_unavailable(zone, start + i - zone->base);
 
spinlock_unlock(&zone->lock);
zone_mark_unavailable(&zones.info[znum],
start + i - zones.info[znum].base);
}
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/** Initialize physical memory management. */
1164,6 → 1173,7
mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
condvar_initialize(&mem_avail_cv);
}
/* Tell the architecture to create some memory */
frame_arch_init();
if (config.cpu_active == 1) {
1172,41 → 1182,34
frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)),
SIZE2FRAMES(config.stack_size));
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++) {
pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr));
frame_mark_unavailable(pfn,
SIZE2FRAMES(init.tasks[i].size));
}
 
if (ballocs.size)
frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)),
SIZE2FRAMES(ballocs.size));
 
/* Black list first frame, as allocating NULL would
* fail in some places */
* fail in some places
*/
frame_mark_unavailable(0, 1);
}
}
 
 
/** Return total size of all zones. */
uint64_t zone_total_size(void)
{
zone_t *zone = NULL;
unsigned int i;
ipl_t ipl;
uint64_t total = 0;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
for (i = 0; i < zones.count; i++) {
zone = zones.info[i];
spinlock_lock(&zone->lock);
total += (uint64_t) FRAMES2SIZE(zone->count);
spinlock_unlock(&zone->lock);
}
uint64_t total = 0;
size_t i;
for (i = 0; i < zones.count; i++)
total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
1217,18 → 1220,14
/** Prints list of zones. */
void zone_print_list(void)
{
zone_t *zone = NULL;
unsigned int i;
ipl_t ipl;
 
#ifdef __32_BITS__
printf("# base address free frames busy frames\n");
printf("-- ------------ ------------ ------------\n");
#ifdef __32_BITS__
printf("# base address frames flags free frames busy frames\n");
printf("-- ------------ ------------ -------- ------------ ------------\n");
#endif
 
#ifdef __64_BITS__
printf("# base address free frames busy frames\n");
printf("-- -------------------- ------------ ------------\n");
printf("# base address frames flags free frames busy frames\n");
printf("-- -------------------- ------------ -------- ------------ ------------\n");
#endif
/*
1241,13 → 1240,10
* we may end up with inaccurate output (e.g. a zone being skipped from
* the listing).
*/
 
for (i = 0; ; i++) {
uintptr_t base;
count_t free_count;
count_t busy_count;
 
ipl = interrupts_disable();
size_t i;
for (i = 0;; i++) {
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (i >= zones.count) {
1255,56 → 1251,61
interrupts_restore(ipl);
break;
}
 
zone = zones.info[i];
spinlock_lock(&zone->lock);
 
base = PFN2ADDR(zone->base);
free_count = zone->free_count;
busy_count = zone->busy_count;
 
spinlock_unlock(&zone->lock);
uintptr_t base = PFN2ADDR(zones.info[i].base);
size_t count = zones.info[i].count;
zone_flags_t flags = zones.info[i].flags;
size_t free_count = zones.info[i].free_count;
size_t busy_count = zones.info[i].busy_count;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
bool available = zone_flags_available(flags);
printf("%-2" PRIs, i);
#ifdef __32_BITS__
printf("%-2u %10p %12" PRIc " %12" PRIc "\n", i, base,
free_count, busy_count);
printf(" %10p", base);
#endif
 
#ifdef __64_BITS__
printf("%-2u %18p %12" PRIc " %12" PRIc "\n", i, base,
free_count, busy_count);
printf(" %18p", base);
#endif
printf(" %12" PRIs " %c%c%c ", count,
available ? 'A' : ' ',
(flags & ZONE_RESERVED) ? 'R' : ' ',
(flags & ZONE_FIRMWARE) ? 'F' : ' ');
if (available)
printf("%12" PRIs " %12" PRIs,
free_count, busy_count);
printf("\n");
}
}
 
/** Prints zone details.
*
* @param num Zone base address or zone number.
* @param num Zone base address or zone number.
*
*/
void zone_print_one(unsigned int num)
void zone_print_one(size_t num)
{
zone_t *zone = NULL;
ipl_t ipl;
unsigned int i;
uintptr_t base;
count_t count;
count_t busy_count;
count_t free_count;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
 
size_t znum = (size_t) -1;
size_t i;
for (i = 0; i < zones.count; i++) {
if ((i == num) || (PFN2ADDR(zones.info[i]->base) == num)) {
zone = zones.info[i];
if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) {
znum = i;
break;
}
}
if (!zone) {
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
printf("Zone not found.\n");
1311,24 → 1312,33
return;
}
spinlock_lock(&zone->lock);
base = PFN2ADDR(zone->base);
count = zone->count;
busy_count = zone->busy_count;
free_count = zone->free_count;
spinlock_unlock(&zone->lock);
uintptr_t base = PFN2ADDR(zones.info[i].base);
zone_flags_t flags = zones.info[i].flags;
size_t count = zones.info[i].count;
size_t free_count = zones.info[i].free_count;
size_t busy_count = zones.info[i].busy_count;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
bool available = zone_flags_available(flags);
printf("Zone number: %" PRIs "\n", znum);
printf("Zone base address: %p\n", base);
printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count,
printf("Zone size: %" PRIs " frames (%" PRIs " KiB)\n", count,
SIZE2KB(FRAMES2SIZE(count)));
printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n",
busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n",
free_count, SIZE2KB(FRAMES2SIZE(free_count)));
printf("Zone flags: %c%c%c\n",
available ? 'A' : ' ',
(flags & ZONE_RESERVED) ? 'R' : ' ',
(flags & ZONE_FIRMWARE) ? 'F' : ' ');
if (available) {
printf("Allocated space: %" PRIs " frames (%" PRIs " KiB)\n",
busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
printf("Available space: %" PRIs " frames (%" PRIs " KiB)\n",
free_count, SIZE2KB(FRAMES2SIZE(free_count)));
}
}
 
/** @}
*/
 
/branches/arm/kernel/generic/src/mm/backend_elf.c
82,7 → 82,7
elf_segment_header_t *entry = area->backend_data.segment;
btree_node_t *leaf;
uintptr_t base, frame, page, start_anon;
index_t i;
size_t i;
bool dirty = false;
 
if (!as_area_check_access(area, access))
129,7 → 129,7
page_mapping_insert(AS, addr, frame,
as_area_get_flags(area));
if (!used_space_insert(area, page, 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
mutex_unlock(&area->sh_info->lock);
return AS_PF_OK;
}
214,7 → 214,7
 
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, page, 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
 
return AS_PF_OK;
}
234,7 → 234,7
elf_header_t *elf = area->backend_data.elf;
elf_segment_header_t *entry = area->backend_data.segment;
uintptr_t base, start_anon;
index_t i;
size_t i;
 
ASSERT((page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) &&
(page < entry->p_vaddr + entry->p_memsz));
304,7 → 304,7
for (i = 0; i < node->keys; i++) {
uintptr_t base = node->key[i];
count_t count = (count_t) node->value[i];
size_t count = (size_t) node->value[i];
unsigned int j;
/*
/branches/arm/kernel/generic/src/mm/buddy.c
46,7 → 46,7
#include <macros.h>
 
/** Return size needed for the buddy configuration data. */
size_t buddy_conf_size(int max_order)
size_t buddy_conf_size(size_t max_order)
{
return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t);
}
/branches/arm/kernel/generic/src/mm/backend_phys.c
77,7 → 77,7
page_mapping_insert(AS, addr, base + (addr - area->base),
as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
 
return AS_PF_OK;
}
/branches/arm/kernel/generic/src/ipc/event.c
0,0 → 1,154
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup generic
* @{
*/
/**
* @file
* @brief Kernel event notifications.
*/
 
#include <ipc/event.h>
#include <ipc/event_types.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <synch/spinlock.h>
#include <console/console.h>
#include <memstr.h>
#include <errno.h>
#include <arch.h>
 
/**
* The events array.
* Arranging the events in this two-dimensional array should decrease the
* likelyhood of cacheline ping-pong.
*/
static event_t events[EVENT_END];
 
/** Initialize kernel events. */
void event_init(void)
{
unsigned int i;
for (i = 0; i < EVENT_END; i++) {
spinlock_initialize(&events[i].lock, "event.lock");
events[i].answerbox = NULL;
events[i].counter = 0;
events[i].method = 0;
}
}
 
static int event_subscribe(event_type_t evno, unative_t method,
answerbox_t *answerbox)
{
if (evno >= EVENT_END)
return ELIMIT;
spinlock_lock(&events[evno].lock);
int res;
if (events[evno].answerbox == NULL) {
events[evno].answerbox = answerbox;
events[evno].method = method;
events[evno].counter = 0;
res = EOK;
} else
res = EEXISTS;
spinlock_unlock(&events[evno].lock);
return res;
}
 
unative_t sys_event_subscribe(unative_t evno, unative_t method)
{
return (unative_t) event_subscribe((event_type_t) evno, (unative_t)
method, &TASK->answerbox);
}
 
bool event_is_subscribed(event_type_t evno)
{
bool res;
ASSERT(evno < EVENT_END);
spinlock_lock(&events[evno].lock);
res = events[evno].answerbox != NULL;
spinlock_unlock(&events[evno].lock);
return res;
}
 
 
void event_cleanup_answerbox(answerbox_t *answerbox)
{
unsigned int i;
for (i = 0; i < EVENT_END; i++) {
spinlock_lock(&events[i].lock);
if (events[i].answerbox == answerbox) {
events[i].answerbox = NULL;
events[i].counter = 0;
events[i].method = 0;
}
spinlock_unlock(&events[i].lock);
}
}
 
void event_notify(event_type_t evno, unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5)
{
ASSERT(evno < EVENT_END);
spinlock_lock(&events[evno].lock);
if (events[evno].answerbox != NULL) {
call_t *call = ipc_call_alloc(FRAME_ATOMIC);
if (call) {
call->flags |= IPC_CALL_NOTIF;
call->priv = ++events[evno].counter;
IPC_SET_METHOD(call->data, events[evno].method);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
spinlock_lock(&events[evno].answerbox->irq_lock);
list_append(&call->link, &events[evno].answerbox->irq_notifs);
spinlock_unlock(&events[evno].answerbox->irq_lock);
waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
}
}
spinlock_unlock(&events[evno].lock);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/generic/src/ipc/sysipc.c
93,6 → 93,8
static inline int method_is_forwardable(unative_t method)
{
switch (method) {
case IPC_M_CONNECTION_CLONE:
case IPC_M_CONNECT_ME:
case IPC_M_PHONE_HUNGUP:
/* This message is meant only for the original recipient. */
return 0;
140,6 → 142,8
static inline int answer_need_old(call_t *call)
{
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_CONNECTION_CLONE:
case IPC_M_CONNECT_ME:
case IPC_M_CONNECT_TO_ME:
case IPC_M_CONNECT_ME_TO:
case IPC_M_SHARE_OUT:
182,9 → 186,48
if (!olddata)
return 0;
 
if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTION_CLONE) {
phoneid = IPC_GET_ARG1(*olddata);
phone_t *phone = &TASK->phones[phoneid];
if (IPC_GET_RETVAL(answer->data) != EOK) {
/*
* The recipient of the cloned phone rejected the offer.
* In this case, the connection was established at the
* request time and therefore we need to slam the phone.
* We don't merely hangup as that would result in
* sending IPC_M_HUNGUP to the third party on the
* other side of the cloned phone.
*/
mutex_lock(&phone->lock);
if (phone->state == IPC_PHONE_CONNECTED) {
spinlock_lock(&phone->callee->lock);
list_remove(&phone->link);
phone->state = IPC_PHONE_SLAMMED;
spinlock_unlock(&phone->callee->lock);
}
mutex_unlock(&phone->lock);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME) {
phone_t *phone = (phone_t *)IPC_GET_ARG5(*olddata);
if (IPC_GET_RETVAL(answer->data) != EOK) {
/*
* The other party on the cloned phoned rejected our
* request for connection on the protocol level.
* We need to break the connection without sending
* IPC_M_HUNGUP back.
*/
mutex_lock(&phone->lock);
if (phone->state == IPC_PHONE_CONNECTED) {
spinlock_lock(&phone->callee->lock);
list_remove(&phone->link);
phone->state = IPC_PHONE_SLAMMED;
spinlock_unlock(&phone->callee->lock);
}
mutex_unlock(&phone->lock);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
phoneid = IPC_GET_ARG5(*olddata);
if (IPC_GET_RETVAL(answer->data)) {
if (IPC_GET_RETVAL(answer->data) != EOK) {
/* The connection was not accepted */
phone_dealloc(phoneid);
} else {
196,7 → 239,7
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
/* If the users accepted call, connect */
if (!IPC_GET_RETVAL(answer->data)) {
if (IPC_GET_RETVAL(answer->data) == EOK) {
ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata),
&TASK->answerbox);
}
293,6 → 336,26
return 0;
}
 
static void phones_lock(phone_t *p1, phone_t *p2)
{
if (p1 < p2) {
mutex_lock(&p1->lock);
mutex_lock(&p2->lock);
} else if (p1 > p2) {
mutex_lock(&p2->lock);
mutex_lock(&p1->lock);
} else {
mutex_lock(&p1->lock);
}
}
 
static void phones_unlock(phone_t *p1, phone_t *p2)
{
mutex_unlock(&p1->lock);
if (p1 != p2)
mutex_unlock(&p2->lock);
}
 
/** Called before the request is sent.
*
* @param call Call structure with the request.
308,8 → 371,39
int rc;
 
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_CONNECTION_CLONE: {
phone_t *cloned_phone;
GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
return ENOENT);
phones_lock(cloned_phone, phone);
if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
phone->state != IPC_PHONE_CONNECTED) {
phones_unlock(cloned_phone, phone);
return EINVAL;
}
/*
* We can be pretty sure now that both tasks exist and we are
* connected to them. As we continue to hold the phone locks,
* we are effectively preventing them from finishing their
* potential cleanup.
*/
newphid = phone_alloc(phone->callee->task);
if (newphid < 0) {
phones_unlock(cloned_phone, phone);
return ELIMIT;
}
ipc_phone_connect(&phone->callee->task->phones[newphid],
cloned_phone->callee);
phones_unlock(cloned_phone, phone);
/* Set the new phone for the callee. */
IPC_SET_ARG1(call->data, newphid);
break;
}
case IPC_M_CONNECT_ME:
IPC_SET_ARG5(call->data, (unative_t) phone);
break;
case IPC_M_CONNECT_ME_TO:
newphid = phone_alloc();
newphid = phone_alloc(TASK);
if (newphid < 0)
return ELIMIT;
/* Set arg5 for server */
332,7 → 426,7
src = IPC_GET_ARG1(call->data);
size = IPC_GET_ARG2(call->data);
if ((size <= 0) || (size > DATA_XFER_LIMIT))
if (size > DATA_XFER_LIMIT)
return ELIMIT;
call->buffer = (uint8_t *) malloc(size, 0);
399,7 → 493,7
int phoneid;
 
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) {
phoneid = phone_alloc();
phoneid = phone_alloc(TASK);
if (phoneid < 0) { /* Failed to allocate phone */
IPC_SET_RETVAL(call->data, ELIMIT);
ipc_answer(box, call);
455,10 → 549,17
IPC_SET_ARG5(call.data, 0);
 
if (!(res = request_preprocess(&call, phone))) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = ipc_call_sync(phone, &call);
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
if (rc != EOK)
return rc;
process_answer(&call);
 
} else {
IPC_SET_RETVAL(call.data, res);
}
495,7 → 596,13
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res = request_preprocess(&call, phone))) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = ipc_call_sync(phone, &call);
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
if (rc != EOK)
return rc;
process_answer(&call);
605,7 → 712,8
return (unative_t) call;
}
 
/** Forward a received call to another destination.
/** Forward a received call to another destination - common code for both the
* fast and the slow version.
*
* @param callid Hash of the call to forward.
* @param phoneid Phone handle to use for forwarding.
612,23 → 720,21
* @param method New method to use for the forwarded call.
* @param arg1 New value of the first argument for the forwarded call.
* @param arg2 New value of the second argument for the forwarded call.
* @param arg3 New value of the third argument for the forwarded call.
* @param arg4 New value of the fourth argument for the forwarded call.
* @param arg5 New value of the fifth argument for the forwarded call.
* @param mode Flags that specify mode of the forward operation.
* @param slow If true, arg3, arg4 and arg5 are considered. Otherwise
* the function considers only the fast version arguments:
* i.e. arg1 and arg2.
*
* @return Return 0 on succes, otherwise return an error code.
*
* In case the original method is a system method, ARG1, ARG2 and ARG3 are
* overwritten in the forwarded message with the new method and the new arg1 and
* arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are rewritten with
* the new method, arg1 and arg2, respectively. Also note there is a set of
* immutable methods, for which the new method and argument is not set and
* these values are ignored.
*
* Warning: When implementing support for changing additional payload
* arguments, make sure that ARG5 is not rewritten for certain
* system IPC
* Warning: Make sure that ARG5 is not rewritten for certain system IPC
*/
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, int mode)
static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, unative_t arg3,
unative_t arg4, unative_t arg5, int mode, bool slow)
{
call_t *call;
phone_t *phone;
636,7 → 742,7
call = get_call(callid);
if (!call)
return ENOENT;
 
call->flags |= IPC_CALL_FORWARDED;
 
GET_CHECK_PHONE(phone, phoneid, {
653,8 → 759,8
 
/*
* Userspace is not allowed to change method of system methods on
* forward, allow changing ARG1, ARG2 and ARG3 by means of method,
* arg1 and arg2.
* forward, allow changing ARG1, ARG2, ARG3 and ARG4 by means of method,
* arg1, arg2 and arg3.
* If the method is immutable, don't change anything.
*/
if (!method_is_immutable(IPC_GET_METHOD(call->data))) {
665,10 → 771,22
IPC_SET_ARG1(call->data, method);
IPC_SET_ARG2(call->data, arg1);
IPC_SET_ARG3(call->data, arg2);
if (slow) {
IPC_SET_ARG4(call->data, arg3);
/*
* For system methods we deliberately don't
* overwrite ARG5.
*/
}
} else {
IPC_SET_METHOD(call->data, method);
IPC_SET_ARG1(call->data, arg1);
IPC_SET_ARG2(call->data, arg2);
if (slow) {
IPC_SET_ARG3(call->data, arg3);
IPC_SET_ARG4(call->data, arg4);
IPC_SET_ARG5(call->data, arg5);
}
}
}
 
675,6 → 793,64
return ipc_forward(call, phone, &TASK->answerbox, mode);
}
 
/** Forward a received call to another destination - fast version.
*
* @param callid Hash of the call to forward.
* @param phoneid Phone handle to use for forwarding.
* @param method New method to use for the forwarded call.
* @param arg1 New value of the first argument for the forwarded call.
* @param arg2 New value of the second argument for the forwarded call.
* @param mode Flags that specify mode of the forward operation.
*
* @return Return 0 on succes, otherwise return an error code.
*
* In case the original method is a system method, ARG1, ARG2 and ARG3 are
* overwritten in the forwarded message with the new method and the new
* arg1 and arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are
* rewritten with the new method, arg1 and arg2, respectively. Also note there
* is a set of immutable methods, for which the new method and arguments are not
* set and these values are ignored.
*/
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, int mode)
{
return sys_ipc_forward_common(callid, phoneid, method, arg1, arg2, 0, 0,
0, mode, false);
}
 
/** Forward a received call to another destination - slow version.
*
* @param callid Hash of the call to forward.
* @param phoneid Phone handle to use for forwarding.
* @param data Userspace address of the new IPC data.
* @param mode Flags that specify mode of the forward operation.
*
* @return Return 0 on succes, otherwise return an error code.
*
* This function is the slow verision of the sys_ipc_forward_fast interface.
* It can copy all five new arguments and the new method from the userspace.
* It naturally extends the functionality of the fast version. For system
* methods, it additionally stores the new value of arg3 to ARG4. For non-system
* methods, it additionally stores the new value of arg3, arg4 and arg5,
* respectively, to ARG3, ARG4 and ARG5, respectively.
*/
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
ipc_data_t *data, int mode)
{
ipc_data_t newdata;
int rc;
 
rc = copy_from_uspace(&newdata.args, &data->args,
sizeof(newdata.args));
if (rc != 0)
return (unative_t) rc;
 
return sys_ipc_forward_common(callid, phoneid,
IPC_GET_METHOD(newdata), IPC_GET_ARG1(newdata),
IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true);
}
 
/** Answer an IPC call - fast version.
*
* This function can handle only two return arguments of payload, but is faster
798,9 → 974,17
{
call_t *call;
 
restart:
restart:
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
call = ipc_wait_for_call(&TASK->answerbox, usec,
flags | SYNCH_FLAGS_INTERRUPTIBLE);
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
if (!call)
return 0;
 
846,6 → 1030,21
/* Include phone address('id') of the caller in the request,
* copy whole call->data, not only call->data.args */
if (STRUCT_TO_USPACE(calldata, &call->data)) {
/*
* The callee will not receive this call and no one else has
* a chance to answer it. Reply with the EPARTY error code.
*/
ipc_data_t saved_data;
int saveddata = 0;
 
if (answer_need_old(call)) {
memcpy(&saved_data, &call->data, sizeof(call->data));
saveddata = 1;
}
IPC_SET_RETVAL(call->data, EPARTY);
(void) answer_preprocess(call, saveddata ? &saved_data : NULL);
ipc_answer(&TASK->answerbox, call);
return 0;
}
return (unative_t)call;
/branches/arm/kernel/generic/src/ipc/ipcrsc.c
160,27 → 160,29
return result;
}
 
/** Allocate new phone slot in the current TASK structure.
/** Allocate new phone slot in the specified task.
*
* @param t Task for which to allocate a new phone.
*
* @return New phone handle or -1 if the phone handle limit is
* exceeded.
*/
int phone_alloc(void)
int phone_alloc(task_t *t)
{
int i;
 
spinlock_lock(&TASK->lock);
spinlock_lock(&t->lock);
for (i = 0; i < IPC_MAX_PHONES; i++) {
if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
atomic_get(&TASK->phones[i].active_calls) == 0)
TASK->phones[i].state = IPC_PHONE_FREE;
if (t->phones[i].state == IPC_PHONE_HUNGUP &&
atomic_get(&t->phones[i].active_calls) == 0)
t->phones[i].state = IPC_PHONE_FREE;
 
if (TASK->phones[i].state == IPC_PHONE_FREE) {
TASK->phones[i].state = IPC_PHONE_CONNECTING;
if (t->phones[i].state == IPC_PHONE_FREE) {
t->phones[i].state = IPC_PHONE_CONNECTING;
break;
}
}
spinlock_unlock(&TASK->lock);
spinlock_unlock(&t->lock);
 
if (i == IPC_MAX_PHONES)
return -1;
/branches/arm/kernel/generic/src/ipc/kbox.c
42,19 → 42,27
#include <debug.h>
#include <udebug/udebug_ipc.h>
#include <ipc/kbox.h>
#include <print.h>
 
void ipc_kbox_cleanup(void)
{
ipl_t ipl;
bool have_kb_thread;
 
/* Only hold kb_cleanup_lock while setting kb_finished - this is enough */
mutex_lock(&TASK->kb_cleanup_lock);
TASK->kb_finished = true;
mutex_unlock(&TASK->kb_cleanup_lock);
/*
* Only hold kb.cleanup_lock while setting kb.finished -
* this is enough.
*/
mutex_lock(&TASK->kb.cleanup_lock);
TASK->kb.finished = true;
mutex_unlock(&TASK->kb.cleanup_lock);
 
have_kb_thread = (TASK->kb_thread != NULL);
have_kb_thread = (TASK->kb.thread != NULL);
 
/* From now on nobody will try to connect phones or attach kbox threads */
/*
* From now on nobody will try to connect phones or attach
* kbox threads
*/
 
/*
* Disconnect all phones connected to our kbox. Passing true for
62,83 → 70,136
* disconnected phone. This ensures the kbox thread is going to
* wake up and terminate.
*/
ipc_answerbox_slam_phones(&TASK->kernel_box, have_kb_thread);
ipc_answerbox_slam_phones(&TASK->kb.box, have_kb_thread);
 
/*
* If the task was being debugged, clean up debugging session.
* This is necessarry as slamming the phones won't force
* kbox thread to clean it up since sender != debugger.
*/
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
udebug_task_cleanup(TASK);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
if (have_kb_thread) {
LOG("join kb_thread..\n");
thread_join(TASK->kb_thread);
thread_detach(TASK->kb_thread);
LOG("join done\n");
TASK->kb_thread = NULL;
LOG("Join kb.thread.");
thread_join(TASK->kb.thread);
thread_detach(TASK->kb.thread);
LOG("...join done.");
TASK->kb.thread = NULL;
}
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
spinlock_lock(&TASK->kernel_box.lock);
ipc_cleanup_call_list(&TASK->kernel_box.dispatched_calls);
ipc_cleanup_call_list(&TASK->kernel_box.calls);
spinlock_unlock(&TASK->kernel_box.lock);
/* Answer all messages in 'calls' and 'dispatched_calls' queues. */
spinlock_lock(&TASK->kb.box.lock);
ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls);
ipc_cleanup_call_list(&TASK->kb.box.calls);
spinlock_unlock(&TASK->kb.box.lock);
}
 
/** Handle hangup message in kbox.
*
* @param call The IPC_M_PHONE_HUNGUP call structure.
* @param last Output, the function stores @c true here if
* this was the last phone, @c false otherwise.
**/
static void kbox_proc_phone_hungup(call_t *call, bool *last)
{
ipl_t ipl;
 
/* Was it our debugger, who hung up? */
if (call->sender == TASK->udebug.debugger) {
/* Terminate debugging session (if any). */
LOG("Terminate debugging session.");
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
udebug_task_cleanup(TASK);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
} else {
LOG("Was not debugger.");
}
 
LOG("Continue with hangup message.");
IPC_SET_RETVAL(call->data, 0);
ipc_answer(&TASK->kb.box, call);
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
spinlock_lock(&TASK->kb.box.lock);
if (list_empty(&TASK->kb.box.connected_phones)) {
/*
* Last phone has been disconnected. Detach this thread so it
* gets freed and signal to the caller.
*/
 
/* Only detach kbox thread unless already terminating. */
mutex_lock(&TASK->kb.cleanup_lock);
if (&TASK->kb.finished == false) {
/* Detach kbox thread so it gets freed from memory. */
thread_detach(TASK->kb.thread);
TASK->kb.thread = NULL;
}
mutex_unlock(&TASK->kb.cleanup_lock);
 
LOG("Phone list is empty.");
*last = true;
} else {
*last = false;
}
 
spinlock_unlock(&TASK->kb.box.lock);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
 
/** Implementing function for the kbox thread.
*
* This function listens for debug requests. It terminates
* when all phones are disconnected from the kbox.
*
* @param arg Ignored.
*/
static void kbox_thread_proc(void *arg)
{
call_t *call;
int method;
bool done;
ipl_t ipl;
 
(void)arg;
LOG("kbox_thread_proc()\n");
LOG("Starting.");
done = false;
 
while (!done) {
call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT,
call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
SYNCH_FLAGS_NONE);
 
if (call != NULL) {
method = IPC_GET_METHOD(call->data);
if (call == NULL)
continue; /* Try again. */
 
if (method == IPC_M_DEBUG_ALL) {
udebug_call_receive(call);
}
switch (IPC_GET_METHOD(call->data)) {
 
if (method == IPC_M_PHONE_HUNGUP) {
LOG("kbox: handle hangup message\n");
case IPC_M_DEBUG_ALL:
/* Handle debug call. */
udebug_call_receive(call);
break;
 
/* Was it our debugger, who hung up? */
if (call->sender == TASK->udebug.debugger) {
/* Terminate debugging session (if any) */
LOG("kbox: terminate debug session\n");
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
udebug_task_cleanup(TASK);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
} else {
LOG("kbox: was not debugger\n");
}
case IPC_M_PHONE_HUNGUP:
/*
* Process the hangup call. If this was the last
* phone, done will be set to true and the
* while loop will terminate.
*/
kbox_proc_phone_hungup(call, &done);
break;
 
LOG("kbox: continue with hangup message\n");
IPC_SET_RETVAL(call->data, 0);
ipc_answer(&TASK->kernel_box, call);
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
spinlock_lock(&TASK->answerbox.lock);
if (list_empty(&TASK->answerbox.connected_phones)) {
/* Last phone has been disconnected */
TASK->kb_thread = NULL;
done = true;
LOG("phone list is empty\n");
}
spinlock_unlock(&TASK->answerbox.lock);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
default:
/* Ignore */
break;
}
}
 
LOG("kbox: finished\n");
LOG("Exiting.");
}
 
 
145,10 → 206,10
/**
* Connect phone to a task kernel-box specified by id.
*
* Note that this is not completely atomic. For optimisation reasons,
* The task might start cleaning up kbox after the phone has been connected
* and before a kbox thread has been created. This must be taken into account
* in the cleanup code.
* Note that this is not completely atomic. For optimisation reasons, the task
* might start cleaning up kbox after the phone has been connected and before
* a kbox thread has been created. This must be taken into account in the
* cleanup code.
*
* @return Phone id on success, or negative error code.
*/
174,44 → 235,45
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
 
mutex_lock(&ta->kb_cleanup_lock);
mutex_lock(&ta->kb.cleanup_lock);
 
if (atomic_predec(&ta->refcount) == 0) {
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
task_destroy(ta);
return ENOENT;
}
 
if (ta->kb_finished != false) {
mutex_unlock(&ta->kb_cleanup_lock);
if (ta->kb.finished != false) {
mutex_unlock(&ta->kb.cleanup_lock);
return EINVAL;
}
 
newphid = phone_alloc();
newphid = phone_alloc(TASK);
if (newphid < 0) {
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
return ELIMIT;
}
 
/* Connect the newly allocated phone to the kbox */
ipc_phone_connect(&TASK->phones[newphid], &ta->kernel_box);
ipc_phone_connect(&TASK->phones[newphid], &ta->kb.box);
 
if (ta->kb_thread != NULL) {
mutex_unlock(&ta->kb_cleanup_lock);
if (ta->kb.thread != NULL) {
mutex_unlock(&ta->kb.cleanup_lock);
return newphid;
}
 
/* Create a kbox thread */
kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0, "kbox", false);
kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0,
"kbox", false);
if (!kb_thread) {
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
return ENOMEM;
}
 
ta->kb_thread = kb_thread;
ta->kb.thread = kb_thread;
thread_ready(kb_thread);
 
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
 
return newphid;
}
/branches/arm/kernel/generic/src/ipc/ipc.c
44,6 → 44,7
#include <synch/synch.h>
#include <ipc/ipc.h>
#include <ipc/kbox.h>
#include <ipc/event.h>
#include <errno.h>
#include <mm/slab.h>
#include <arch.h>
50,7 → 51,6
#include <proc/task.h>
#include <memstr.h>
#include <debug.h>
 
#include <print.h>
#include <console/console.h>
#include <proc/thread.h>
328,12 → 328,10
list_remove(&phone->link);
spinlock_unlock(&box->lock);
 
if (phone->state != IPC_PHONE_SLAMMED) {
call = ipc_call_alloc(0);
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
}
call = ipc_call_alloc(0);
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
}
 
phone->state = IPC_PHONE_HUNGUP;
526,6 → 524,9
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Unsubscribe from any event notifications. */
event_cleanup_answerbox(&TASK->answerbox);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/branches/arm/kernel/generic/src/ipc/irq.c
44,8 → 44,28
* - ARG1: payload modified by a 'top-half' handler
* - ARG2: payload modified by a 'top-half' handler
* - ARG3: payload modified by a 'top-half' handler
* - ARG4: payload modified by a 'top-half' handler
* - ARG5: payload modified by a 'top-half' handler
* - in_phone_hash: interrupt counter (may be needed to assure correct order
* in multithreaded drivers)
*
* Note on synchronization for ipc_irq_register(), ipc_irq_unregister(),
* ipc_irq_cleanup() and IRQ handlers:
*
* By always taking all of the uspace IRQ hash table lock, IRQ structure lock
* and answerbox lock, we can rule out race conditions between the
* registration functions and also the cleanup function. Thus the observer can
* either see the IRQ structure present in both the hash table and the
* answerbox list or absent in both. Views in which the IRQ structure would be
* linked in the hash table but not in the answerbox list, or vice versa, are
* not possible.
*
* By always taking the hash table lock and the IRQ structure lock, we can
* rule out a scenario in which we would free up an IRQ structure, which is
* still referenced by, for example, an IRQ handler. The locking scheme forces
* us to lock the IRQ structure only after any progressing IRQs on that
* structure are finished. Because we hold the hash table lock, we prevent new
* IRQs from taking new references to the IRQ structure.
*/
 
#include <arch.h>
58,78 → 78,8
#include <console/console.h>
#include <print.h>
 
/** Execute code associated with IRQ notification.
/** Free the top-half pseudocode.
*
* @param call Notification call.
* @param code Top-half pseudocode.
*/
static void code_execute(call_t *call, irq_code_t *code)
{
unsigned int i;
unative_t dstval = 0;
if (!code)
return;
for (i = 0; i < code->cmdcount; i++) {
switch (code->cmds[i].cmd) {
case CMD_MEM_READ_1:
dstval = *((uint8_t *) code->cmds[i].addr);
break;
case CMD_MEM_READ_2:
dstval = *((uint16_t *) code->cmds[i].addr);
break;
case CMD_MEM_READ_4:
dstval = *((uint32_t *) code->cmds[i].addr);
break;
case CMD_MEM_READ_8:
dstval = *((uint64_t *) code->cmds[i].addr);
break;
case CMD_MEM_WRITE_1:
*((uint8_t *) code->cmds[i].addr) = code->cmds[i].value;
break;
case CMD_MEM_WRITE_2:
*((uint16_t *) code->cmds[i].addr) =
code->cmds[i].value;
break;
case CMD_MEM_WRITE_4:
*((uint32_t *) code->cmds[i].addr) =
code->cmds[i].value;
break;
case CMD_MEM_WRITE_8:
*((uint64_t *) code->cmds[i].addr) =
code->cmds[i].value;
break;
#if defined(ia32) || defined(amd64)
case CMD_PORT_READ_1:
dstval = inb((long) code->cmds[i].addr);
break;
case CMD_PORT_WRITE_1:
outb((long) code->cmds[i].addr, code->cmds[i].value);
break;
#endif
#if defined(ia64) && defined(SKI)
case CMD_IA64_GETCHAR:
dstval = _getc(&ski_uconsole);
break;
#endif
#if defined(ppc32)
case CMD_PPC32_GETCHAR:
dstval = cuda_get_scancode();
break;
#endif
default:
break;
}
if (code->cmds[i].dstarg && code->cmds[i].dstarg <
IPC_CALL_LEN) {
call->data.args[code->cmds[i].dstarg] = dstval;
}
}
}
 
/** Free top-half pseudocode.
*
* @param code Pointer to the top-half pseudocode.
*/
static void code_free(irq_code_t *code)
140,7 → 90,7
}
}
 
/** Copy top-half pseudocode from userspace into the kernel.
/** Copy the top-half pseudocode from userspace into the kernel.
*
* @param ucode Userspace address of the top-half pseudocode.
*
176,47 → 126,16
return code;
}
 
/** Unregister task from IRQ notification.
*
* @param box Answerbox associated with the notification.
* @param inr IRQ number.
* @param devno Device number.
*/
void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
{
ipl_t ipl;
irq_t *irq;
 
ipl = interrupts_disable();
irq = irq_find_and_lock(inr, devno);
if (irq) {
if (irq->notif_cfg.answerbox == box) {
code_free(irq->notif_cfg.code);
irq->notif_cfg.notify = false;
irq->notif_cfg.answerbox = NULL;
irq->notif_cfg.code = NULL;
irq->notif_cfg.method = 0;
irq->notif_cfg.counter = 0;
 
spinlock_lock(&box->irq_lock);
list_remove(&irq->notif_cfg.link);
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq->lock);
}
}
interrupts_restore(ipl);
}
 
/** Register an answerbox as a receiving end for IRQ notifications.
*
* @param box Receiving answerbox.
* @param inr IRQ number.
* @param devno Device number.
* @param method Method to be associated with the notification.
* @param ucode Uspace pointer to top-half pseudocode.
* @param box Receiving answerbox.
* @param inr IRQ number.
* @param devno Device number.
* @param method Method to be associated with the notification.
* @param ucode Uspace pointer to top-half pseudocode.
*
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success.
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success.
*
*/
int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno,
unative_t method, irq_code_t *ucode)
224,7 → 143,12
ipl_t ipl;
irq_code_t *code;
irq_t *irq;
 
link_t *hlp;
unative_t key[] = {
(unative_t) inr,
(unative_t) devno
};
if (ucode) {
code = code_from_uspace(ucode);
if (!code)
232,36 → 156,177
} else {
code = NULL;
}
 
/*
* Allocate and populate the IRQ structure.
*/
irq = malloc(sizeof(irq_t), 0);
irq_initialize(irq);
irq->devno = devno;
irq->inr = inr;
irq->claim = ipc_irq_top_half_claim;
irq->handler = ipc_irq_top_half_handler;
irq->notif_cfg.notify = true;
irq->notif_cfg.answerbox = box;
irq->notif_cfg.method = method;
irq->notif_cfg.code = code;
irq->notif_cfg.counter = 0;
/*
* Enlist the IRQ structure in the uspace IRQ hash table and the
* answerbox's list.
*/
ipl = interrupts_disable();
irq = irq_find_and_lock(inr, devno);
if (!irq) {
interrupts_restore(ipl);
spinlock_lock(&irq_uspace_hash_table_lock);
hlp = hash_table_find(&irq_uspace_hash_table, key);
if (hlp) {
irq_t *hirq __attribute__((unused))
= hash_table_get_instance(hlp, irq_t, link);
/* hirq is locked */
spinlock_unlock(&hirq->lock);
code_free(code);
return ENOENT;
}
if (irq->notif_cfg.answerbox) {
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
free(irq);
interrupts_restore(ipl);
code_free(code);
return EEXISTS;
}
irq->notif_cfg.notify = true;
irq->notif_cfg.answerbox = box;
irq->notif_cfg.method = method;
irq->notif_cfg.code = code;
irq->notif_cfg.counter = 0;
 
spinlock_lock(&irq->lock); /* Not really necessary, but paranoid */
spinlock_lock(&box->irq_lock);
hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
list_append(&irq->notif_cfg.link, &box->irq_head);
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
return EOK;
}
 
/** Unregister task from IRQ notification.
*
* @param box Answerbox associated with the notification.
* @param inr IRQ number.
* @param devno Device number.
*/
int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
{
ipl_t ipl;
unative_t key[] = {
(unative_t) inr,
(unative_t) devno
};
link_t *lnk;
irq_t *irq;
 
ipl = interrupts_disable();
spinlock_lock(&irq_uspace_hash_table_lock);
lnk = hash_table_find(&irq_uspace_hash_table, key);
if (!lnk) {
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
return ENOENT;
}
irq = hash_table_get_instance(lnk, irq_t, link);
/* irq is locked */
spinlock_lock(&box->irq_lock);
ASSERT(irq->notif_cfg.answerbox == box);
/* Free up the pseudo code and associated structures. */
code_free(irq->notif_cfg.code);
 
/* Remove the IRQ from the answerbox's list. */
list_remove(&irq->notif_cfg.link);
 
/*
* We need to drop the IRQ lock now because hash_table_remove() will try
* to reacquire it. That basically violates the natural locking order,
* but a deadlock in hash_table_remove() is prevented by the fact that
* we already held the IRQ lock and didn't drop the hash table lock in
* the meantime.
*/
spinlock_unlock(&irq->lock);
 
/* Remove the IRQ from the uspace IRQ hash table. */
hash_table_remove(&irq_uspace_hash_table, key, 2);
spinlock_unlock(&irq_uspace_hash_table_lock);
spinlock_unlock(&box->irq_lock);
/* Free up the IRQ structure. */
free(irq);
interrupts_restore(ipl);
return EOK;
}
 
return 0;
 
/** Disconnect all IRQ notifications from an answerbox.
*
* This function is effective because the answerbox contains
* list of all irq_t structures that are registered to
* send notifications to it.
*
* @param box Answerbox for which we want to carry out the cleanup.
*/
void ipc_irq_cleanup(answerbox_t *box)
{
ipl_t ipl;
loop:
ipl = interrupts_disable();
spinlock_lock(&irq_uspace_hash_table_lock);
spinlock_lock(&box->irq_lock);
while (box->irq_head.next != &box->irq_head) {
link_t *cur = box->irq_head.next;
irq_t *irq;
DEADLOCK_PROBE_INIT(p_irqlock);
unative_t key[2];
irq = list_get_instance(cur, irq_t, notif_cfg.link);
if (!spinlock_trylock(&irq->lock)) {
/*
* Avoid deadlock by trying again.
*/
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
goto loop;
}
key[0] = irq->inr;
key[1] = irq->devno;
ASSERT(irq->notif_cfg.answerbox == box);
/* Unlist from the answerbox. */
list_remove(&irq->notif_cfg.link);
/* Free up the pseudo code and associated structures. */
code_free(irq->notif_cfg.code);
/*
* We need to drop the IRQ lock now because hash_table_remove()
* will try to reacquire it. That basically violates the natural
* locking order, but a deadlock in hash_table_remove() is
* prevented by the fact that we already held the IRQ lock and
* didn't drop the hash table lock in the meantime.
*/
spinlock_unlock(&irq->lock);
/* Remove from the hash table. */
hash_table_remove(&irq_uspace_hash_table, key, 2);
free(irq);
}
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
}
 
/** Add a call to the proper answerbox queue.
280,125 → 345,158
waitq_wakeup(&irq->notif_cfg.answerbox->wq, WAKEUP_FIRST);
}
 
/** Send notification message.
/** Apply the top-half pseudo code to find out whether to accept the IRQ or not.
*
* @param irq IRQ structure.
* @param a1 Driver-specific payload argument.
* @param a2 Driver-specific payload argument.
* @param a3 Driver-specific payload argument.
* @param a4 Driver-specific payload argument.
* @param a5 Driver-specific payload argument.
*
* @return IRQ_ACCEPT if the interrupt is accepted by the
* pseudocode. IRQ_DECLINE otherwise.
*/
void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5)
irq_ownership_t ipc_irq_top_half_claim(irq_t *irq)
{
call_t *call;
unsigned int i;
unative_t dstval;
irq_code_t *code = irq->notif_cfg.code;
unative_t *scratch = irq->notif_cfg.scratch;
 
spinlock_lock(&irq->lock);
 
if (irq->notif_cfg.answerbox) {
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
spinlock_unlock(&irq->lock);
return;
if (!irq->notif_cfg.notify)
return IRQ_DECLINE;
if (!code)
return IRQ_DECLINE;
for (i = 0; i < code->cmdcount; i++) {
unsigned int srcarg = code->cmds[i].srcarg;
unsigned int dstarg = code->cmds[i].dstarg;
if (srcarg >= IPC_CALL_LEN)
break;
if (dstarg >= IPC_CALL_LEN)
break;
switch (code->cmds[i].cmd) {
case CMD_PIO_READ_8:
dstval = pio_read_8((ioport8_t *) code->cmds[i].addr);
if (dstarg)
scratch[dstarg] = dstval;
break;
case CMD_PIO_READ_16:
dstval = pio_read_16((ioport16_t *) code->cmds[i].addr);
if (dstarg)
scratch[dstarg] = dstval;
break;
case CMD_PIO_READ_32:
dstval = pio_read_32((ioport32_t *) code->cmds[i].addr);
if (dstarg)
scratch[dstarg] = dstval;
break;
case CMD_PIO_WRITE_8:
pio_write_8((ioport8_t *) code->cmds[i].addr,
(uint8_t) code->cmds[i].value);
break;
case CMD_PIO_WRITE_16:
pio_write_16((ioport16_t *) code->cmds[i].addr,
(uint16_t) code->cmds[i].value);
break;
case CMD_PIO_WRITE_32:
pio_write_32((ioport32_t *) code->cmds[i].addr,
(uint32_t) code->cmds[i].value);
break;
case CMD_BTEST:
if (srcarg && dstarg) {
dstval = scratch[srcarg] & code->cmds[i].value;
scratch[dstarg] = dstval;
}
break;
case CMD_PREDICATE:
if (srcarg && !scratch[srcarg]) {
i += code->cmds[i].value;
continue;
}
break;
case CMD_ACCEPT:
return IRQ_ACCEPT;
break;
case CMD_DECLINE:
default:
return IRQ_DECLINE;
}
call->flags |= IPC_CALL_NOTIF;
IPC_SET_METHOD(call->data, irq->notif_cfg.method);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
/* Put a counter to the message */
call->priv = ++irq->notif_cfg.counter;
send_call(irq, call);
}
spinlock_unlock(&irq->lock);
return IRQ_DECLINE;
}
 
/** Notify a task that an IRQ had occurred.
 
/* IRQ top-half handler.
*
* We expect interrupts to be disabled and the irq->lock already held.
*
* @param irq IRQ structure.
*/
void ipc_irq_send_notif(irq_t *irq)
void ipc_irq_top_half_handler(irq_t *irq)
{
call_t *call;
 
ASSERT(irq);
 
if (irq->notif_cfg.answerbox) {
call_t *call;
 
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
if (!call)
return;
}
call->flags |= IPC_CALL_NOTIF;
/* Put a counter to the message */
call->priv = ++irq->notif_cfg.counter;
 
/* Set up args */
IPC_SET_METHOD(call->data, irq->notif_cfg.method);
IPC_SET_ARG1(call->data, irq->notif_cfg.scratch[1]);
IPC_SET_ARG2(call->data, irq->notif_cfg.scratch[2]);
IPC_SET_ARG3(call->data, irq->notif_cfg.scratch[3]);
IPC_SET_ARG4(call->data, irq->notif_cfg.scratch[4]);
IPC_SET_ARG5(call->data, irq->notif_cfg.scratch[5]);
 
/* Execute code to handle irq */
code_execute(call, irq->notif_cfg.code);
send_call(irq, call);
}
}
 
/** Disconnect all IRQ notifications from an answerbox.
/** Send notification message.
*
* This function is effective because the answerbox contains
* list of all irq_t structures that are registered to
* send notifications to it.
*
* @param box Answerbox for which we want to carry out the cleanup.
* @param irq IRQ structure.
* @param a1 Driver-specific payload argument.
* @param a2 Driver-specific payload argument.
* @param a3 Driver-specific payload argument.
* @param a4 Driver-specific payload argument.
* @param a5 Driver-specific payload argument.
*/
void ipc_irq_cleanup(answerbox_t *box)
void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5)
{
ipl_t ipl;
loop:
ipl = interrupts_disable();
spinlock_lock(&box->irq_lock);
while (box->irq_head.next != &box->irq_head) {
link_t *cur = box->irq_head.next;
irq_t *irq;
DEADLOCK_PROBE_INIT(p_irqlock);
irq = list_get_instance(cur, irq_t, notif_cfg.link);
if (!spinlock_trylock(&irq->lock)) {
/*
* Avoid deadlock by trying again.
*/
spinlock_unlock(&box->irq_lock);
interrupts_restore(ipl);
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
goto loop;
call_t *call;
 
spinlock_lock(&irq->lock);
 
if (irq->notif_cfg.answerbox) {
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
spinlock_unlock(&irq->lock);
return;
}
call->flags |= IPC_CALL_NOTIF;
/* Put a counter to the message */
call->priv = ++irq->notif_cfg.counter;
 
IPC_SET_METHOD(call->data, irq->notif_cfg.method);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
ASSERT(irq->notif_cfg.answerbox == box);
list_remove(&irq->notif_cfg.link);
/*
* Don't forget to free any top-half pseudocode.
*/
code_free(irq->notif_cfg.code);
irq->notif_cfg.notify = false;
irq->notif_cfg.answerbox = NULL;
irq->notif_cfg.code = NULL;
irq->notif_cfg.method = 0;
irq->notif_cfg.counter = 0;
 
spinlock_unlock(&irq->lock);
send_call(irq, call);
}
spinlock_unlock(&box->irq_lock);
interrupts_restore(ipl);
spinlock_unlock(&irq->lock);
}
 
/** @}
/branches/arm/kernel/generic/src/syscall/syscall.c
32,9 → 32,9
 
/**
* @file
* @brief Syscall table and syscall wrappers.
* @brief Syscall table and syscall wrappers.
*/
 
#include <syscall/syscall.h>
#include <proc/thread.h>
#include <proc/task.h>
41,61 → 41,19
#include <proc/program.h>
#include <mm/as.h>
#include <print.h>
#include <putchar.h>
#include <errno.h>
#include <arch.h>
#include <debug.h>
#include <ddi/device.h>
#include <ipc/sysipc.h>
#include <synch/futex.h>
#include <synch/smc.h>
#include <ddi/ddi.h>
#include <ipc/event.h>
#include <security/cap.h>
#include <syscall/copy.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <udebug/udebug.h>
 
/** Print using kernel facility
*
* Print to kernel log.
*
*/
static unative_t sys_klog(int fd, const void * buf, size_t count)
{
size_t i;
char *data;
int rc;
 
if (count > PAGE_SIZE)
return ELIMIT;
if (count > 0) {
data = (char *) malloc(count, 0);
if (!data)
return ENOMEM;
rc = copy_from_uspace(data, buf, count);
if (rc) {
free(data);
return rc;
}
for (i = 0; i < count; i++)
putchar(data[i]);
free(data);
} else
klog_update();
return count;
}
 
/** Tell kernel to get keyboard/console access again */
static unative_t sys_debug_enable_console(void)
{
arch_grab_console();
return 0;
}
 
/** Dispatch system call */
unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5, unative_t a6, unative_t id)
103,13 → 61,20
unative_t rc;
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
#endif
bool debug;
 
if (id < SYSCALL_END) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
/*
* Early check for undebugged tasks. We do not lock anything as this
* test need not be precise in either way.
*/
debug = THREAD->udebug.active;
if (debug) {
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
}
#endif
if (id < SYSCALL_END) {
rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
} else {
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
116,13 → 81,22
task_kill(TASK->taskid);
thread_exit();
}
if (THREAD->interrupted)
thread_exit();
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
udebug_stoppable_end();
if (debug) {
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
/*
* Stopping point needed for tasks that only invoke
* non-blocking system calls. Not needed if the task
* is not being debugged (it cannot block here).
*/
udebug_stoppable_begin();
udebug_stoppable_end();
}
#endif
return rc;
138,6 → 112,7
(syshandler_t) sys_thread_get_id,
(syshandler_t) sys_task_get_id,
(syshandler_t) sys_task_set_name,
(syshandler_t) sys_program_spawn_loader,
/* Synchronization related syscalls. */
159,10 → 134,14
(syshandler_t) sys_ipc_answer_fast,
(syshandler_t) sys_ipc_answer_slow,
(syshandler_t) sys_ipc_forward_fast,
(syshandler_t) sys_ipc_forward_slow,
(syshandler_t) sys_ipc_wait_for_call,
(syshandler_t) sys_ipc_hangup,
(syshandler_t) sys_ipc_register_irq,
(syshandler_t) sys_ipc_unregister_irq,
 
/* Event notification syscalls. */
(syshandler_t) sys_event_subscribe,
/* Capabilities related syscalls. */
(syshandler_t) sys_cap_grant,
169,6 → 148,7
(syshandler_t) sys_cap_revoke,
/* DDI related syscalls. */
(syshandler_t) sys_device_assign_devno,
(syshandler_t) sys_physmem_map,
(syshandler_t) sys_iospace_enable,
(syshandler_t) sys_preempt_control,
179,7 → 159,8
/* Debug calls */
(syshandler_t) sys_debug_enable_console,
 
(syshandler_t) sys_debug_disable_console,
(syshandler_t) sys_ipc_connect_kbox
};
 
/branches/arm/kernel/generic/src/udebug/udebug.c
35,18 → 35,6
* @brief Udebug hooks and data structure management.
*
* Udebug is an interface that makes userspace debuggers possible.
*
* Functions in this file are executed directly in each thread, which
* may or may not be the subject of debugging. The udebug_stoppable_begin/end()
* functions are also executed in the clock interrupt handler. To avoid
* deadlock, functions in this file are protected from the interrupt
* by locking the recursive lock THREAD->udebug.int_lock (just an atomic
* variable). This prevents udebug_stoppable_begin/end() from being
* executed in the interrupt handler (they are skipped).
*
* Functions in udebug_ops.c and udebug_ipc.c execute in different threads,
* so they needn't be protected from the (preemptible) interrupt-initiated
* code.
*/
#include <synch/waitq.h>
53,18 → 41,10
#include <debug.h>
#include <udebug/udebug.h>
#include <errno.h>
#include <print.h>
#include <arch.h>
 
static inline void udebug_int_lock(void)
{
atomic_inc(&THREAD->udebug.int_lock);
}
 
static inline void udebug_int_unlock(void)
{
atomic_dec(&THREAD->udebug.int_lock);
}
 
/** Initialize udebug part of task structure.
*
* Called as part of task structure initialization.
89,15 → 69,11
mutex_initialize(&ut->lock, MUTEX_PASSIVE);
waitq_initialize(&ut->go_wq);
 
/*
* At the beginning the thread is stoppable, so int_lock be set, too.
*/
atomic_set(&ut->int_lock, 1);
 
ut->go_call = NULL;
ut->stop = true;
ut->uspace_state = NULL;
ut->go = false;
ut->stoppable = true;
ut->debug_active = false;
ut->active = false;
ut->cur_event = 0; /* none */
}
 
122,27 → 98,6
waitq_sleep_finish(wq, rc, ipl);
}
 
/** Do a preliminary check that a debugging session is in progress.
*
* This only requires the THREAD->udebug.lock mutex (and not TASK->udebug.lock
* mutex). For an undebugged task, this will never block (while there could be
* collisions by different threads on the TASK mutex), thus improving SMP
* perormance for undebugged tasks.
*
* @return True if the thread was in a debugging session when the function
* checked, false otherwise.
*/
static bool udebug_thread_precheck(void)
{
bool res;
 
mutex_lock(&THREAD->udebug.lock);
res = THREAD->udebug.debug_active;
mutex_unlock(&THREAD->udebug.lock);
 
return res;
}
 
/** Start of stoppable section.
*
* A stoppable section is a section of code where if the thread can be stoped. In other words,
161,14 → 116,6
ASSERT(THREAD);
ASSERT(TASK);
 
udebug_int_lock();
 
/* Early check for undebugged tasks */
if (!udebug_thread_precheck()) {
udebug_int_unlock();
return;
}
 
mutex_lock(&TASK->udebug.lock);
 
nsc = --TASK->udebug.not_stoppable_count;
198,7 → 145,8
* Active debugging session
*/
 
if (THREAD->udebug.debug_active && THREAD->udebug.stop) {
if (THREAD->udebug.active == true &&
THREAD->udebug.go == false) {
/*
* Thread was requested to stop - answer go call
*/
228,18 → 176,11
*/
void udebug_stoppable_end(void)
{
/* Early check for undebugged tasks */
if (!udebug_thread_precheck()) {
udebug_int_unlock();
return;
}
 
restart:
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
if (THREAD->udebug.debug_active &&
THREAD->udebug.stop == true) {
if (THREAD->udebug.active && THREAD->udebug.go == false) {
TASK->udebug.begin_call = NULL;
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
247,7 → 188,7
udebug_wait_for_go(&THREAD->udebug.go_wq);
 
goto restart;
/* must try again - have to lose stoppability atomically */
/* Must try again - have to lose stoppability atomically. */
} else {
++TASK->udebug.not_stoppable_count;
ASSERT(THREAD->udebug.stoppable == true);
256,44 → 197,17
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
}
 
udebug_int_unlock();
}
 
/** Upon being scheduled to run, check if the current thread should stop.
*
* This function is called from clock(). Preemption is enabled.
* interrupts are disabled, but since this is called after
* being scheduled-in, we can enable them, if we're careful enough
* not to allow arbitrary recursion or deadlock with the thread context.
* This function is called from clock().
*/
void udebug_before_thread_runs(void)
{
ipl_t ipl;
 
return;
ASSERT(!PREEMPTION_DISABLED);
 
/*
* Prevent agains re-entering, such as when preempted inside this
* function.
*/
if (atomic_get(&THREAD->udebug.int_lock) != 0)
return;
 
udebug_int_lock();
 
ipl = interrupts_enable();
 
/* Now we're free to do whatever we need (lock mutexes, sleep, etc.) */
 
/* Check if we're supposed to stop */
udebug_stoppable_begin();
udebug_stoppable_end();
 
interrupts_restore(ipl);
 
udebug_int_unlock();
}
 
/** Syscall event hook.
310,20 → 224,11
 
etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B;
 
udebug_int_lock();
 
/* Early check for undebugged tasks */
if (!udebug_thread_precheck()) {
udebug_int_unlock();
return;
}
 
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
/* Must only generate events when in debugging session and have go */
if (THREAD->udebug.debug_active != true ||
THREAD->udebug.stop == true ||
/* Must only generate events when in debugging session and is go. */
if (THREAD->udebug.active != true || THREAD->udebug.go == false ||
(TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
330,7 → 235,7
return;
}
 
//printf("udebug_syscall_event\n");
/* Fill in the GO response. */
call = THREAD->udebug.go_call;
THREAD->udebug.go_call = NULL;
 
338,7 → 243,6
IPC_SET_ARG1(call->data, etype);
IPC_SET_ARG2(call->data, id);
IPC_SET_ARG3(call->data, rc);
//printf("udebug_syscall_event/ipc_answer\n");
 
THREAD->udebug.syscall_args[0] = a1;
THREAD->udebug.syscall_args[1] = a2;
348,11 → 252,11
THREAD->udebug.syscall_args[5] = a6;
 
/*
* Make sure udebug.stop is true when going to sleep
* Make sure udebug.go is false when going to sleep
* in case we get woken up by DEBUG_END. (At which
* point it must be back to the initial true value).
*/
THREAD->udebug.stop = true;
THREAD->udebug.go = false;
THREAD->udebug.cur_event = etype;
 
ipc_answer(&TASK->answerbox, call);
361,42 → 265,46
mutex_unlock(&TASK->udebug.lock);
 
udebug_wait_for_go(&THREAD->udebug.go_wq);
 
udebug_int_unlock();
}
 
/** Thread-creation event hook.
/** Thread-creation event hook combined with attaching the thread.
*
* Must be called when a new userspace thread is created in the debugged
* task. Generates a THREAD_B event.
* task. Generates a THREAD_B event. Also attaches the thread @a t
* to the task @a ta.
*
* This is necessary to avoid a race condition where the BEGIN and THREAD_READ
* requests would be handled inbetween attaching the thread and checking it
* for being in a debugging session to send the THREAD_B event. We could then
* either miss threads or get some threads both in the thread list
* and get a THREAD_B event for them.
*
* @param t Structure of the thread being created. Not locked, as the
* thread is not executing yet.
* @param ta Task to which the thread should be attached.
*/
void udebug_thread_b_event(struct thread *t)
void udebug_thread_b_event_attach(struct thread *t, struct task *ta)
{
call_t *call;
 
udebug_int_lock();
 
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
LOG("udebug_thread_b_event\n");
LOG("- check state\n");
thread_attach(t, ta);
 
LOG("Check state");
 
/* Must only generate events when in debugging session */
if (THREAD->udebug.debug_active != true) {
LOG("- debug_active: %s, udebug.stop: %s\n",
THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
THREAD->udebug.stop ? "yes(-)" : "no(+)");
if (THREAD->udebug.active != true) {
LOG("udebug.active: %s, udebug.go: %s",
THREAD->udebug.active ? "Yes(+)" : "No",
THREAD->udebug.go ? "Yes(-)" : "No");
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
return;
}
 
LOG("- trigger event\n");
 
LOG("Trigger event");
call = THREAD->udebug.go_call;
THREAD->udebug.go_call = NULL;
IPC_SET_RETVAL(call->data, 0);
404,11 → 312,11
IPC_SET_ARG2(call->data, (unative_t)t);
 
/*
* Make sure udebug.stop is true when going to sleep
* Make sure udebug.go is false when going to sleep
* in case we get woken up by DEBUG_END. (At which
* point it must be back to the initial true value).
*/
THREAD->udebug.stop = true;
THREAD->udebug.go = false;
THREAD->udebug.cur_event = UDEBUG_EVENT_THREAD_B;
 
ipc_answer(&TASK->answerbox, call);
416,10 → 324,8
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
 
LOG("- sleep\n");
LOG("Wait for Go");
udebug_wait_for_go(&THREAD->udebug.go_wq);
 
udebug_int_unlock();
}
 
/** Thread-termination event hook.
431,35 → 337,31
{
call_t *call;
 
udebug_int_lock();
 
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
LOG("udebug_thread_e_event\n");
LOG("- check state\n");
LOG("Check state");
 
/* Must only generate events when in debugging session */
if (THREAD->udebug.debug_active != true) {
/* printf("- debug_active: %s, udebug.stop: %s\n",
THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
THREAD->udebug.stop ? "yes(-)" : "no(+)");*/
/* Must only generate events when in debugging session. */
if (THREAD->udebug.active != true) {
LOG("udebug.active: %s, udebug.go: %s",
THREAD->udebug.active ? "Yes" : "No",
THREAD->udebug.go ? "Yes" : "No");
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
return;
}
 
LOG("- trigger event\n");
 
LOG("Trigger event");
call = THREAD->udebug.go_call;
THREAD->udebug.go_call = NULL;
IPC_SET_RETVAL(call->data, 0);
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
 
/* Prevent any further debug activity in thread */
THREAD->udebug.debug_active = false;
/* Prevent any further debug activity in thread. */
THREAD->udebug.active = false;
THREAD->udebug.cur_event = 0; /* none */
THREAD->udebug.stop = true; /* set to initial value */
THREAD->udebug.go = false; /* set to initial value */
 
ipc_answer(&TASK->answerbox, call);
 
466,8 → 368,10
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
 
/* Leave int_lock enabled */
/* This event does not sleep - debugging has finished in this thread */
/*
* This event does not sleep - debugging has finished
* in this thread.
*/
}
 
/**
487,17 → 391,13
int flags;
ipl_t ipl;
 
LOG("udebug_task_cleanup()\n");
LOG("task %" PRIu64 "\n", ta->taskid);
 
udebug_int_lock();
 
if (ta->udebug.dt_state != UDEBUG_TS_BEGINNING &&
ta->udebug.dt_state != UDEBUG_TS_ACTIVE) {
LOG("udebug_task_cleanup(): task not being debugged\n");
return EINVAL;
}
 
LOG("Task %" PRIu64, ta->taskid);
 
/* Finish debugging of all userspace threads */
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
512,22 → 412,22
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
 
/* Only process userspace threads */
/* Only process userspace threads. */
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Prevent any further debug activity in thread */
t->udebug.debug_active = false;
/* Prevent any further debug activity in thread. */
t->udebug.active = false;
t->udebug.cur_event = 0; /* none */
 
/* Still has go? */
if (t->udebug.stop == false) {
/* Is the thread still go? */
if (t->udebug.go == true) {
/*
* Yes, so clear go. As debug_active == false,
* Yes, so clear go. As active == false,
* this doesn't affect anything.
*/
t->udebug.stop = true;
t->udebug.go = false;
 
/* Answer GO call */
LOG("answer GO call with EVENT_FINISHED\n");
LOG("Answer GO call with EVENT_FINISHED.");
IPC_SET_RETVAL(t->udebug.go_call->data, 0);
IPC_SET_ARG1(t->udebug.go_call->data,
UDEBUG_EVENT_FINISHED);
553,8 → 453,6
ta->udebug.dt_state = UDEBUG_TS_INACTIVE;
ta->udebug.debugger = NULL;
 
udebug_int_unlock();
 
return 0;
}
 
/branches/arm/kernel/generic/src/udebug/udebug_ops.c
44,6 → 44,7
#include <proc/thread.h>
#include <arch.h>
#include <errno.h>
#include <print.h>
#include <syscall/copy.h>
#include <ipc/ipc.h>
#include <udebug/udebug.h>
57,8 → 58,8
*
* Specifically, verifies that thread t exists, is a userspace thread,
* and belongs to the current task (TASK). Verifies, that the thread
* has (or hasn't) go according to having_go (typically false).
* It also locks t->udebug.lock, making sure that t->udebug.debug_active
* is (or is not) go according to being_go (typically false).
* It also locks t->udebug.lock, making sure that t->udebug.active
* is true - that the thread is in a valid debugging session.
*
* With this verified and the t->udebug.lock mutex held, it is ensured
70,11 → 71,11
* the t->lock spinlock to the t->udebug.lock mutex.
*
* @param t Pointer, need not at all be valid.
* @param having_go Required thread state.
* @param being_go Required thread state.
*
* Returns EOK if all went well, or an error code otherwise.
*/
static int _thread_op_begin(thread_t *t, bool having_go)
static int _thread_op_begin(thread_t *t, bool being_go)
{
task_id_t taskid;
ipl_t ipl;
98,7 → 99,7
spinlock_lock(&t->lock);
spinlock_unlock(&threads_lock);
 
/* Verify that 't' is a userspace thread */
/* Verify that 't' is a userspace thread. */
if ((t->flags & THREAD_FLAG_USPACE) == 0) {
/* It's not, deny its existence */
spinlock_unlock(&t->lock);
107,8 → 108,8
return ENOENT;
}
 
/* Verify debugging state */
if (t->udebug.debug_active != true) {
/* Verify debugging state. */
if (t->udebug.active != true) {
/* Not in debugging session or undesired GO state */
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
117,16 → 118,16
}
 
/*
* Since the thread has debug_active == true, TASK->udebug.lock
* is enough to ensure its existence and that debug_active remains
* Since the thread has active == true, TASK->udebug.lock
* is enough to ensure its existence and that active remains
* true.
*/
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
 
/* Only mutex TASK->udebug.lock left */
/* Only mutex TASK->udebug.lock left. */
/* Now verify that the thread belongs to the current task */
/* Now verify that the thread belongs to the current task. */
if (t->task != TASK) {
/* No such thread belonging this task*/
mutex_unlock(&TASK->udebug.lock);
139,18 → 140,18
*/
mutex_lock(&t->udebug.lock);
 
/* The big task mutex is no longer needed */
/* The big task mutex is no longer needed. */
mutex_unlock(&TASK->udebug.lock);
 
if (!t->udebug.stop != having_go) {
/* Not in debugging session or undesired GO state */
if (t->udebug.go != being_go) {
/* Not in debugging session or undesired GO state. */
mutex_unlock(&t->udebug.lock);
return EINVAL;
}
 
/* Only t->udebug.lock left */
/* Only t->udebug.lock left. */
 
return EOK; /* All went well */
return EOK; /* All went well. */
}
 
/** End debugging operation on a thread. */
180,15 → 181,11
thread_t *t;
link_t *cur;
 
LOG("udebug_begin()\n");
 
LOG("Debugging task %llu", TASK->taskid);
mutex_lock(&TASK->udebug.lock);
LOG("debugging task %llu\n", TASK->taskid);
 
if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) {
mutex_unlock(&TASK->udebug.lock);
LOG("udebug_begin(): busy error\n");
 
return EBUSY;
}
 
204,7 → 201,7
reply = 0; /* no reply */
}
/* Set udebug.debug_active on all of the task's userspace threads */
/* Set udebug.active on all of the task's userspace threads. */
 
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
211,15 → 208,11
 
mutex_lock(&t->udebug.lock);
if ((t->flags & THREAD_FLAG_USPACE) != 0)
t->udebug.debug_active = true;
t->udebug.active = true;
mutex_unlock(&t->udebug.lock);
}
 
mutex_unlock(&TASK->udebug.lock);
 
LOG("udebug_begin() done (%s)\n",
reply ? "reply" : "stoppability wait");
 
return reply;
}
 
232,13 → 225,10
{
int rc;
 
LOG("udebug_end()\n");
LOG("Task %" PRIu64, TASK->taskid);
 
mutex_lock(&TASK->udebug.lock);
LOG("task %" PRIu64 "\n", TASK->taskid);
 
rc = udebug_task_cleanup(TASK);
 
mutex_unlock(&TASK->udebug.lock);
 
return rc;
253,19 → 243,16
*/
int udebug_set_evmask(udebug_evmask_t mask)
{
LOG("udebug_set_mask()\n");
LOG("mask = 0x%x", mask);
 
mutex_lock(&TASK->udebug.lock);
 
if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
mutex_unlock(&TASK->udebug.lock);
LOG("udebug_set_mask(): not active debuging session\n");
 
return EINVAL;
}
 
TASK->udebug.evmask = mask;
 
mutex_unlock(&TASK->udebug.lock);
 
return 0;
273,7 → 260,7
 
/** Give thread GO.
*
* Upon recieving a go message, the thread is given GO. Having GO
* Upon recieving a go message, the thread is given GO. Being GO
* means the thread is allowed to execute userspace code (until
* a debugging event or STOP occurs, at which point the thread loses GO.
*
284,7 → 271,7
{
int rc;
 
/* On success, this will lock t->udebug.lock */
/* On success, this will lock t->udebug.lock. */
rc = _thread_op_begin(t, false);
if (rc != EOK) {
return rc;
291,11 → 278,11
}
 
t->udebug.go_call = call;
t->udebug.stop = false;
t->udebug.go = true;
t->udebug.cur_event = 0; /* none */
 
/*
* Neither t's lock nor threads_lock may be held during wakeup
* Neither t's lock nor threads_lock may be held during wakeup.
*/
waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
 
316,8 → 303,7
{
int rc;
 
LOG("udebug_stop()\n");
mutex_lock(&TASK->udebug.lock);
LOG("udebug_stop()");
 
/*
* On success, this will lock t->udebug.lock. Note that this makes sure
328,36 → 314,34
return rc;
}
 
/* Take GO away from the thread */
t->udebug.stop = true;
/* Take GO away from the thread. */
t->udebug.go = false;
 
if (!t->udebug.stoppable) {
/* Answer will be sent when the thread becomes stoppable */
if (t->udebug.stoppable != true) {
/* Answer will be sent when the thread becomes stoppable. */
_thread_op_end(t);
return 0;
}
 
/*
* Answer GO call
* Answer GO call.
*/
LOG("udebug_stop - answering go call\n");
 
/* Make sure nobody takes this call away from us */
/* Make sure nobody takes this call away from us. */
call = t->udebug.go_call;
t->udebug.go_call = NULL;
 
IPC_SET_RETVAL(call->data, 0);
IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
LOG("udebug_stop/ipc_answer\n");
 
THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
 
_thread_op_end(t);
 
mutex_lock(&TASK->udebug.lock);
ipc_answer(&TASK->answerbox, call);
mutex_unlock(&TASK->udebug.lock);
 
LOG("udebog_stop/done\n");
return 0;
}
 
391,7 → 375,7
int flags;
size_t max_ids;
 
LOG("udebug_thread_read()\n");
LOG("udebug_thread_read()");
 
/* Allocate a buffer to hold thread IDs */
id_buffer = malloc(buf_size, 0);
422,7 → 406,7
flags = t->flags;
spinlock_unlock(&t->lock);
 
/* Not interested in kernel threads */
/* Not interested in kernel threads. */
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Using thread struct pointer as identification hash */
tid = (unative_t) t;
458,16 → 442,16
int rc;
unative_t *arg_buffer;
 
/* Prepare a buffer to hold the arguments */
/* Prepare a buffer to hold the arguments. */
arg_buffer = malloc(6 * sizeof(unative_t), 0);
 
/* On success, this will lock t->udebug.lock */
/* On success, this will lock t->udebug.lock. */
rc = _thread_op_begin(t, false);
if (rc != EOK) {
return rc;
}
 
/* Additionally we need to verify that we are inside a syscall */
/* Additionally we need to verify that we are inside a syscall. */
if (t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_B &&
t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_E) {
_thread_op_end(t);
474,7 → 458,7
return EINVAL;
}
 
/* Copy to a local buffer before releasing the lock */
/* Copy to a local buffer before releasing the lock. */
memcpy(arg_buffer, t->udebug.syscall_args, 6 * sizeof(unative_t));
 
_thread_op_end(t);
/branches/arm/kernel/generic/src/udebug/udebug_ipc.c
73,7 → 73,7
rc = udebug_begin(call);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
83,7 → 83,7
*/
if (rc != 0) {
IPC_SET_RETVAL(call->data, 0);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
}
 
99,7 → 99,7
rc = udebug_end();
 
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process a SET_EVMASK call.
116,7 → 116,7
rc = udebug_set_evmask(mask);
 
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
 
135,7 → 135,7
rc = udebug_go(t, call);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
}
154,7 → 154,7
 
rc = udebug_stop(t, call);
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process a THREAD_READ call.
182,7 → 182,7
rc = udebug_thread_read(&buffer, buf_size, &n);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
209,7 → 209,7
IPC_SET_ARG3(call->data, total_bytes);
call->buffer = buffer;
 
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process an ARGS_READ call.
229,7 → 229,7
rc = udebug_args_read(t, &buffer);
if (rc != EOK) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
247,7 → 247,7
IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
call->buffer = buffer;
 
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process an MEM_READ call.
270,7 → 270,7
rc = udebug_mem_read(uspace_src, size, &buffer);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
282,7 → 282,7
IPC_SET_ARG2(call->data, size);
call->buffer = buffer;
 
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Handle a debug call received on the kernel answerbox.
306,7 → 306,7
*/
if (TASK->udebug.debugger != call->sender) {
IPC_SET_RETVAL(call->data, EINVAL);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
}
/branches/arm/kernel/generic/src/interrupt/interrupt.c
42,7 → 42,6
#include <debug.h>
#include <console/kconsole.h>
#include <console/console.h>
#include <console/chardev.h>
#include <console/cmd.h>
#include <panic.h>
#include <print.h>
68,13 → 67,13
iroutine old;
spinlock_lock(&exctbl_lock);
 
old = exc_table[n].f;
exc_table[n].f = f;
exc_table[n].name = name;
 
spinlock_unlock(&exctbl_lock);
 
spinlock_unlock(&exctbl_lock);
return old;
}
 
86,8 → 85,17
void exc_dispatch(int n, istate_t *istate)
{
ASSERT(n < IVT_ITEMS);
 
#ifdef CONFIG_UDEBUG
if (THREAD) THREAD->udebug.uspace_state = istate;
#endif
exc_table[n].f(n + IVT_FIRST, istate);
 
#ifdef CONFIG_UDEBUG
if (THREAD) THREAD->udebug.uspace_state = NULL;
#endif
 
/* This is a safe place to exit exiting thread */
if (THREAD && THREAD->interrupted && istate_from_uspace(istate))
thread_exit();
100,8 → 108,10
panic("Unhandled exception %d.", n);
}
 
#ifdef CONFIG_KCONSOLE
 
/** kconsole cmd - print all exceptions */
static int exc_print_cmd(cmd_arg_t *argv)
static int cmd_exc_print(cmd_arg_t *argv)
{
#if (IVT_ITEMS > 0)
unsigned int i;
120,9 → 130,7
#endif
for (i = 0; i < IVT_ITEMS; i++) {
symbol = get_symtab_entry((unative_t) exc_table[i].f);
if (!symbol)
symbol = "not found";
symbol = symtab_fmt_name_lookup((unative_t) exc_table[i].f);
 
#ifdef __32_BITS__
printf("%-3u %-20s %10p %s\n", i + IVT_FIRST, exc_table[i].name,
137,7 → 145,7
if (((i + 1) % 20) == 0) {
printf(" -- Press any key to continue -- ");
spinlock_unlock(&exctbl_lock);
getc(stdin);
indev_pop_character(stdin);
spinlock_lock(&exctbl_lock);
printf("\n");
}
149,15 → 157,18
return 1;
}
 
 
static cmd_info_t exc_info = {
.name = "exc",
.description = "Print exception table.",
.func = exc_print_cmd,
.func = cmd_exc_print,
.help = NULL,
.argc = 0,
.argv = NULL
};
 
#endif
 
/** Initialize generic exception handling support */
void exc_init(void)
{
166,9 → 177,11
for (i = 0; i < IVT_ITEMS; i++)
exc_register(i, "undef", (iroutine) exc_undef);
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&exc_info);
if (!cmd_register(&exc_info))
panic("could not register command %s\n", exc_info.name);
printf("Cannot register command %s\n", exc_info.name);
#endif
}
 
/** @}
/branches/arm/kernel/generic/src/cpu/cpu.c
64,7 → 64,7
cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count,
FRAME_ATOMIC);
if (!cpus)
panic("malloc/cpus");
panic("Cannot allocate CPU structures.");
 
/* initialize everything */
memsetb(cpus, sizeof(cpu_t) * config.cpu_count, 0);
86,7 → 86,7
}
#endif /* CONFIG_SMP */
 
CPU = &cpus[config.cpu_active-1];
CPU = &cpus[config.cpu_active - 1];
CPU->active = 1;
CPU->tlb_active = 1;
/branches/arm/kernel/generic/src/sysinfo/sysinfo.c
163,7 → 163,8
i = 0;
}
}
panic("Not reached\n");
 
panic("Not reached.");
return NULL;
}
 
/branches/arm/kernel/genarch/include/kbd/scanc_pc.h
File deleted
/branches/arm/kernel/genarch/include/kbd/z8530.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc_sun.h
File deleted
/branches/arm/kernel/genarch/include/kbd/pl050.h
File deleted
/branches/arm/kernel/genarch/include/kbd/ns16550.h
File deleted
/branches/arm/kernel/genarch/include/kbd/i8042.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc_pl050.h
File deleted
/branches/arm/kernel/genarch/include/kbd/key.h
File deleted
/branches/arm/kernel/genarch/include/drivers/via-cuda/cuda.h
0,0 → 1,123
/*
* Copyright (c) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_CUDA_H_
#define KERN_CUDA_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <synch/spinlock.h>
 
typedef struct {
uint8_t b;
uint8_t pad0[0x1ff];
 
uint8_t a;
uint8_t pad1[0x1ff];
 
uint8_t dirb;
uint8_t pad2[0x1ff];
 
uint8_t dira;
uint8_t pad3[0x1ff];
 
uint8_t t1cl;
uint8_t pad4[0x1ff];
 
uint8_t t1ch;
uint8_t pad5[0x1ff];
 
uint8_t t1ll;
uint8_t pad6[0x1ff];
 
uint8_t t1lh;
uint8_t pad7[0x1ff];
 
uint8_t t2cl;
uint8_t pad8[0x1ff];
 
uint8_t t2ch;
uint8_t pad9[0x1ff];
 
uint8_t sr;
uint8_t pad10[0x1ff];
 
uint8_t acr;
uint8_t pad11[0x1ff];
 
uint8_t pcr;
uint8_t pad12[0x1ff];
 
uint8_t ifr;
uint8_t pad13[0x1ff];
 
uint8_t ier;
uint8_t pad14[0x1ff];
 
uint8_t anh;
uint8_t pad15[0x1ff];
} cuda_t;
 
enum {
CUDA_RCV_BUF_SIZE = 5
};
 
enum cuda_xfer_state {
cx_listen,
cx_receive,
cx_rcv_end,
cx_send_start,
cx_send
};
 
typedef struct {
irq_t irq;
cuda_t *cuda;
indev_t *kbrdin;
uint8_t rcv_buf[CUDA_RCV_BUF_SIZE];
uint8_t snd_buf[CUDA_RCV_BUF_SIZE];
size_t bidx;
size_t snd_bytes;
enum cuda_xfer_state xstate;
SPINLOCK_DECLARE(dev_lock);
} cuda_instance_t;
 
extern cuda_instance_t *cuda_init(cuda_t *, inr_t, cir_t, void *);
extern void cuda_wire(cuda_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/ns16550/ns16550.h
0,0 → 1,76
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Headers for NS 16550 serial controller.
*/
 
#ifndef KERN_NS16550_H_
#define KERN_NS16550_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
 
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */
 
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */
 
#define MCR_OUT2 0x08 /** OUT2. */
 
/** NS16550 registers. */
typedef struct {
ioport8_t rbr; /**< Receiver Buffer Register. */
ioport8_t ier; /**< Interrupt Enable Register. */
union {
ioport8_t iir; /**< Interrupt Ident Register (read). */
ioport8_t fcr; /**< FIFO control register (write). */
} __attribute__ ((packed));
ioport8_t lcr; /**< Line Control register. */
ioport8_t mcr; /**< Modem Control Register. */
ioport8_t lsr; /**< Line Status Register. */
} __attribute__ ((packed)) ns16550_t;
 
/** Structure representing the ns16550 device. */
typedef struct {
irq_t irq;
ns16550_t *ns16550;
indev_t *kbrdin;
} ns16550_instance_t;
 
extern ns16550_instance_t *ns16550_init(ns16550_t *, inr_t, cir_t, void *);
extern void ns16550_wire(ns16550_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/dsrln/dsrlnin.h
0,0 → 1,61
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Dummy serial line input.
*/
 
#ifndef KERN_DSRLNIN_H_
#define KERN_DSRLNIN_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <typedefs.h>
 
typedef struct {
ioport8_t data;
} __attribute__ ((packed)) dsrlnin_t;
 
typedef struct {
irq_t irq;
dsrlnin_t *dsrlnin;
indev_t *srlnin;
} dsrlnin_instance_t;
 
extern dsrlnin_instance_t *dsrlnin_init(dsrlnin_t *, inr_t);
extern void dsrlnin_wire(dsrlnin_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/drivers/dsrln/dsrlnout.h
0,0 → 1,48
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Dummy serial line output.
*/
 
#ifndef KERN_DSRLNOUT_H_
#define KERN_DSRLNOUT_H_
 
#include <arch/types.h>
#include <typedefs.h>
 
extern void dsrlnout_init(ioport8_t *);
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/drivers/i8042/i8042.h
0,0 → 1,62
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_I8042_H_
#define KERN_I8042_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <typedefs.h>
 
typedef struct {
ioport8_t data;
uint8_t pad[3];
ioport8_t status;
} __attribute__ ((packed)) i8042_t;
 
typedef struct {
irq_t irq;
i8042_t *i8042;
indev_t *kbrdin;
} i8042_instance_t;
 
extern i8042_instance_t *i8042_init(i8042_t *, inr_t);
extern void i8042_wire(i8042_instance_t *, indev_t *);
extern void i8042_cpu_reset(i8042_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/z8530/z8530.h
0,0 → 1,128
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Headers for Zilog 8530 serial controller.
*/
 
#ifndef KERN_Z8530_H_
#define KERN_Z8530_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
 
#define WR0 0
#define WR1 1
#define WR2 2
#define WR3 3
#define WR4 4
#define WR5 5
#define WR6 6
#define WR7 7
#define WR8 8
#define WR9 9
#define WR10 10
#define WR11 11
#define WR12 12
#define WR13 13
#define WR14 14
#define WR15 15
 
#define RR0 0
#define RR1 1
#define RR2 2
#define RR3 3
#define RR8 8
#define RR10 10
#define RR12 12
#define RR13 13
#define RR14 14
#define RR15 15
 
/** Reset pending TX interrupt. */
#define WR0_TX_IP_RST (0x5 << 3)
#define WR0_ERR_RST (0x6 << 3)
 
/** Receive Interrupts Disabled. */
#define WR1_RID (0x0 << 3)
/** Receive Interrupt on First Character or Special Condition. */
#define WR1_RIFCSC (0x1 << 3)
/** Interrupt on All Receive Characters or Special Conditions. */
#define WR1_IARCSC (0x2 << 3)
/** Receive Interrupt on Special Condition. */
#define WR1_RISC (0x3 << 3)
/** Parity Is Special Condition. */
#define WR1_PISC (0x1 << 2)
 
/** Rx Enable. */
#define WR3_RX_ENABLE (0x1 << 0)
/** 8-bits per character. */
#define WR3_RX8BITSCH (0x3 << 6)
 
/** Master Interrupt Enable. */
#define WR9_MIE (0x1 << 3)
 
/** Receive Character Available. */
#define RR0_RCA (0x1 << 0)
 
/** z8530's registers. */
typedef struct {
union {
ioport8_t ctl_b;
ioport8_t status_b;
} __attribute__ ((packed));
uint8_t pad1;
ioport8_t data_b;
uint8_t pad2;
union {
ioport8_t ctl_a;
ioport8_t status_a;
} __attribute__ ((packed));
uint8_t pad3;
ioport8_t data_a;
} __attribute__ ((packed)) z8530_t;
 
/** Structure representing the z8530 device. */
typedef struct {
irq_t irq;
z8530_t *z8530;
indev_t *kbrdin;
} z8530_instance_t;
 
extern z8530_instance_t *z8530_init(z8530_t *, inr_t, cir_t, void *);
extern void z8530_wire(z8530_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/ega/ega.h
0,0 → 1,56
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch_drivers
* @{
*/
/** @file
*/
 
#ifndef KERN_EGA_H_
#define KERN_EGA_H_
 
#include <arch/types.h>
#include <typedefs.h>
 
#define EGA_COLS 80
#define EGA_ROWS 25
#define EGA_SCREEN (EGA_COLS * EGA_ROWS)
#define EGA_VRAM_SIZE (2 * EGA_SCREEN)
 
/* EGA device registers. */
#define EGA_INDEX_REG 0
#define EGA_DATA_REG 1
 
extern void ega_redraw(void);
extern void ega_init(ioport8_t *, uintptr_t);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/legacy/ia32/io.h
0,0 → 1,51
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup ia32
* @{
*/
/** @file
* @brief This file contains definitions used by architectures with the
* ia32 legacy I/O space (i.e. ia32, amd64 and ia64).
*/
 
#ifndef KERN_LEGACY_IA32_IO_H
#define KERN_LEGACY_IA32_IO_H
 
#include <arch/types.h>
 
#define I8042_BASE ((ioport8_t *) 0x60)
#define EGA_BASE ((ioport8_t *) 0x3d4)
#define NS16550_BASE ((ioport8_t *) 0x3f8)
 
#define EGA_VIDEORAM 0xb8000
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/scanc_mac.h
0,0 → 1,48
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for Macintosh ADB keyboards.
*/
 
#ifndef KERN_SCANC_MAC_H_
#define KERN_SCANC_MAC_H_
 
#define SC_LSHIFT 0x38
#define SC_RSHIFT 0xfd /* Not used */
#define SC_CAPSLOCK 0xfe /* Not used */
#define SC_SCAN_ESCAPE 0xff /* Not used */
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/kbrd.h
0,0 → 1,60
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
*/
 
#ifndef KERN_KBD_H_
#define KERN_KBD_H_
 
#include <console/chardev.h>
#include <proc/thread.h>
#include <synch/spinlock.h>
 
typedef struct {
thread_t *thread;
indev_t *sink;
indev_t raw;
SPINLOCK_DECLARE(keylock); /**< keylock protects keyflags and lockflags. */
volatile unsigned int keyflags; /**< Tracking of multiple keypresses. */
volatile unsigned int lockflags; /**< Tracking of multiple keys lockings. */
} kbrd_instance_t;
 
extern kbrd_instance_t *kbrd_init(void);
extern indev_t *kbrd_wire(kbrd_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/kbrd/scanc_pc.h
0,0 → 1,48
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for PC keyboards.
*/
 
#ifndef KERN_SCANC_PC_H_
#define KERN_SCANC_PC_H_
 
#define SC_LSHIFT 0x2a
#define SC_RSHIFT 0x36
#define SC_CAPSLOCK 0x3a
#define SC_SCAN_ESCAPE 0xe0
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/scanc_sun.h
0,0 → 1,48
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for Sun keyboards.
*/
 
#ifndef KERN_SCANC_SUN_H_
#define KERN_SCANC_SUN_H_
 
#define SC_LSHIFT 0x63
#define SC_RSHIFT 0x6e
#define SC_CAPSLOCK 0x77
#define SC_SCAN_ESCAPE 0xe0
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/scanc.h
0,0 → 1,49
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
*/
 
#ifndef KERN_SCANC_H_
#define KERN_SCANC_H_
 
#include <typedefs.h>
 
#define SCANCODES 128
 
extern wchar_t sc_primary_map[SCANCODES];
extern wchar_t sc_secondary_map[SCANCODES];
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/srln/srln.h
0,0 → 1,55
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
*/
 
#ifndef KERN_SRLN_H_
#define KERN_SRLN_H_
 
#include <console/chardev.h>
#include <proc/thread.h>
 
typedef struct {
thread_t *thread;
indev_t *sink;
indev_t raw;
} srln_instance_t;
 
extern srln_instance_t *srln_init(void);
extern indev_t *srln_wire(srln_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/fb/font-8x16.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
35,11 → 35,15
#ifndef KERN_FONT_8X16_H_
#define KERN_FONT_8X16_H_
 
#define FONT_GLIPHS 256
#define FONT_SCANLINES 16
#define FONT_GLYPHS 2899
#define FONT_WIDTH 8
#define FONT_SCANLINES 16
 
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES];
#include <typedefs.h>
 
extern uint16_t fb_font_glyph(const wchar_t ch);
extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
#endif
 
/** @}
/branches/arm/kernel/genarch/include/fb/visuals.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
35,16 → 35,16
#ifndef KERN_VISUALS_H_
#define KERN_VISUALS_H_
 
#define VISUAL_INDIRECT_8 0
#define VISUAL_INDIRECT_8 0
 
#define VISUAL_RGB_5_5_5 1
#define VISUAL_RGB_5_6_5 2
#define VISUAL_RGB_8_8_8 3
#define VISUAL_RGB_8_8_8_0 4
#define VISUAL_RGB_0_8_8_8 5
#define VISUAL_RGB_5_5_5 1
#define VISUAL_RGB_5_6_5 2
#define VISUAL_RGB_8_8_8 3
#define VISUAL_RGB_8_8_8_0 4
#define VISUAL_RGB_0_8_8_8 5
 
#define VISUAL_BGR_0_8_8_8 6
#define VISUAL_BGR_8_8_8_0 7
#define VISUAL_BGR_0_8_8_8 6
#define VISUAL_BGR_8_8_8 7
 
#endif
 
/branches/arm/kernel/genarch/include/fb/fb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
38,9 → 38,37
#include <arch/types.h>
#include <synch/spinlock.h>
 
/**
* Properties of the framebuffer device.
*/
typedef struct fb_properties {
/** Physical address of the framebuffer device. */
uintptr_t addr;
 
/**
* Address where the first (top left) pixel is mapped,
* relative to "addr".
*/
unsigned int offset;
 
/** Screen width in pixels. */
unsigned int x;
 
/** Screen height in pixels. */
unsigned int y;
 
/** Bytes per one scanline. */
unsigned int scan;
 
/** Color model. */
unsigned int visual;
} fb_properties_t;
 
SPINLOCK_EXTERN(fb_lock);
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan, unsigned int visual);
 
void fb_redraw(void);
void fb_init(fb_properties_t *props);
 
#endif
 
/** @}
/branches/arm/kernel/genarch/include/fb/logo-196x66.h
0,0 → 1,49
/*
* Copyright (c) 2008 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_LOGO_196X66_H_
#define KERN_LOGO_196X66_H_
 
#define LOGO_WIDTH 196
#define LOGO_HEIGHT 66
#define LOGO_COLOR 0xffffff
 
#include <arch/types.h>
 
extern uint32_t fb_logo[LOGO_WIDTH * LOGO_HEIGHT];
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/multiboot/multiboot.h
0,0 → 1,100
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_MULTIBOOT_H_
#define KERN_MULTIBOOT_H_
 
#include <arch/types.h>
#include <arch/boot/memmap.h>
 
/** Multiboot 32-bit address. */
typedef uint32_t mbaddr_t;
 
/** Multiboot mod structure */
typedef struct {
mbaddr_t start;
mbaddr_t end;
mbaddr_t string;
uint32_t reserved;
} __attribute__ ((packed)) multiboot_mod_t;
 
/** Multiboot mmap structure */
typedef struct {
uint32_t size;
e820memmap_t mm_info;
} __attribute__ ((packed)) multiboot_mmap_t;
 
/** Multiboot information structure */
typedef struct {
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mods_count;
mbaddr_t mods_addr;
uint32_t syms[4];
uint32_t mmap_length;
mbaddr_t mmap_addr;
/* ... */
} __attribute__ ((packed)) multiboot_info_t;
 
enum multiboot_info_flags {
MBINFO_FLAGS_MEM = 0x01,
MBINFO_FLAGS_BOOT = 0x02,
MBINFO_FLAGS_CMDLINE = 0x04,
MBINFO_FLAGS_MODS = 0x08,
MBINFO_FLAGS_SYMS1 = 0x10,
MBINFO_FLAGS_SYMS2 = 0x20,
MBINFO_FLAGS_MMAP = 0x40
/* ... */
};
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
 
/** Convert 32-bit multiboot address to a pointer. */
#define MULTIBOOT_PTR(mba) ((void *)(uintptr_t) (mba))
 
extern void multiboot_info_parse(uint32_t, const multiboot_info_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/ofw/ofw_tree.h
30,6 → 30,7
#define KERN_OFW_TREE_H_
 
#include <arch/types.h>
#include <ddi/irq.h>
#include <typedefs.h>
 
#define OFW_TREE_PROPERTY_MAX_NAMELEN 32
43,11 → 44,11
ofw_tree_node_t *peer;
ofw_tree_node_t *child;
 
uint32_t node_handle; /**< Old OpenFirmware node handle. */
uint32_t node_handle; /**< Old OpenFirmware node handle. */
 
char *da_name; /**< Disambigued name. */
char *da_name; /**< Disambigued name. */
 
unsigned properties; /**< Number of properties. */
unsigned properties; /**< Number of properties. */
ofw_tree_property_t *property;
/**
105,7 → 106,7
uint32_t child_space;
uint32_t child_base;
uint32_t parent_space;
uint64_t parent_base; /* group phys.mid and phys.lo together */
uint64_t parent_base; /* group phys.mid and phys.lo together */
uint32_t size;
} __attribute__ ((packed));
typedef struct ofw_ebus_range ofw_ebus_range_t;
127,8 → 128,8
typedef struct ofw_ebus_intr_mask ofw_ebus_intr_mask_t;
 
struct ofw_pci_reg {
uint32_t space; /* needs to be masked to obtain pure space id */
uint64_t addr; /* group phys.mid and phys.lo together */
uint32_t space; /* needs to be masked to obtain pure space id */
uint64_t addr; /* group phys.mid and phys.lo together */
uint64_t size;
} __attribute__ ((packed));
typedef struct ofw_pci_reg ofw_pci_reg_t;
135,7 → 136,7
 
struct ofw_pci_range {
uint32_t space;
uint64_t child_base; /* group phys.mid and phys.lo together */
uint64_t child_base; /* group phys.mid and phys.lo together */
uint64_t parent_base;
uint64_t size;
} __attribute__ ((packed));
160,27 → 161,43
} __attribute__ ((packed));
typedef struct ofw_upa_reg ofw_upa_reg_t;
 
extern void ofw_tree_init(ofw_tree_node_t *root);
extern void ofw_tree_init(ofw_tree_node_t *);
extern void ofw_tree_print(void);
extern const char *ofw_tree_node_name(const ofw_tree_node_t *node);
extern ofw_tree_node_t *ofw_tree_lookup(const char *path);
extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name);
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name);
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type);
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type);
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle);
extern const char *ofw_tree_node_name(const ofw_tree_node_t *);
extern ofw_tree_node_t *ofw_tree_lookup(const char *);
extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *,
const char *);
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *);
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *,
const char *);
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *,
const char *);
extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
const char *name);
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *,
uint32_t);
 
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa);
extern bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa);
extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa);
extern bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa);
extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *node, ofw_sbus_reg_t *reg, uintptr_t *pa);
extern bool ofw_upa_apply_ranges(ofw_tree_node_t *node, ofw_upa_reg_t *reg, uintptr_t *pa);
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
uintptr_t *);
extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
uintptr_t *);
extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,
uintptr_t *);
extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,
uintptr_t *);
extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,
uintptr_t *);
extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,
uintptr_t *);
 
extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out);
extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,
ofw_pci_reg_t *);
 
extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr);
extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr);
extern bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr);
extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
uint32_t, int *, cir_t *, void **);
extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,
uint32_t, int *, cir_t *, void **);
extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,
int, int *, cir_t *, void **);
 
#endif
/branches/arm/kernel/genarch/src/kbd/ns16550.c
File deleted
/branches/arm/kernel/genarch/src/kbd/i8042.c
File deleted
/branches/arm/kernel/genarch/src/kbd/scanc_pl050.c
File deleted
/branches/arm/kernel/genarch/src/kbd/key.c
File deleted
/branches/arm/kernel/genarch/src/kbd/z8530.c
File deleted
/branches/arm/kernel/genarch/src/kbd/scanc_pc.c
File deleted
/branches/arm/kernel/genarch/src/kbd/scanc_sun.c
File deleted
/branches/arm/kernel/genarch/src/drivers/via-cuda/cuda.c
0,0 → 1,360
/*
* Copyright (c) 2006 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#include <genarch/drivers/via-cuda/cuda.h>
#include <console/chardev.h>
#include <ddi/irq.h>
#include <arch/asm.h>
#include <mm/slab.h>
#include <ddi/device.h>
#include <synch/spinlock.h>
 
static irq_ownership_t cuda_claim(irq_t *irq);
static void cuda_irq_handler(irq_t *irq);
 
static void cuda_irq_listen(irq_t *irq);
static void cuda_irq_receive(irq_t *irq);
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len);
static void cuda_irq_send_start(irq_t *irq);
static void cuda_irq_send(irq_t *irq);
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *buf, size_t len);
static void cuda_send_start(cuda_instance_t *instance);
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable);
 
/** B register fields */
enum {
TREQ = 0x08,
TACK = 0x10,
TIP = 0x20
};
 
/** IER register fields */
enum {
IER_CLR = 0x00,
IER_SET = 0x80,
 
SR_INT = 0x04,
ALL_INT = 0x7f
};
 
/** ACR register fields */
enum {
SR_OUT = 0x10
};
 
/** Packet types */
enum {
PT_ADB = 0x00,
PT_CUDA = 0x01
};
 
/** CUDA packet types */
enum {
CPT_AUTOPOLL = 0x01
};
 
cuda_instance_t *cuda_init(cuda_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
cuda_instance_t *instance
= malloc(sizeof(cuda_instance_t), FRAME_ATOMIC);
if (instance) {
instance->cuda = dev;
instance->kbrdin = NULL;
instance->xstate = cx_listen;
instance->bidx = 0;
instance->snd_bytes = 0;
 
spinlock_initialize(&instance->dev_lock, "cuda_dev");
 
/* Disable all interrupts from CUDA. */
pio_write_8(&dev->ier, IER_CLR | ALL_INT);
 
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = cuda_claim;
instance->irq.handler = cuda_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
instance->irq.preack = true;
}
return instance;
}
 
#include <print.h>
void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance);
ASSERT(kbrdin);
 
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
 
/* Enable SR interrupt. */
pio_write_8(&dev->ier, TIP | TREQ);
pio_write_8(&dev->ier, IER_SET | SR_INT);
 
/* Enable ADB autopolling. */
cuda_autopoll_set(instance, true);
}
 
static irq_ownership_t cuda_claim(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t ifr;
 
spinlock_lock(&instance->dev_lock);
ifr = pio_read_8(&dev->ifr);
spinlock_unlock(&instance->dev_lock);
 
if ((ifr & SR_INT) == 0)
return IRQ_DECLINE;
 
return IRQ_ACCEPT;
}
 
static void cuda_irq_handler(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
uint8_t rbuf[CUDA_RCV_BUF_SIZE];
size_t len;
bool handle;
 
handle = false;
len = 0;
 
spinlock_lock(&instance->dev_lock);
 
/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
pio_write_8(&instance->cuda->ifr, SR_INT);
 
switch (instance->xstate) {
case cx_listen: cuda_irq_listen(irq); break;
case cx_receive: cuda_irq_receive(irq); break;
case cx_rcv_end: cuda_irq_rcv_end(irq, rbuf, &len);
handle = true; break;
case cx_send_start: cuda_irq_send_start(irq); break;
case cx_send: cuda_irq_send(irq); break;
}
 
spinlock_unlock(&instance->dev_lock);
 
/* Handle an incoming packet. */
if (handle)
cuda_packet_handle(instance, rbuf, len);
}
 
/** Interrupt in listen state.
*
* Start packet reception.
*/
static void cuda_irq_listen(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) != 0) {
printf("cuda_irq_listen: no TREQ?!\n");
return;
}
 
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
instance->xstate = cx_receive;
}
 
/** Interrupt in receive state.
*
* Receive next byte of packet.
*/
static void cuda_irq_receive(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b, data;
 
data = pio_read_8(&dev->sr);
if (instance->bidx < CUDA_RCV_BUF_SIZE)
instance->rcv_buf[instance->bidx++] = data;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
pio_write_8(&dev->b, b ^ TACK);
} else {
pio_write_8(&dev->b, b | TACK | TIP);
instance->xstate = cx_rcv_end;
}
}
 
/** Interrupt in rcv_end state.
*
* Terminate packet reception. Either go back to listen state or start
* receiving another packet if CUDA has one for us.
*/
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t data, b;
 
b = pio_read_8(&dev->b);
data = pio_read_8(&dev->sr);
 
if ((b & TREQ) == 0) {
instance->xstate = cx_receive;
pio_write_8(&dev->b, b & ~TIP);
} else {
instance->xstate = cx_listen;
cuda_send_start(instance);
}
 
memcpy(buf, instance->rcv_buf, instance->bidx);
*len = instance->bidx;
instance->bidx = 0;
}
 
/** Interrupt in send_start state.
*
* Process result of sending first byte (and send second on success).
*/
static void cuda_irq_send_start(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
/* Collision */
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK);
instance->xstate = cx_listen;
return;
}
 
pio_write_8(&dev->sr, instance->snd_buf[1]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
instance->bidx = 2;
 
instance->xstate = cx_send;
}
 
/** Interrupt in send state.
*
* Send next byte or terminate transmission.
*/
static void cuda_irq_send(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
 
if (instance->bidx < instance->snd_bytes) {
/* Send next byte. */
pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
return;
}
 
/* End transfer. */
instance->snd_bytes = 0;
instance->bidx = 0;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP);
 
instance->xstate = cx_listen;
/* TODO: Match reply with request. */
}
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *data, size_t len)
{
if (data[0] != 0x00 || data[1] != 0x40 || (data[2] != 0x2c
&& data[2] != 0x8c))
return;
 
/* The packet contains one or two scancodes. */
if (data[3] != 0xff)
indev_push_character(instance->kbrdin, data[3]);
if (data[4] != 0xff)
indev_push_character(instance->kbrdin, data[4]);
}
 
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable)
{
instance->snd_buf[0] = PT_CUDA;
instance->snd_buf[1] = CPT_AUTOPOLL;
instance->snd_buf[2] = enable ? 0x01 : 0x00;
instance->snd_bytes = 3;
instance->bidx = 0;
 
cuda_send_start(instance);
}
 
static void cuda_send_start(cuda_instance_t *instance)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance->xstate == cx_listen);
 
if (instance->snd_bytes == 0)
return;
 
/* Check for incoming data. */
if ((pio_read_8(&dev->b) & TREQ) == 0)
return;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT);
pio_write_8(&dev->sr, instance->snd_buf[0]);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
 
instance->xstate = cx_send_start;
}
 
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/ega/ega.c
0,0 → 1,587
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch_drivers
* @{
*/
/**
* @file
* @brief EGA driver.
*/
 
#include <genarch/drivers/ega/ega.h>
#include <putchar.h>
#include <mm/page.h>
#include <mm/as.h>
#include <mm/slab.h>
#include <arch/mm/page.h>
#include <synch/spinlock.h>
#include <arch/types.h>
#include <arch/asm.h>
#include <memstr.h>
#include <string.h>
#include <console/chardev.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <ddi/ddi.h>
 
/*
* The EGA driver.
* Simple and short. Function for displaying characters and "scrolling".
*/
 
SPINLOCK_INITIALIZE(egalock);
static uint32_t ega_cursor;
static uint8_t *videoram;
static uint8_t *backbuf;
static ioport8_t *ega_base;
 
#define SPACE 0x20
#define STYLE 0x1e
#define INVAL 0x17
 
#define EMPTY_CHAR ((STYLE << 8) | SPACE)
 
static uint16_t ega_oem_glyph(const wchar_t ch)
{
if ((ch >= 0x0000) && (ch <= 0x007f))
return ch;
if (ch == 0x00a0)
return 255;
if (ch == 0x00a1)
return 173;
if ((ch >= 0x00a2) && (ch <= 0x00a3))
return (ch - 7);
if (ch == 0x00a5)
return 157;
if (ch == 0x00aa)
return 166;
if (ch == 0x00ab)
return 174;
if (ch == 0x00ac)
return 170;
if (ch == 0x00b0)
return 248;
if (ch == 0x00b1)
return 241;
if (ch == 0x00b2)
return 253;
if (ch == 0x00b5)
return 230;
if (ch == 0x00b7)
return 250;
if (ch == 0x00ba)
return 167;
if (ch == 0x00bb)
return 175;
if (ch == 0x00bc)
return 172;
if (ch == 0x00bd)
return 171;
if (ch == 0x00bf)
return 168;
if ((ch >= 0x00c4) && (ch <= 0x00c5))
return (ch - 54);
if (ch == 0x00c6)
return 146;
if (ch == 0x00c7)
return 128;
if (ch == 0x00c9)
return 144;
if (ch == 0x00d1)
return 165;
if (ch == 0x00d6)
return 153;
if (ch == 0x00dc)
return 154;
if (ch == 0x00df)
return 225;
if (ch == 0x00e0)
return 133;
if (ch == 0x00e1)
return 160;
if (ch == 0x00e2)
return 131;
if (ch == 0x00e4)
return 132;
if (ch == 0x00e5)
return 134;
if (ch == 0x00e6)
return 145;
if (ch == 0x00e7)
return 135;
if (ch == 0x00e8)
return 138;
if (ch == 0x00e9)
return 130;
if ((ch >= 0x00ea) && (ch <= 0x00eb))
return (ch - 98);
if (ch == 0x00ec)
return 141;
if (ch == 0x00ed)
return 161;
if (ch == 0x00ee)
return 140;
if (ch == 0x00ef)
return 139;
if (ch == 0x00f1)
return 164;
if (ch == 0x00f2)
return 149;
if (ch == 0x00f3)
return 162;
if (ch == 0x00f4)
return 147;
if (ch == 0x00f6)
return 148;
if (ch == 0x00f7)
return 246;
if (ch == 0x00f9)
return 151;
if (ch == 0x00fa)
return 163;
if (ch == 0x00fb)
return 150;
if (ch == 0x00fc)
return 129;
if (ch == 0x00ff)
return 152;
if (ch == 0x0192)
return 159;
if (ch == 0x0393)
return 226;
if (ch == 0x0398)
return 233;
if (ch == 0x03a3)
return 228;
if (ch == 0x03a6)
return 232;
if (ch == 0x03a9)
return 234;
if (ch == 0x03b1)
return 224;
if (ch == 0x03b4)
return 235;
if (ch == 0x03b5)
return 238;
if (ch == 0x03c0)
return 227;
if (ch == 0x03c3)
return 229;
if (ch == 0x03c4)
return 231;
if (ch == 0x03c6)
return 237;
if (ch == 0x207f)
return 252;
if (ch == 0x20a7)
return 158;
if (ch == 0x2219)
return 249;
if (ch == 0x221a)
return 251;
if (ch == 0x221e)
return 236;
if (ch == 0x2229)
return 239;
if (ch == 0x2248)
return 247;
if (ch == 0x2261)
return 240;
if (ch == 0x2264)
return 243;
if (ch == 0x2265)
return 242;
if (ch == 0x2310)
return 169;
if ((ch >= 0x2320) && (ch <= 0x2321))
return (ch - 8748);
if (ch == 0x2500)
return 196;
if (ch == 0x2502)
return 179;
if (ch == 0x250c)
return 218;
if (ch == 0x2510)
return 191;
if (ch == 0x2514)
return 192;
if (ch == 0x2518)
return 217;
if (ch == 0x251c)
return 195;
if (ch == 0x2524)
return 180;
if (ch == 0x252c)
return 194;
if (ch == 0x2534)
return 193;
if (ch == 0x253c)
return 197;
if (ch == 0x2550)
return 205;
if (ch == 0x2551)
return 186;
if ((ch >= 0x2552) && (ch <= 0x2553))
return (ch - 9341);
if (ch == 0x2554)
return 201;
if (ch == 0x2555)
return 184;
if (ch == 0x2556)
return 183;
if (ch == 0x2557)
return 187;
if (ch == 0x2558)
return 212;
if (ch == 0x2559)
return 211;
if (ch == 0x255a)
return 200;
if (ch == 0x255b)
return 190;
if (ch == 0x255c)
return 189;
if (ch == 0x255d)
return 188;
if ((ch >= 0x255e) && (ch <= 0x255f))
return (ch - 9368);
if (ch == 0x2560)
return 204;
if ((ch >= 0x2561) && (ch <= 0x2562))
return (ch - 9388);
if (ch == 0x2563)
return 185;
if ((ch >= 0x2564) && (ch <= 0x2565))
return (ch - 9363);
if (ch == 0x2566)
return 203;
if ((ch >= 0x2567) && (ch <= 0x2568))
return (ch - 9368);
if (ch == 0x2569)
return 202;
if (ch == 0x256a)
return 216;
if (ch == 0x256b)
return 215;
if (ch == 0x256c)
return 206;
if (ch == 0x2580)
return 223;
if (ch == 0x2584)
return 220;
if (ch == 0x2588)
return 219;
if (ch == 0x258c)
return 221;
if (ch == 0x2590)
return 222;
if ((ch >= 0x2591) && (ch <= 0x2593))
return (ch - 9441);
return 256;
}
 
/*
* This function takes care of scrolling.
*/
static void ega_check_cursor(bool silent)
{
if (ega_cursor < EGA_SCREEN)
return;
memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2),
(EGA_SCREEN - EGA_COLS) * 2);
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
if (!silent) {
memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
(EGA_SCREEN - EGA_COLS) * 2);
memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
}
ega_cursor = ega_cursor - EGA_COLS;
}
 
static void ega_show_cursor(bool silent)
{
if (!silent) {
pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG);
pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5)));
}
}
 
static void ega_move_cursor(bool silent)
{
if (!silent) {
pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
}
}
 
static void ega_sync_cursor(bool silent)
{
if (!silent) {
pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG);
pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
ega_cursor = (hi << 8) | lo;
} else
ega_cursor = 0;
if (ega_cursor >= EGA_SCREEN)
ega_cursor = 0;
if ((ega_cursor % EGA_COLS) != 0)
ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
if (!silent)
memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
ega_check_cursor(silent);
ega_move_cursor(silent);
ega_show_cursor(silent);
}
 
static void ega_display_char(wchar_t ch, bool silent)
{
uint16_t index = ega_oem_glyph(ch);
uint8_t glyph;
uint8_t style;
if ((index >> 8)) {
glyph = U_SPECIAL;
style = INVAL;
} else {
glyph = index & 0xff;
style = STYLE;
}
backbuf[ega_cursor * 2] = glyph;
backbuf[ega_cursor * 2 + 1] = style;
if (!silent) {
videoram[ega_cursor * 2] = glyph;
videoram[ega_cursor * 2 + 1] = style;
}
}
 
static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)
{
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&egalock);
switch (ch) {
case '\n':
ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
break;
case '\t':
ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
break;
case '\b':
if (ega_cursor % EGA_COLS)
ega_cursor--;
break;
default:
ega_display_char(ch, silent);
ega_cursor++;
break;
}
ega_check_cursor(silent);
ega_move_cursor(silent);
spinlock_unlock(&egalock);
interrupts_restore(ipl);
}
 
static outdev_t ega_console;
static outdev_operations_t ega_ops = {
.write = ega_putchar
};
 
void ega_init(ioport8_t *base, uintptr_t videoram_phys)
{
/* Initialize the software structure. */
ega_base = base;
backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
if (!backbuf)
panic("Unable to allocate backbuffer.");
videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE);
/* Synchronize the back buffer and cursor position. */
memcpy(backbuf, videoram, EGA_VRAM_SIZE);
ega_sync_cursor(silent);
outdev_initialize("ega", &ega_console, &ega_ops);
stdout = &ega_console;
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 2);
sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
sysinfo_set_item_val("fb.blinking", NULL, true);
sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);
}
 
void ega_redraw(void)
{
memcpy(videoram, backbuf, EGA_VRAM_SIZE);
ega_move_cursor(silent);
ega_show_cursor(silent);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/ns16550/ns16550.c
0,0 → 1,123
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief NS 16550 serial controller driver.
*/
 
#include <genarch/drivers/ns16550/ns16550.h>
#include <ddi/irq.h>
#include <arch/asm.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
#define LSR_DATA_READY 0x01
 
static irq_ownership_t ns16550_claim(irq_t *irq)
{
ns16550_instance_t *instance = irq->instance;
ns16550_t *dev = instance->ns16550;
if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
return IRQ_ACCEPT;
else
return IRQ_DECLINE;
}
 
static void ns16550_irq_handler(irq_t *irq)
{
ns16550_instance_t *instance = irq->instance;
ns16550_t *dev = instance->ns16550;
if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
uint8_t data = pio_read_8(&dev->rbr);
indev_push_character(instance->kbrdin, data);
}
}
 
/**< Clear input buffer. */
static void ns16550_clear_buffer(ns16550_t *dev)
{
while ((pio_read_8(&dev->lsr) & LSR_DATA_READY))
(void) pio_read_8(&dev->rbr);
}
 
/** Initialize ns16550.
*
* @param dev Addrress of the beginning of the device in I/O space.
* @param devno Device number.
* @param inr Interrupt number.
* @param cir Clear interrupt function.
* @param cir_arg First argument to cir.
*
* @return Keyboard instance or NULL on failure.
*
*/
ns16550_instance_t *ns16550_init(ns16550_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
ns16550_instance_t *instance
= malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC);
if (instance) {
instance->ns16550 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = ns16550_claim;
instance->irq.handler = ns16550_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
}
return instance;
}
 
void ns16550_wire(ns16550_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
ns16550_clear_buffer(instance->ns16550);
/* Enable interrupts */
pio_write_8(&instance->ns16550->ier, IER_ERBFI);
pio_write_8(&instance->ns16550->mcr, MCR_OUT2);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/dsrln/dsrlnin.c
0,0 → 1,85
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Dummy serial line input.
*/
 
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <arch/asm.h>
#include <ddi/device.h>
 
static irq_ownership_t dsrlnin_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
static void dsrlnin_irq_handler(irq_t *irq)
{
dsrlnin_instance_t *instance = irq->instance;
dsrlnin_t *dev = instance->dsrlnin;
indev_push_character(instance->srlnin, pio_read_8(&dev->data));
}
 
dsrlnin_instance_t *dsrlnin_init(dsrlnin_t *dev, inr_t inr)
{
dsrlnin_instance_t *instance
= malloc(sizeof(dsrlnin_instance_t), FRAME_ATOMIC);
if (instance) {
instance->dsrlnin = dev;
instance->srlnin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = dsrlnin_claim;
instance->irq.handler = dsrlnin_irq_handler;
instance->irq.instance = instance;
}
return instance;
}
 
void dsrlnin_wire(dsrlnin_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
instance->srlnin = srlnin;
irq_register(&instance->irq);
}
 
/** @}
*/
/branches/arm/kernel/genarch/src/drivers/dsrln/dsrlnout.c
0,0 → 1,76
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Dummy serial line output.
*/
 
 
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <console/chardev.h>
#include <arch/asm.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <string.h>
 
static ioport8_t *dsrlnout_base;
 
static void dsrlnout_putchar(outdev_t *dev __attribute__((unused)), const wchar_t ch, bool silent)
{
if (!silent) {
if (ascii_check(ch))
pio_write_8(dsrlnout_base, ch);
else
pio_write_8(dsrlnout_base, U_SPECIAL);
}
}
 
static outdev_t dsrlnout_console;
static outdev_operations_t dsrlnout_ops = {
.write = dsrlnout_putchar
};
 
void dsrlnout_init(ioport8_t *base)
{
/* Initialize the software structure. */
dsrlnout_base = base;
outdev_initialize("dsrlnout", &dsrlnout_console, &dsrlnout_ops);
stdout = &dsrlnout_console;
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 3);
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base));
}
 
/** @}
*/
/branches/arm/kernel/genarch/src/drivers/i8042/i8042.c
0,0 → 1,127
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief i8042 processor driver
*
* It takes care of the i8042 serial communication.
*
*/
 
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <arch/asm.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
#define i8042_SET_COMMAND 0x60
#define i8042_COMMAND 0x69
#define i8042_CPU_RESET 0xfe
 
#define i8042_BUFFER_FULL_MASK 0x01
#define i8042_WAIT_MASK 0x02
 
static irq_ownership_t i8042_claim(irq_t *irq)
{
i8042_instance_t *i8042_instance = irq->instance;
i8042_t *dev = i8042_instance->i8042;
if (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
return IRQ_ACCEPT;
else
return IRQ_DECLINE;
}
 
static void i8042_irq_handler(irq_t *irq)
{
i8042_instance_t *instance = irq->instance;
i8042_t *dev = instance->i8042;
uint8_t status;
if (((status = pio_read_8(&dev->status)) & i8042_BUFFER_FULL_MASK)) {
uint8_t data = pio_read_8(&dev->data);
indev_push_character(instance->kbrdin, data);
}
}
 
/**< Clear input buffer. */
static void i8042_clear_buffer(i8042_t *dev)
{
while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
(void) pio_read_8(&dev->data);
}
 
/** Initialize i8042. */
i8042_instance_t *i8042_init(i8042_t *dev, inr_t inr)
{
i8042_instance_t *instance
= malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
if (instance) {
instance->i8042 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = i8042_claim;
instance->irq.handler = i8042_irq_handler;
instance->irq.instance = instance;
}
return instance;
}
 
void i8042_wire(i8042_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
i8042_clear_buffer(instance->i8042);
}
 
/* Reset CPU by pulsing pin 0 */
void i8042_cpu_reset(i8042_t *dev)
{
interrupts_disable();
i8042_clear_buffer(dev);
/* Reset CPU */
pio_write_8(&dev->status, i8042_CPU_RESET);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/z8530/z8530.c
0,0 → 1,136
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Zilog 8530 serial controller driver.
*/
 
#include <genarch/drivers/z8530/z8530.h>
#include <console/chardev.h>
#include <ddi/irq.h>
#include <arch/asm.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
static inline void z8530_write(ioport8_t *ctl, uint8_t reg, uint8_t val)
{
/*
* Registers 8-15 will automatically issue the Point High
* command as their bit 3 is 1.
*/
pio_write_8(ctl, reg); /* Select register */
pio_write_8(ctl, val); /* Write value */
}
 
static inline uint8_t z8530_read(ioport8_t *ctl, uint8_t reg)
{
/*
* Registers 8-15 will automatically issue the Point High
* command as their bit 3 is 1.
*/
pio_write_8(ctl, reg); /* Select register */
return pio_read_8(ctl);
}
 
static irq_ownership_t z8530_claim(irq_t *irq)
{
z8530_instance_t *instance = irq->instance;
z8530_t *dev = instance->z8530;
if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA)
return IRQ_ACCEPT;
else
return IRQ_DECLINE;
}
 
static void z8530_irq_handler(irq_t *irq)
{
z8530_instance_t *instance = irq->instance;
z8530_t *dev = instance->z8530;
if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) {
uint8_t data = z8530_read(&dev->ctl_a, RR8);
indev_push_character(instance->kbrdin, data);
}
}
 
/** Initialize z8530. */
z8530_instance_t *z8530_init(z8530_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
z8530_instance_t *instance
= malloc(sizeof(z8530_instance_t), FRAME_ATOMIC);
if (instance) {
instance->z8530 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = z8530_claim;
instance->irq.handler = z8530_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
}
return instance;
}
 
void z8530_wire(z8530_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
(void) z8530_read(&instance->z8530->ctl_a, RR8);
/*
* Clear any pending TX interrupts or we never manage
* to set FHC UART interrupt state to idle.
*/
z8530_write(&instance->z8530->ctl_a, WR0, WR0_TX_IP_RST);
/* interrupt on all characters */
z8530_write(&instance->z8530->ctl_a, WR1, WR1_IARCSC);
/* 8 bits per character and enable receiver */
z8530_write(&instance->z8530->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
/* Master Interrupt Enable. */
z8530_write(&instance->z8530->ctl_a, WR9, WR9_MIE);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/mm/page_ht.c
51,8 → 51,8
#include <adt/hash_table.h>
#include <align.h>
 
static index_t hash(unative_t key[]);
static bool compare(unative_t key[], count_t keys, link_t *item);
static size_t hash(unative_t key[]);
static bool compare(unative_t key[], size_t keys, link_t *item);
static void remove_callback(link_t *item);
 
static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
93,11 → 93,11
*
* @return Index into page hash table.
*/
index_t hash(unative_t key[])
size_t hash(unative_t key[])
{
as_t *as = (as_t *) key[KEY_AS];
uintptr_t page = (uintptr_t) key[KEY_PAGE];
index_t index;
size_t index;
/*
* Virtual page addresses have roughly the same probability
124,7 → 124,7
*
* @return true on match, false otherwise.
*/
bool compare(unative_t key[], count_t keys, link_t *item)
bool compare(unative_t key[], size_t keys, link_t *item)
{
pte_t *t;
 
192,6 → 192,8
t->k = !(flags & PAGE_USER);
t->c = (flags & PAGE_CACHEABLE) != 0;
t->p = !(flags & PAGE_NOT_PRESENT);
t->a = false;
t->d = false;
 
t->as = as;
t->page = ALIGN_DOWN(page, PAGE_SIZE);
/branches/arm/kernel/genarch/src/mm/asid.c
32,7 → 32,7
 
/**
* @file
* @brief ASID management.
* @brief ASID management.
*
* Modern processor architectures optimize TLB utilization
* by using ASIDs (a.k.a. memory contexts on sparc64 and
65,7 → 65,7
#include <adt/list.h>
#include <debug.h>
 
static count_t asids_allocated = 0;
static size_t asids_allocated = 0;
 
/** Allocate free address space identifier.
*
120,7 → 120,7
* of TLB entries (e.g. TSB on sparc64), the
* cache must be invalidated as well.
*/
as_invalidate_translation_cache(as, 0, (count_t) -1);
as_invalidate_translation_cache(as, 0, (size_t) -1);
/*
* Get the system rid of the stolen ASID.
/branches/arm/kernel/genarch/src/kbrd/kbrd.c
0,0 → 1,191
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Keyboard processing.
*/
 
#include <genarch/kbrd/kbrd.h>
#include <genarch/kbrd/scanc.h>
 
#ifdef CONFIG_PC_KBD
#include <genarch/kbrd/scanc_pc.h>
#endif
 
#ifdef CONFIG_SUN_KBD
#include <genarch/kbrd/scanc_sun.h>
#endif
 
#ifdef CONFIG_MAC_KBD
#include <genarch/kbrd/scanc_mac.h>
#endif
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch.h>
#include <macros.h>
 
#define IGNORE_CODE 0x7f
#define KEY_RELEASE 0x80
 
#define PRESSED_SHIFT (1 << 0)
#define PRESSED_CAPSLOCK (1 << 1)
#define LOCKED_CAPSLOCK (1 << 0)
 
static indev_operations_t kbrd_raw_ops = {
.poll = NULL
};
 
/** Process release of key.
*
* @param sc Scancode of the key being released.
*/
static void key_released(kbrd_instance_t *instance, wchar_t sc)
{
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags &= ~PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags &= ~PRESSED_CAPSLOCK;
if (instance->lockflags & LOCKED_CAPSLOCK)
instance->lockflags &= ~LOCKED_CAPSLOCK;
else
instance->lockflags |= LOCKED_CAPSLOCK;
break;
default:
break;
}
spinlock_unlock(&instance->keylock);
}
 
/** Process keypress.
*
* @param sc Scancode of the key being pressed.
*/
static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
{
bool letter;
bool shift;
bool capslock;
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags |= PRESSED_CAPSLOCK;
break;
case SC_SCAN_ESCAPE:
break;
default:
letter = islower(sc_primary_map[sc]);
shift = instance->keyflags & PRESSED_SHIFT;
capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
(instance->lockflags & LOCKED_CAPSLOCK);
if ((letter) && (capslock))
shift = !shift;
if (shift)
indev_push_character(instance->sink, sc_secondary_map[sc]);
else
indev_push_character(instance->sink, sc_primary_map[sc]);
break;
}
spinlock_unlock(&instance->keylock);
}
 
static void kkbrd(void *arg)
{
kbrd_instance_t *instance = (kbrd_instance_t *) arg;
while (true) {
wchar_t sc = indev_pop_character(&instance->raw);
if (sc == IGNORE_CODE)
continue;
if (sc & KEY_RELEASE)
key_released(instance, (sc ^ KEY_RELEASE) & 0x7f);
else
key_pressed(instance, sc & 0x7f);
}
}
 
kbrd_instance_t *kbrd_init(void)
{
kbrd_instance_t *instance
= malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread
= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->sink = NULL;
indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
spinlock_initialize(&instance->keylock, "instance_keylock");
instance->keyflags = 0;
instance->lockflags = 0;
}
return instance;
}
 
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
{
ASSERT(instance);
ASSERT(sink);
instance->sink = sink;
thread_ready(instance->thread);
return &instance->raw;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/kbrd/scanc_mac.c
0,0 → 1,306
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for Macintosh ADB keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
[0x00] = 'a',
[0x01] = 's',
[0x02] = 'd',
[0x03] = 'f',
[0x04] = 'h',
[0x05] = 'g',
[0x06] = 'z',
[0x07] = 'x',
[0x08] = 'c',
[0x09] = 'v',
[0x0a] = U_SPECIAL,
[0x0b] = 'b',
[0x0c] = 'q',
[0x0d] = 'w',
[0x0e] = 'e',
[0x0f] = 'r',
[0x10] = 'y',
[0x11] = 't',
[0x12] = '1',
[0x13] = '2',
[0x14] = '3',
[0x15] = '4',
[0x16] = '6',
[0x17] = '5',
[0x18] = '=',
[0x19] = '9',
[0x1a] = '7',
[0x1b] = '-',
[0x1c] = '8',
[0x1d] = '0',
[0x1e] = ']',
[0x1f] = 'o',
[0x20] = 'u',
[0x21] = '[',
[0x22] = 'i',
[0x23] = 'p',
[0x24] = '\n', /* Enter */
[0x25] = 'l',
[0x26] = 'j',
[0x27] = '\'',
[0x28] = 'k',
[0x29] = ';',
[0x2a] = '\\',
[0x2b] = ',',
[0x2c] = '/',
[0x2d] = 'n',
[0x2e] = 'm',
[0x2f] = '.',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '`',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_ESCAPE,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_LEFT_ARROW,
[0x3c] = U_RIGHT_ARROW,
[0x3d] = U_DOWN_ARROW,
[0x3e] = U_UP_ARROW,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_HOME_ARROW,
[0x74] = U_PAGE_UP,
[0x75] = U_DELETE,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_PAGE_DOWN,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
[0x00] = 'A',
[0x01] = 'S',
[0x02] = 'D',
[0x03] = 'F',
[0x04] = 'H',
[0x05] = 'G',
[0x06] = 'Z',
[0x07] = 'X',
[0x08] = 'C',
[0x09] = 'V',
[0x0a] = U_SPECIAL,
[0x0b] = 'B',
[0x0c] = 'Q',
[0x0d] = 'W',
[0x0e] = 'E',
[0x0f] = 'R',
[0x10] = 'Y',
[0x11] = 'T',
[0x12] = '!',
[0x13] = '@',
[0x14] = '#',
[0x15] = '$',
[0x16] = '^',
[0x17] = '%',
[0x18] = '+',
[0x19] = '(',
[0x1a] = '&',
[0x1b] = '_',
[0x1c] = '*',
[0x1d] = ')',
[0x1e] = '}',
[0x1f] = 'O',
[0x20] = 'U',
[0x21] = '{',
[0x22] = 'I',
[0x23] = 'P',
[0x24] = '\n', /* Enter */
[0x25] = 'L',
[0x26] = 'J',
[0x27] = '"',
[0x28] = 'K',
[0x29] = ':',
[0x2a] = '|',
[0x2b] = '<',
[0x2c] = '?',
[0x2d] = 'N',
[0x2e] = 'M',
[0x2f] = '>',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '~',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_SPECIAL,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_SPECIAL,
[0x3c] = U_SPECIAL,
[0x3d] = U_SPECIAL,
[0x3e] = U_SPECIAL,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_SPECIAL,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** @}
*/
/branches/arm/kernel/genarch/src/kbrd/scanc_pc.c
0,0 → 1,221
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for PC keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
U_NULL, /* 0x00 - undefined */
U_ESCAPE, /* 0x01 - Esc */
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',
'\b', /* 0x0e - Backspace */
'\t', /* 0x0f - Tab */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
'\n', /* 0x1e - Enter */
U_SPECIAL, /* 0x1d - Left Ctrl */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
U_SPECIAL, /* 0x2a - Left Shift */
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
U_SPECIAL, /* 0x36 - Right Shift */
U_SPECIAL, /* 0x37 - Print Screen */
U_SPECIAL, /* 0x38 - Left Alt */
' ',
U_SPECIAL, /* 0x3a - CapsLock */
U_SPECIAL, /* 0x3b - F1 */
U_SPECIAL, /* 0x3c - F2 */
U_SPECIAL, /* 0x3d - F3 */
U_SPECIAL, /* 0x3e - F4 */
U_SPECIAL, /* 0x3f - F5 */
U_SPECIAL, /* 0x40 - F6 */
U_SPECIAL, /* 0x41 - F7 */
U_SPECIAL, /* 0x42 - F8 */
U_SPECIAL, /* 0x43 - F9 */
U_SPECIAL, /* 0x44 - F10 */
U_SPECIAL, /* 0x45 - NumLock */
U_SPECIAL, /* 0x46 - ScrollLock */
U_HOME_ARROW, /* 0x47 - Home */
U_UP_ARROW, /* 0x48 - Up Arrow */
U_PAGE_UP, /* 0x49 - Page Up */
'-',
U_LEFT_ARROW, /* 0x4b - Left Arrow */
'5', /* 0x4c - Numpad Center */
U_RIGHT_ARROW, /* 0x4d - Right Arrow */
'+',
U_END_ARROW, /* 0x4f - End */
U_DOWN_ARROW, /* 0x50 - Down Arrow */
U_PAGE_DOWN, /* 0x51 - Page Down */
'0', /* 0x52 - Numpad Insert */
U_DELETE, /* 0x53 - Delete */
U_SPECIAL, /* 0x54 - Alt-SysRq */
U_SPECIAL, /* 0x55 - F11/F12/PF1/FN */
U_SPECIAL, /* 0x56 - unlabelled key next to LAlt */
U_SPECIAL, /* 0x57 - F11 */
U_SPECIAL, /* 0x58 - F12 */
U_SPECIAL, /* 0x59 */
U_SPECIAL, /* 0x5a */
U_SPECIAL, /* 0x5b */
U_SPECIAL, /* 0x5c */
U_SPECIAL, /* 0x5d */
U_SPECIAL, /* 0x5e */
U_SPECIAL, /* 0x5f */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
U_SPECIAL, /* 0x66 */
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_SPECIAL, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_SPECIAL, /* 0x6b */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_SPECIAL, /* 0x71 */
U_SPECIAL, /* 0x72 */
U_SPECIAL, /* 0x73 */
U_SPECIAL, /* 0x74 */
U_SPECIAL, /* 0x75 */
U_SPECIAL, /* 0x76 */
U_SPECIAL, /* 0x77 */
U_SPECIAL, /* 0x78 */
U_SPECIAL, /* 0x79 */
U_SPECIAL, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_SPECIAL, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
U_NULL, /* 0x00 - undefined */
U_ESCAPE, /* 0x01 - Esc */
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',
'\b', /* 0x0e - Backspace */
'\t', /* 0x0f - Tab */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
'\n', /* 0x1e - Enter */
U_SPECIAL, /* 0x1d - Left Ctrl */
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
U_SPECIAL, /* 0x2a - Left Shift */
'|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?',
U_SPECIAL, /* 0x36 - Right Shift */
U_SPECIAL, /* 0x37 - Print Screen */
U_SPECIAL, /* 0x38 - Left Alt */
' ',
U_SPECIAL, /* 0x3a - CapsLock */
U_SPECIAL, /* 0x3b - F1 */
U_SPECIAL, /* 0x3c - F2 */
U_SPECIAL, /* 0x3d - F3 */
U_SPECIAL, /* 0x3e - F4 */
U_SPECIAL, /* 0x3f - F5 */
U_SPECIAL, /* 0x40 - F6 */
U_SPECIAL, /* 0x41 - F7 */
U_SPECIAL, /* 0x42 - F8 */
U_SPECIAL, /* 0x43 - F9 */
U_SPECIAL, /* 0x44 - F10 */
U_SPECIAL, /* 0x45 - NumLock */
U_SPECIAL, /* 0x46 - ScrollLock */
U_HOME_ARROW, /* 0x47 - Home */
U_UP_ARROW, /* 0x48 - Up Arrow */
U_PAGE_UP, /* 0x49 - Page Up */
'-',
U_LEFT_ARROW, /* 0x4b - Left Arrow */
'5', /* 0x4c - Numpad Center */
U_RIGHT_ARROW, /* 0x4d - Right Arrow */
'+',
U_END_ARROW, /* 0x4f - End */
U_DOWN_ARROW, /* 0x50 - Down Arrow */
U_PAGE_DOWN, /* 0x51 - Page Down */
'0', /* 0x52 - Numpad Insert */
U_DELETE, /* 0x53 - Delete */
U_SPECIAL, /* 0x54 - Alt-SysRq */
U_SPECIAL, /* 0x55 - F11/F12/PF1/FN */
U_SPECIAL, /* 0x56 - unlabelled key next to LAlt */
U_SPECIAL, /* 0x57 - F11 */
U_SPECIAL, /* 0x58 - F12 */
U_SPECIAL, /* 0x59 */
U_SPECIAL, /* 0x5a */
U_SPECIAL, /* 0x5b */
U_SPECIAL, /* 0x5c */
U_SPECIAL, /* 0x5d */
U_SPECIAL, /* 0x5e */
U_SPECIAL, /* 0x5f */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
U_SPECIAL, /* 0x66 */
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_SPECIAL, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_SPECIAL, /* 0x6b */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_SPECIAL, /* 0x71 */
U_SPECIAL, /* 0x72 */
U_SPECIAL, /* 0x73 */
U_SPECIAL, /* 0x74 */
U_SPECIAL, /* 0x75 */
U_SPECIAL, /* 0x76 */
U_SPECIAL, /* 0x77 */
U_SPECIAL, /* 0x78 */
U_SPECIAL, /* 0x79 */
U_SPECIAL, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_SPECIAL, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** @}
*/
/branches/arm/kernel/genarch/src/kbrd/scanc_sun.c
0,0 → 1,306
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Scan codes for Sun keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
[0x00] = U_SPECIAL,
[0x01] = U_SPECIAL,
[0x02] = U_SPECIAL,
[0x03] = U_SPECIAL,
[0x04] = U_SPECIAL,
[0x05] = U_SPECIAL, /* F1 */
[0x06] = U_SPECIAL, /* F2 */
[0x07] = U_SPECIAL, /* F10 */
[0x08] = U_SPECIAL, /* F3 */
[0x09] = U_SPECIAL, /* F11 */
[0x0a] = U_SPECIAL, /* F4 */
[0x0b] = U_SPECIAL, /* F12 */
[0x0c] = U_SPECIAL, /* F5 */
[0x0d] = U_SPECIAL, /* Right Alt */
[0x0e] = U_SPECIAL, /* F6 */
[0x0f] = U_SPECIAL,
[0x10] = U_SPECIAL, /* F7 */
[0x11] = U_SPECIAL, /* F8 */
[0x12] = U_SPECIAL, /* F9 */
[0x13] = U_SPECIAL, /* Left Alt */
[0x14] = U_UP_ARROW, /* Up Arrow */
[0x15] = U_SPECIAL, /* Pause */
[0x16] = U_SPECIAL,
[0x17] = U_SPECIAL, /* Scroll Lock */
[0x18] = U_LEFT_ARROW, /* Left Arrow */
[0x19] = U_SPECIAL,
[0x1a] = U_SPECIAL,
[0x1b] = U_DOWN_ARROW, /* Down Arrow */
[0x1c] = U_RIGHT_ARROW, /* Right Arrow */
[0x1d] = U_ESCAPE, /* Esc */
[0x1e] = '1',
[0x1f] = '2',
[0x20] = '3',
[0x21] = '4',
[0x22] = '5',
[0x23] = '6',
[0x24] = '7',
[0x25] = '8',
[0x26] = '9',
[0x27] = '0',
[0x28] = '-',
[0x29] = '=',
[0x2a] = '`',
[0x2b] = '\b', /* Backspace */
[0x2c] = U_SPECIAL, /* Insert */
[0x2d] = U_SPECIAL,
[0x2e] = '/', /* Numpad / */
[0x2f] = '*', /* Numpad * */
[0x30] = U_SPECIAL,
[0x31] = U_SPECIAL,
[0x32] = '.', /* Numpad . */
[0x33] = U_SPECIAL,
[0x34] = U_HOME_ARROW, /* Home */
[0x35] = '\t', /* Tab */
[0x36] = 'q',
[0x37] = 'w',
[0x38] = 'e',
[0x39] = 'r',
[0x3a] = 't',
[0x3b] = 'y',
[0x3c] = 'u',
[0x3d] = 'i',
[0x3e] = 'o',
[0x3f] = 'p',
[0x40] = '[',
[0x41] = ']',
[0x42] = U_DELETE, /* Delete */
[0x43] = U_SPECIAL,
[0x44] = '7', /* Numpad 7 */
[0x45] = '8', /* Numpad 8 */
[0x46] = '9', /* Numpad 9 */
[0x47] = '-', /* Numpad - */
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_END_ARROW, /* End */
[0x4b] = U_SPECIAL,
[0x4c] = U_SPECIAL, /* Control */
[0x4d] = 'a',
[0x4e] = 's',
[0x4f] = 'd',
[0x50] = 'f',
[0x51] = 'g',
[0x52] = 'h',
[0x53] = 'j',
[0x54] = 'k',
[0x55] = 'l',
[0x56] = ';',
[0x57] = '\'',
[0x58] = '\\',
[0x59] = '\n', /* Enter */
[0x5a] = '\n', /* Numpad Enter */
[0x5b] = '4', /* Numpad 4 */
[0x5c] = '5', /* Numpad 5 */
[0x5d] = '6', /* Numpad 6 */
[0x5e] = '0', /* Numpad 0 */
[0x5f] = U_SPECIAL,
[0x60] = U_PAGE_UP, /* Page Up */
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL, /* NumLock */
[0x63] = U_SPECIAL, /* Left Shift */
[0x64] = 'z',
[0x65] = 'x',
[0x66] = 'c',
[0x67] = 'v',
[0x68] = 'b',
[0x69] = 'n',
[0x6a] = 'm',
[0x6b] = ',',
[0x6c] = '.',
[0x6d] = '/',
[0x6e] = U_SPECIAL, /* Right Shift */
[0x6f] = U_SPECIAL,
[0x70] = '1', /* Numpad 1 */
[0x71] = '2', /* Numpad 2 */
[0x72] = '3', /* Numpad 3 */
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL, /* CapsLock */
[0x78] = U_SPECIAL,
[0x79] = ' ',
[0x7a] = U_SPECIAL,
[0x7b] = U_PAGE_DOWN, /* Page Down */
[0x7c] = U_SPECIAL,
[0x7d] = '+', /* Numpad + */
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
[0x00] = U_SPECIAL,
[0x01] = U_SPECIAL,
[0x02] = U_SPECIAL,
[0x03] = U_SPECIAL,
[0x04] = U_SPECIAL,
[0x05] = U_SPECIAL, /* F1 */
[0x06] = U_SPECIAL, /* F2 */
[0x07] = U_SPECIAL, /* F10 */
[0x08] = U_SPECIAL, /* F3 */
[0x09] = U_SPECIAL, /* F11 */
[0x0a] = U_SPECIAL, /* F4 */
[0x0b] = U_SPECIAL, /* F12 */
[0x0c] = U_SPECIAL, /* F5 */
[0x0d] = U_SPECIAL, /* Right Alt */
[0x0e] = U_SPECIAL, /* F6 */
[0x0f] = U_SPECIAL,
[0x10] = U_SPECIAL, /* F7 */
[0x11] = U_SPECIAL, /* F8 */
[0x12] = U_SPECIAL, /* F9 */
[0x13] = U_SPECIAL, /* Left Alt */
[0x14] = U_UP_ARROW, /* Up Arrow */
[0x15] = U_SPECIAL, /* Pause */
[0x16] = U_SPECIAL,
[0x17] = U_SPECIAL, /* Scroll Lock */
[0x18] = U_LEFT_ARROW, /* Left Arrow */
[0x19] = U_SPECIAL,
[0x1a] = U_SPECIAL,
[0x1b] = U_DOWN_ARROW, /* Down Arrow */
[0x1c] = U_RIGHT_ARROW, /* Right Arrow */
[0x1d] = U_ESCAPE, /* Esc */
[0x1e] = '!',
[0x1f] = '@',
[0x20] = '#',
[0x21] = '$',
[0x22] = '%',
[0x23] = '^',
[0x24] = '&',
[0x25] = '*',
[0x26] = '(',
[0x27] = ')',
[0x28] = '_',
[0x29] = '+',
[0x2a] = '~',
[0x2b] = '\b', /* Backspace */
[0x2c] = U_SPECIAL, /* Insert */
[0x2d] = U_SPECIAL,
[0x2e] = '/', /* Numpad / */
[0x2f] = '*', /* Numpad * */
[0x30] = U_SPECIAL,
[0x31] = U_SPECIAL,
[0x32] = '.', /* Numpad . */
[0x33] = U_SPECIAL,
[0x34] = U_HOME_ARROW, /* Home */
[0x35] = '\t', /* Tab */
[0x36] = 'Q',
[0x37] = 'W',
[0x38] = 'E',
[0x39] = 'R',
[0x3a] = 'T',
[0x3b] = 'Y',
[0x3c] = 'U',
[0x3d] = 'I',
[0x3e] = 'O',
[0x3f] = 'P',
[0x40] = '{',
[0x41] = '}',
[0x42] = U_DELETE, /* Delete */
[0x43] = U_SPECIAL,
[0x44] = '7', /* Numpad 7 */
[0x45] = '8', /* Numpad 8 */
[0x46] = '9', /* Numpad 9 */
[0x47] = '-', /* Numpad - */
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_END_ARROW, /* End */
[0x4b] = U_SPECIAL,
[0x4c] = U_SPECIAL, /* Control */
[0x4d] = 'A',
[0x4e] = 'S',
[0x4f] = 'D',
[0x50] = 'F',
[0x51] = 'G',
[0x52] = 'H',
[0x53] = 'J',
[0x54] = 'K',
[0x55] = 'L',
[0x56] = ':',
[0x57] = '"',
[0x58] = '|',
[0x59] = '\n', /* Enter */
[0x5a] = '\n', /* Numpad Enter */
[0x5b] = '4', /* Numpad 4 */
[0x5c] = '5', /* Numpad 5 */
[0x5d] = '6', /* Numpad 6 */
[0x5e] = '0', /* Numpad 0 */
[0x5f] = U_SPECIAL,
[0x60] = U_PAGE_UP, /* Page Up */
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL, /* NumLock */
[0x63] = U_SPECIAL, /* Left Shift */
[0x64] = 'Z',
[0x65] = 'X',
[0x66] = 'C',
[0x67] = 'V',
[0x68] = 'B',
[0x69] = 'N',
[0x6a] = 'M',
[0x6b] = '<',
[0x6c] = '>',
[0x6d] = '?',
[0x6e] = U_SPECIAL, /* Right Shift */
[0x6f] = U_SPECIAL,
[0x70] = '1', /* Numpad 1 */
[0x71] = '2', /* Numpad 2 */
[0x72] = '3', /* Numpad 3 */
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL, /* CapsLock */
[0x78] = U_SPECIAL,
[0x79] = ' ',
[0x7a] = U_SPECIAL,
[0x7b] = U_PAGE_DOWN, /* Page Down */
[0x7c] = U_SPECIAL,
[0x7d] = '+', /* Numpad + */
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** @}
*/
/branches/arm/kernel/genarch/src/kbrd
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/acpi/acpi.c
49,8 → 49,12
struct acpi_rsdt *acpi_rsdt = NULL;
struct acpi_xsdt *acpi_xsdt = NULL;
 
struct acpi_signature_map signature_map[] = {
{ (uint8_t *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" }
struct acpi_signature_map signature_map[] = {
{
(uint8_t *) "APIC",
(void *) &acpi_madt,
"Multiple APIC Description Table"
}
};
 
static int rsdp_check(uint8_t *rsdp) {
105,7 → 109,7
if (!acpi_sdt_check((uint8_t *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
126,7 → 130,7
if (!acpi_sdt_check((uint8_t *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
160,13 → 164,16
return;
 
rsdp_found:
printf("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
 
acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address;
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
if (acpi_rsdp->revision)
acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
 
if (acpi_rsdt) map_sdt((struct acpi_sdt_header *) acpi_rsdt);
if (acpi_xsdt) map_sdt((struct acpi_sdt_header *) acpi_xsdt);
if (acpi_rsdt)
map_sdt((struct acpi_sdt_header *) acpi_rsdt);
if (acpi_xsdt)
map_sdt((struct acpi_sdt_header *) acpi_xsdt);
 
if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) {
printf("RSDT: bad checksum\n");
177,8 → 184,10
return;
}
 
if (acpi_xsdt) configure_via_xsdt();
else if (acpi_rsdt) configure_via_rsdt();
if (acpi_xsdt)
configure_via_xsdt();
else if (acpi_rsdt)
configure_via_rsdt();
 
}
 
/branches/arm/kernel/genarch/src/acpi/madt.c
62,11 → 62,11
struct madt_l_apic *madt_l_apic_entries = NULL;
struct madt_io_apic *madt_io_apic_entries = NULL;
 
index_t madt_l_apic_entry_index = 0;
index_t madt_io_apic_entry_index = 0;
count_t madt_l_apic_entry_cnt = 0;
count_t madt_io_apic_entry_cnt = 0;
count_t cpu_count = 0;
size_t madt_l_apic_entry_index = 0;
size_t madt_io_apic_entry_index = 0;
size_t madt_l_apic_entry_cnt = 0;
size_t madt_io_apic_entry_cnt = 0;
size_t cpu_count = 0;
 
struct madt_apic_header * * madt_entries_index = NULL;
unsigned int madt_entries_index_cnt = 0;
86,10 → 86,10
/*
* ACPI MADT Implementation of SMP configuration interface.
*/
static count_t madt_cpu_count(void);
static bool madt_cpu_enabled(index_t i);
static bool madt_cpu_bootstrap(index_t i);
static uint8_t madt_cpu_apic_id(index_t i);
static size_t madt_cpu_count(void);
static bool madt_cpu_enabled(size_t i);
static bool madt_cpu_bootstrap(size_t i);
static uint8_t madt_cpu_apic_id(size_t i);
static int madt_irq_to_pin(unsigned int irq);
 
struct smp_config_operations madt_config_operations = {
100,12 → 100,12
.irq_to_pin = madt_irq_to_pin
};
 
count_t madt_cpu_count(void)
size_t madt_cpu_count(void)
{
return madt_l_apic_entry_cnt;
}
 
bool madt_cpu_enabled(index_t i)
bool madt_cpu_enabled(size_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
112,13 → 112,13
 
}
 
bool madt_cpu_bootstrap(index_t i)
bool madt_cpu_bootstrap(size_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
}
 
uint8_t madt_cpu_apic_id(index_t i)
uint8_t madt_cpu_apic_id(size_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
/branches/arm/kernel/genarch/src/ofw/ebus.c
38,17 → 38,18
#include <genarch/ofw/ofw_tree.h>
#include <arch/memstr.h>
#include <arch/trap/interrupt.h>
#include <func.h>
#include <string.h>
#include <panic.h>
#include <debug.h>
#include <macros.h>
 
/** Apply EBUS ranges to EBUS register. */
bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
bool
ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
{
ofw_tree_property_t *prop;
ofw_ebus_range_t *range;
count_t ranges;
size_t ranges;
 
prop = ofw_tree_getprop(node, "ranges");
if (!prop)
62,11 → 63,13
for (i = 0; i < ranges; i++) {
if (reg->space != range[i].child_space)
continue;
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
if (overlaps(reg->addr, reg->size, range[i].child_base,
range[i].size)) {
ofw_pci_reg_t pci_reg;
pci_reg.space = range[i].parent_space;
pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base);
pci_reg.addr = range[i].parent_base +
(reg->addr - range[i].child_base);
pci_reg.size = reg->size;
return ofw_pci_apply_ranges(node->parent, &pci_reg, pa);
76,7 → 79,9
return false;
}
 
bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr)
bool
ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg,
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
{
ofw_tree_property_t *prop;
ofw_tree_node_t *controller;
86,7 → 91,7
return false;
 
ofw_ebus_intr_map_t *intr_map = prop->value;
count_t count = prop->size / sizeof(ofw_ebus_intr_map_t);
size_t count = prop->size / sizeof(ofw_ebus_intr_map_t);
ASSERT(count);
104,8 → 109,8
unsigned int i;
for (i = 0; i < count; i++) {
if ((intr_map[i].space == space) && (intr_map[i].addr == addr)
&& (intr_map[i].intr == intr))
if ((intr_map[i].space == space) &&
(intr_map[i].addr == addr) && (intr_map[i].intr == intr))
goto found;
}
return false;
113,14 → 118,16
found:
/*
* We found the device that functions as an interrupt controller
* for the interrupt. We also found partial mapping from interrupt to INO.
* for the interrupt. We also found partial mapping from interrupt to
* INO.
*/
 
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle);
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"),
intr_map[i].controller_handle);
if (!controller)
return false;
if (strcmp(ofw_tree_node_name(controller), "pci") != 0) {
if (str_cmp(ofw_tree_node_name(controller), "pci") != 0) {
/*
* This is not a PCI node.
*/
130,7 → 137,8
/*
* Let the PCI do the next step in mapping the interrupt.
*/
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr))
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino,
inr, cir, cir_arg))
return false;
 
return true;
/branches/arm/kernel/genarch/src/ofw/fhc.c
38,7 → 38,7
#include <genarch/ofw/ofw_tree.h>
#include <arch/drivers/fhc.h>
#include <arch/memstr.h>
#include <func.h>
#include <string.h>
#include <panic.h>
#include <macros.h>
 
46,7 → 46,7
{
ofw_tree_property_t *prop;
ofw_fhc_range_t *range;
count_t ranges;
size_t ranges;
 
prop = ofw_tree_getprop(node, "ranges");
if (!prop)
66,8 → 66,8
*pa = addr;
return true;
}
if (strcmp(ofw_tree_node_name(node->parent), "central") != 0)
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent));
if (str_cmp(ofw_tree_node_name(node->parent), "central") != 0)
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent));
ofw_central_reg_t central_reg;
84,11 → 84,11
bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa)
{
if (node->parent->parent)
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent));
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent));
ofw_tree_property_t *prop;
ofw_central_range_t *range;
count_t ranges;
size_t ranges;
prop = ofw_tree_getprop(node, "ranges");
if (!prop)
109,7 → 109,9
return false;
}
 
bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr)
bool
ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg,
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
{
fhc_t *fhc = NULL;
if (!node->device) {
126,6 → 128,8
fhc_enable_interrupt(fhc, interrupt);
*inr = interrupt;
*cir = fhc_clear_interrupt;
*cir_arg = fhc;
return true;
}
 
/branches/arm/kernel/genarch/src/ofw/ofw_tree.c
38,7 → 38,7
#include <genarch/ofw/ofw_tree.h>
#include <arch/memstr.h>
#include <mm/slab.h>
#include <func.h>
#include <string.h>
#include <print.h>
#include <panic.h>
 
54,17 → 54,19
 
/** Get OpenFirmware node property.
*
* @param node Node in which to lookup the property.
* @param name Name of the property.
* @param node Node in which to lookup the property.
* @param name Name of the property.
*
* @return Pointer to the property structure or NULL if no such property.
* @return Pointer to the property structure or NULL if no such
* property.
*/
ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
ofw_tree_property_t *
ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
{
unsigned int i;
for (i = 0; i < node->properties; i++) {
if (strcmp(node->property[i].name, name) == 0)
if (str_cmp(node->property[i].name, name) == 0)
return &node->property[i];
}
 
73,9 → 75,9
 
/** Return value of the 'name' property.
*
* @param node Node of interest.
* @param node Node of interest.
*
* @return Value of the 'name' property belonging to the node.
* @return Value of the 'name' property belonging to the node.
*/
const char *ofw_tree_node_name(const ofw_tree_node_t *node)
{
83,10 → 85,10
prop = ofw_tree_getprop(node, "name");
if (!prop)
panic("Node without name property.\n");
panic("Node without name property.");
if (prop->size < 2)
panic("Invalid name property.\n");
panic("Invalid name property.");
return prop->value;
}
93,10 → 95,11
 
/** Lookup child of given name.
*
* @param node Node whose child is being looked up.
* @param name Name of the child being looked up.
* @param node Node whose child is being looked up.
* @param name Name of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
* @return NULL if there is no such child or pointer to the
* matching child node.
*/
ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
{
106,7 → 109,7
* Try to find the disambigued name.
*/
for (cur = node->child; cur; cur = cur->peer) {
if (strcmp(cur->da_name, name) == 0)
if (str_cmp(cur->da_name, name) == 0)
return cur;
}
118,7 → 121,7
* are not always fully-qualified.
*/
for (cur = node->child; cur; cur = cur->peer) {
if (strcmp(ofw_tree_node_name(cur), name) == 0)
if (str_cmp(ofw_tree_node_name(cur), name) == 0)
return cur;
}
127,12 → 130,14
 
/** Lookup first child of given device type.
*
* @param node Node whose child is being looked up.
* @param name Device type of the child being looked up.
* @param node Node whose child is being looked up.
* @param name Device type of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
* @return NULL if there is no such child or pointer to the
* matching child node.
*/
ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
ofw_tree_node_t *
ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
{
ofw_tree_node_t *cur;
ofw_tree_property_t *prop;
141,7 → 146,7
prop = ofw_tree_getprop(cur, "device_type");
if (!prop || !prop->value)
continue;
if (strcmp(prop->value, name) == 0)
if (str_cmp(prop->value, name) == 0)
return cur;
}
153,12 → 158,14
* Child nodes are looked up recursively contrary to peer nodes that
* are looked up iteratively to avoid stack overflow.
*
* @param root Root of the searched subtree.
* @param handle OpenFirmware handle.
* @param root Root of the searched subtree.
* @param handle OpenFirmware handle.
*
* @return NULL if there is no such node or pointer to the matching node.
* @return NULL if there is no such node or pointer to the matching
* node.
*/
ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
ofw_tree_node_t *
ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
{
ofw_tree_node_t *cur;
 
180,12 → 187,14
 
/** Lookup first peer of given device type.
*
* @param node Node whose peer is being looked up.
* @param name Device type of the child being looked up.
* @param node Node whose peer is being looked up.
* @param name Device type of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
* @return NULL if there is no such child or pointer to the
* matching child node.
*/
ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
ofw_tree_node_t *
ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
{
ofw_tree_node_t *cur;
ofw_tree_property_t *prop;
194,7 → 203,7
prop = ofw_tree_getprop(cur, "device_type");
if (!prop || !prop->value)
continue;
if (strcmp(prop->value, name) == 0)
if (str_cmp(prop->value, name) == 0)
return cur;
}
202,29 → 211,57
}
 
 
/** Lookup first peer of given name.
*
* @param node Node whose peer is being looked up.
* @param name Name of the child being looked up.
*
* @return NULL if there is no such peer or pointer to the matching
* peer node.
*/
ofw_tree_node_t *
ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name)
{
ofw_tree_node_t *cur;
ofw_tree_property_t *prop;
for (cur = node->peer; cur; cur = cur->peer) {
prop = ofw_tree_getprop(cur, "name");
if (!prop || !prop->value)
continue;
if (str_cmp(prop->value, name) == 0)
return cur;
}
return NULL;
}
 
/** Lookup OpenFirmware node by its path.
*
* @param path Path to the node.
* @param path Path to the node.
*
* @return NULL if there is no such node or pointer to the leaf node.
* @return NULL if there is no such node or pointer to the leaf
* node.
*/
ofw_tree_node_t *ofw_tree_lookup(const char *path)
{
char buf[NAME_BUF_LEN+1];
char buf[NAME_BUF_LEN + 1];
ofw_tree_node_t *node = ofw_root;
index_t i, j;
size_t i;
size_t j;
if (path[0] != '/')
return NULL;
for (i = 1; i < strlen(path) && node; i = j + 1) {
for (j = i; j < strlen(path) && path[j] != '/'; j++)
;
if (i == j) /* skip extra slashes */
for (i = 1; (i < str_size(path)) && (node); i = j + 1) {
for (j = i; (j < str_size(path)) && (path[j] != '/'); j++);
/* Skip extra slashes */
if (i == j)
continue;
memcpy(buf, &path[i], j - i);
buf[j - i] = '\0';
buf[j - i] = 0;
node = ofw_tree_find_child(node, buf);
}
236,8 → 273,8
* Child nodes are processed recursively and peer nodes are processed
* iteratively in order to avoid stack overflow.
*
* @param node Root of the subtree.
* @param path Current path, NULL for the very root of the entire tree.
* @param node Root of the subtree.
* @param path Current path, NULL for the very root of the entire tree.
*/
static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path)
{
/branches/arm/kernel/genarch/src/ofw/pci.c
39,7 → 39,7
#include <arch/drivers/pci.h>
#include <arch/trap/interrupt.h>
#include <arch/memstr.h>
#include <func.h>
#include <string.h>
#include <panic.h>
#include <macros.h>
 
49,15 → 49,16
 
#define PCI_IGN 0x1f
 
bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
bool
ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
{
ofw_tree_property_t *prop;
ofw_pci_range_t *range;
count_t ranges;
size_t ranges;
 
prop = ofw_tree_getprop(node, "ranges");
if (!prop) {
if (strcmp(ofw_tree_node_name(node->parent), "pci") == 0)
if (str_cmp(ofw_tree_node_name(node->parent), "pci") == 0)
return ofw_pci_apply_ranges(node->parent, reg, pa);
return false;
}
68,10 → 69,13
unsigned int i;
for (i = 0; i < ranges; i++) {
if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK))
if ((reg->space & PCI_SPACE_MASK) !=
(range[i].space & PCI_SPACE_MASK))
continue;
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
*pa = range[i].parent_base + (reg->addr - range[i].child_base);
if (overlaps(reg->addr, reg->size, range[i].child_base,
range[i].size)) {
*pa = range[i].parent_base +
(reg->addr - range[i].child_base);
return true;
}
}
79,7 → 83,9
return false;
}
 
bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out)
bool
ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg,
ofw_pci_reg_t *out)
{
if (reg->space & PCI_ABS_MASK) {
/* already absolute */
91,11 → 97,11
ofw_tree_property_t *prop;
ofw_pci_reg_t *assigned_address;
count_t assigned_addresses;
size_t assigned_addresses;
prop = ofw_tree_getprop(node, "assigned-addresses");
if (!prop)
panic("Can't find \"assigned-addresses\" property.\n");
panic("Cannot find 'assigned-addresses' property.");
assigned_addresses = prop->size / sizeof(ofw_pci_reg_t);
assigned_address = prop->value;
103,7 → 109,8
unsigned int i;
for (i = 0; i < assigned_addresses; i++) {
if ((assigned_address[i].space & PCI_REG_MASK) == (reg->space & PCI_REG_MASK)) {
if ((assigned_address[i].space & PCI_REG_MASK) ==
(reg->space & PCI_REG_MASK)) {
out->space = assigned_address[i].space;
out->addr = reg->addr + assigned_address[i].addr;
out->size = reg->size;
119,7 → 126,9
* So far, we only know how to map interrupts of non-PCI devices connected
* to a PCI bridge.
*/
bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr)
bool
ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino,
int *inr, cir_t *cir, void **cir_arg)
{
pci_t *pci = node->device;
if (!pci) {
132,6 → 141,8
pci_enable_interrupt(pci, ino);
 
*inr = (PCI_IGN << IGN_SHIFT) | ino;
*cir = pci_clear_interrupt;
*cir_arg = pci;
 
return true;
}
/branches/arm/kernel/genarch/src/ofw/sbus.c
43,7 → 43,7
{
ofw_tree_property_t *prop;
ofw_sbus_range_t *range;
count_t ranges;
size_t ranges;
/*
* The SBUS support is very rudimentary in that we simply assume
/branches/arm/kernel/genarch/src/srln/srln.c
0,0 → 1,159
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/**
* @file
* @brief Serial line processing.
*/
 
#include <genarch/srln/srln.h>
#include <console/chardev.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch.h>
#include <string.h>
 
static indev_operations_t srln_raw_ops = {
.poll = NULL
};
 
static void ksrln(void *arg)
{
srln_instance_t *instance = (srln_instance_t *) arg;
bool cr = false;
uint32_t escape = 0;
while (true) {
wchar_t ch = indev_pop_character(&instance->raw);
/* ANSI escape sequence processing */
if (escape != 0) {
escape <<= 8;
escape |= ch & 0xff;
if ((escape == 0x1b4f) || (escape == 0x1b5b) || (escape == 0x1b5b33))
continue;
switch (escape) {
case 0x1b4f46:
case 0x1b5b46:
ch = U_END_ARROW;
escape = 0;
break;
case 0x1b4f48:
case 0x1b5b48:
ch = U_HOME_ARROW;
escape = 0;
break;
case 0x1b5b41:
ch = U_UP_ARROW;
escape = 0;
break;
case 0x1b5b42:
ch = U_DOWN_ARROW;
escape = 0;
break;
case 0x1b5b43:
ch = U_RIGHT_ARROW;
escape = 0;
break;
case 0x1b5b44:
ch = U_LEFT_ARROW;
escape = 0;
break;
case 0x1b5b337e:
ch = U_DELETE;
escape = 0;
break;
default:
escape = 0;
}
}
if (ch == 0x1b) {
escape = ch & 0xff;
continue;
}
/* Replace carriage return with line feed
and suppress any following line feed */
if ((ch == '\n') && (cr)) {
cr = false;
continue;
}
if (ch == '\r') {
ch = '\n';
cr = true;
} else
cr = false;
/* Backspace */
if (ch == 0x7f)
ch = '\b';
indev_push_character(instance->sink, ch);
}
}
 
srln_instance_t *srln_init(void)
{
srln_instance_t *instance
= malloc(sizeof(srln_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread
= thread_create(ksrln, (void *) instance, TASK, 0, "ksrln", false);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->sink = NULL;
indev_initialize("srln", &instance->raw, &srln_raw_ops);
}
return instance;
}
 
indev_t *srln_wire(srln_instance_t *instance, indev_t *sink)
{
ASSERT(instance);
ASSERT(sink);
instance->sink = sink;
thread_ready(instance->thread);
return &instance->raw;
}
 
/** @}
*/
/branches/arm/kernel/genarch/src/multiboot/multiboot.c
0,0 → 1,139
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#include <genarch/multiboot/multiboot.h>
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
#include <string.h>
#include <macros.h>
 
/** Extract command name from the multiboot module command line.
*
* @param buf Destination buffer (will always NULL-terminate).
* @param sz Size of destination buffer (in bytes).
* @param cmd_line Input string (the command line).
*
*/
static void extract_command(char *buf, size_t sz, const char *cmd_line)
{
/* Find the first space. */
const char *end = str_chr(cmd_line, ' ');
if (end == NULL)
end = cmd_line + str_size(cmd_line);
/*
* Find last occurence of '/' before 'end'. If found, place start at
* next character. Otherwise, place start at beginning of buffer.
*/
const char *cp = end;
const char *start = buf;
while (cp != start) {
if (*cp == '/') {
start = cp + 1;
break;
}
cp--;
}
/* Copy the command. */
str_ncpy(buf, sz, start, (size_t) (end - start));
}
 
/** Parse multiboot information structure.
*
* If @a signature does not contain a valid multiboot signature,
* assumes no multiboot information is available.
*
* @param signature Should contain the multiboot signature.
* @param mi Pointer to the multiboot information structure.
*/
void multiboot_info_parse(uint32_t signature, const multiboot_info_t *mi)
{
uint32_t flags;
if (signature == MULTIBOOT_LOADER_MAGIC)
flags = mi->flags;
else {
/* No multiboot info available. */
flags = 0;
}
/* Copy module information. */
uint32_t i;
if ((flags & MBINFO_FLAGS_MODS) != 0) {
init.cnt = min(mi->mods_count, CONFIG_INIT_TASKS);
multiboot_mod_t *mods
= (multiboot_mod_t *) MULTIBOOT_PTR(mi->mods_addr);
for (i = 0; i < init.cnt; i++) {
init.tasks[i].addr = PA2KA(mods[i].start);
init.tasks[i].size = mods[i].end - mods[i].start;
/* Copy command line, if available. */
if (mods[i].string) {
extract_command(init.tasks[i].name,
CONFIG_TASK_NAME_BUFLEN,
MULTIBOOT_PTR(mods[i].string));
} else
init.tasks[i].name[0] = 0;
}
} else
init.cnt = 0;
/* Copy memory map. */
if ((flags & MBINFO_FLAGS_MMAP) != 0) {
int32_t mmap_length = mi->mmap_length;
multiboot_mmap_t *mme = MULTIBOOT_PTR(mi->mmap_addr);
e820counter = 0;
i = 0;
while ((mmap_length > 0) && (i < MEMMAP_E820_MAX_RECORDS)) {
e820table[i++] = mme->mm_info;
/* Compute address of next structure. */
uint32_t size = sizeof(mme->size) + mme->size;
mme = ((void *) mme) + size;
mmap_length -= size;
}
e820counter = i;
} else
e820counter = 0;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/fb/helenos.xbm
File deleted
/branches/arm/kernel/genarch/src/fb/fb.c
1,4 → 1,5
/*
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
26,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
33,6 → 34,7
*/
 
#include <genarch/fb/font-8x16.h>
#include <genarch/fb/logo-196x66.h>
#include <genarch/fb/visuals.h>
#include <genarch/fb/fb.h>
#include <console/chardev.h>
39,159 → 41,125
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <mm/slab.h>
#include <align.h>
#include <panic.h>
#include <memstr.h>
#include <config.h>
#include <bitops.h>
#include <print.h>
#include <string.h>
#include <ddi/ddi.h>
#include <arch/types.h>
 
#include "helenos.xbm"
SPINLOCK_INITIALIZE(fb_lock);
 
static parea_t fb_parea; /**< Physical memory area for fb. */
static uint8_t *fb_addr;
static uint16_t *backbuf;
static uint8_t *glyphs;
static uint8_t *bgscan;
 
SPINLOCK_INITIALIZE(fb_lock);
static unsigned int xres;
static unsigned int yres;
 
static uint8_t *fbaddress = NULL;
static unsigned int ylogo;
static unsigned int ytrim;
static unsigned int rowtrim;
 
static uint8_t *blankline = NULL;
static uint8_t *dbbuffer = NULL; /* Buffer for fast scrolling console */
static index_t dboffset;
static unsigned int scanline;
static unsigned int glyphscanline;
 
static unsigned int xres = 0;
static unsigned int yres = 0;
static unsigned int scanline = 0;
static unsigned int pixelbytes = 0;
#ifdef FB_INVERT_COLORS
static bool invert_colors = true;
#else
static bool invert_colors = false;
#endif
static unsigned int pixelbytes;
static unsigned int glyphbytes;
static unsigned int bgscanbytes;
 
static unsigned int cols;
static unsigned int rows;
static unsigned int position = 0;
static unsigned int columns = 0;
static unsigned int rows = 0;
 
#define COL_WIDTH 8
#define ROW_BYTES (scanline * FONT_SCANLINES)
#define BG_COLOR 0x000080
#define FG_COLOR 0xffff00
#define INV_COLOR 0xaaaaaa
 
#define BGCOLOR 0x000080
#define FGCOLOR 0xffff00
#define LOGOCOLOR 0x2020b0
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
 
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
 
#define POINTPOS(x, y) ((y) * scanline + (x) * pixelbytes)
#define X2COL(x) ((x) / FONT_WIDTH)
#define Y2ROW(y) ((y) / FONT_SCANLINES)
 
/***************************************************************/
/* Pixel specific fuctions */
#define FB_POS(x, y) ((y) * scanline + (x) * pixelbytes)
#define BB_POS(col, row) ((row) * cols + (col))
#define GLYPH_POS(glyph, y) ((glyph) * glyphbytes + (y) * glyphscanline)
 
static void (*rgb2scr)(void *, int);
static int (*scr2rgb)(void *);
 
static inline int COLOR(int color)
{
return invert_colors ? ~color : color;
}
static void (*rgb_conv)(void *, uint32_t);
 
/* Conversion routines between different color representations */
static void rgb_byte0888(void *dst, int rgb)
{
*((int *) dst) = rgb;
}
 
static int byte0888_rgb(void *src)
/** ARGB 8:8:8:8 conversion
*
*/
static void rgb_0888(void *dst, uint32_t rgb)
{
return (*((int *) src)) & 0xffffff;
*((uint32_t *) dst) = rgb & 0xffffff;
}
 
static void bgr_byte0888(void *dst, int rgb)
{
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |
RED(rgb, 8);
}
 
static int byte0888_bgr(void *src)
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
{
int color = *(uint32_t *)(src);
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) |
((color >> 16) & 0xff);
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
}
 
static void rgb_byte888(void *dst, int rgb)
{
uint8_t *scr = (uint8_t *) dst;
#if defined(FB_INVERT_ENDIAN)
scr[0] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[2] = BLUE(rgb, 8);
#else
scr[2] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[0] = BLUE(rgb, 8);
#endif
}
 
static int byte888_rgb(void *src)
/** RGB 8:8:8 conversion
*
*/
static void rgb_888(void *dst, uint32_t rgb)
{
uint8_t *scr = (uint8_t *) src;
#if defined(FB_INVERT_ENDIAN)
return scr[0] << 16 | scr[1] << 8 | scr[2];
#else
return scr[2] << 16 | scr[1] << 8 | scr[0];
#endif
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
static void bgr_byte8880(void *dst, int rgb)
{
uint8_t *scr = (uint8_t *) dst;
scr[3] = RED(rgb, 8);
scr[2] = GREEN(rgb, 8);
scr[1] = BLUE(rgb, 8);
}
 
static int byte8880_bgr(void *src)
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
{
uint8_t *scr = (uint8_t *) src;
return scr[3] << 16 | scr[2] << 8 | scr[1];
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
/** 16-bit depth (5:5:5) */
static void rgb_byte555(void *dst, int rgb)
{
/* 5-bit, 5-bits, 5-bits */
*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 |
BLUE(rgb, 5);
}
 
/** 16-bit depth (5:5:5) */
static int byte555_rgb(void *src)
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
{
int color = *(uint16_t *)(src);
return (((color >> 10) & 0x1f) << (16 + 3)) |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3);
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
}
 
/** 16-bit depth (5:6:5) */
static void rgb_byte565(void *dst, int rgb)
{
/* 5-bit, 6-bits, 5-bits */
*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 |
BLUE(rgb, 5);
}
 
/** 16-bit depth (5:6:5) */
static int byte565_rgb(void *src)
/** RGB 5:6:5 conversion
*
*/
static void rgb_565(void *dst, uint32_t rgb)
{
int color = *(uint16_t *)(src);
return (((color >> 11) & 0x1f) << (16 + 3)) |
(((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
}
 
/** Put pixel - 8-bit depth (color palette/3:2:3)
 
/** RGB 3:2:3
*
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer
* will most likely use a color palette. The color appearance
198,258 → 166,279
* will be pretty random and depend on the default installed
* palette. This could be fixed by supporting custom palette
* and setting it to simulate the 8-bit truecolor.
*
* Currently we set the palette on the ia32, amd64 and sparc64 port.
*
* Note that the byte is being inverted by this function. The reason is
* that we would like to use a color palette where the white color code
* is 0 and the black color code is 255, as some machines (Sun Blade 1500)
* use these codes for black and white and prevent to set codes
* 0 and 255 to other colors.
*
*/
static void rgb_byte8(void *dst, int rgb)
static void rgb_323(void *dst, uint32_t rgb)
{
*((uint8_t *) dst) = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 |
BLUE(rgb, 3);
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
}
 
/** Return pixel color - 8-bit depth (color palette/3:2:3)
 
/** Hide logo and refresh screen
*
* See the comment for rgb_byte().
*/
static int byte8_rgb(void *src)
static void logo_hide(bool silent)
{
int color = *(uint8_t *)src;
return (((color >> 5) & 0x7) << (16 + 5)) |
(((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
ylogo = 0;
ytrim = yres;
rowtrim = rows;
if (!silent)
fb_redraw();
}
 
static void putpixel(unsigned int x, unsigned int y, int color)
{
(*rgb2scr)(&fbaddress[POINTPOS(x, y)], COLOR(color));
 
if (dbbuffer) {
int dline = (y + dboffset) % yres;
(*rgb2scr)(&dbbuffer[POINTPOS(x, dline)], COLOR(color));
}
}
 
/** Get pixel from viewport */
static int getpixel(unsigned int x, unsigned int y)
/** Draw character at given position
*
*/
static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent, bool overlay)
{
if (dbbuffer) {
int dline = (y + dboffset) % yres;
return COLOR((*scr2rgb)(&dbbuffer[POINTPOS(x, dline)]));
unsigned int x = COL2X(col);
unsigned int y = ROW2Y(row);
unsigned int yd;
if (y >= ytrim)
logo_hide(silent);
if (!overlay)
backbuf[BB_POS(col, row)] = glyph;
if (!silent) {
for (yd = 0; yd < FONT_SCANLINES; yd++)
memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)],
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline);
}
return COLOR((*scr2rgb)(&fbaddress[POINTPOS(x, y)]));
}
 
 
/** Fill screen with background color */
static void clear_screen(void)
/** Scroll screen down by one row
*
*
*/
static void screen_scroll(bool silent)
{
unsigned int y;
 
for (y = 0; y < yres; y++) {
memcpy(&fbaddress[scanline * y], blankline, xres * pixelbytes);
if (dbbuffer)
memcpy(&dbbuffer[scanline * y], blankline,
xres * pixelbytes);
if (ylogo > 0) {
logo_hide(silent);
return;
}
}
 
 
/** Scroll screen one row up */
static void scroll_screen(void)
{
if (dbbuffer) {
count_t first;
if (!silent) {
unsigned int row;
/* Clear the last row */
memcpy(&dbbuffer[dboffset * scanline], blankline, ROW_BYTES);
dboffset = (dboffset + FONT_SCANLINES) % yres;
first = yres - dboffset;
/* Move all rows one row up */
if (xres * pixelbytes == scanline) {
memcpy(fbaddress, &dbbuffer[dboffset * scanline],
first * scanline);
memcpy(&fbaddress[first * scanline], dbbuffer,
dboffset * scanline);
} else {
/*
* When the scanline is bigger than number of bytes
* in the X-resolution, chances are that the
* frame buffer memory past the X-resolution is special
* in some way. For example, the SUNW,ffb framebuffer
* wraps this area around the beginning of the same
* line. To avoid troubles, copy only memory as
* specified by the resolution.
*/
unsigned int i;
 
for (i = 0; i < first; i++)
memcpy(&fbaddress[i * scanline],
&dbbuffer[(dboffset + i) * scanline],
xres * pixelbytes);
for (i = 0; i < dboffset; i++)
memcpy(&fbaddress[(first + i) * scanline],
&dbbuffer[i * scanline], xres * pixelbytes);
for (row = 0; row < rows; row++) {
unsigned int y = ROW2Y(row);
unsigned int yd;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
unsigned int x;
unsigned int col;
for (col = 0, x = 0; col < cols; col++,
x += FONT_WIDTH) {
uint16_t glyph;
if (row < rows - 1) {
if (backbuf[BB_POS(col, row)] ==
backbuf[BB_POS(col, row + 1)])
continue;
glyph = backbuf[BB_POS(col, row + 1)];
} else
glyph = 0;
memcpy(&fb_addr[FB_POS(x, y + yd)],
&glyphs[GLYPH_POS(glyph, yd)],
glyphscanline);
}
}
}
} else {
uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
if (xres * pixelbytes == scanline) {
/* Move all rows one row up */
memcpy((void *) fbaddress,
(void *) &fbaddress[ROW_BYTES],
scanline * yres - ROW_BYTES);
/* Clear the last row */
memcpy((void *) lastline, (void *) blankline,
ROW_BYTES);
} else {
/*
* See the comment in the dbbuffer case.
*/
unsigned int i;
 
/* Move all rows one row up */
for (i = 0; i < yres - FONT_SCANLINES; i++)
memcpy(&fbaddress[i * scanline],
&fbaddress[(i + FONT_SCANLINES) * scanline],
xres * pixelbytes);
/* Clear the last row */
for (i = 0; i < FONT_SCANLINES; i++)
memcpy(&lastline[i * scanline],
&blankline[i * scanline],
xres * pixelbytes);
}
}
memmove(backbuf, &backbuf[BB_POS(0, 1)], cols * (rows - 1) * sizeof(uint16_t));
memsetw(&backbuf[BB_POS(0, rows - 1)], cols, 0);
}
 
 
static void invert_pixel(unsigned int x, unsigned int y)
static void cursor_put(bool silent)
{
putpixel(x, y, ~getpixel(x, y));
unsigned int col = position % cols;
unsigned int row = position / cols;
glyph_draw(fb_font_glyph(U_CURSOR), col, row, silent, true);
}
 
 
/** Draw one line of glyph at a given position */
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
static void cursor_remove(bool silent)
{
unsigned int i;
 
for (i = 0; i < 8; i++)
if (glline & (1 << (7 - i))) {
putpixel(x + i, y, FGCOLOR);
} else
putpixel(x + i, y, BGCOLOR);
unsigned int col = position % cols;
unsigned int row = position / cols;
glyph_draw(backbuf[BB_POS(col, row)], col, row, silent, true);
}
 
/***************************************************************/
/* Character-console functions */
 
/** Draw character at given position */
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row)
{
unsigned int y;
 
for (y = 0; y < FONT_SCANLINES; y++)
draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y],
col * COL_WIDTH, row * FONT_SCANLINES + y);
}
 
/** Invert character at given position */
static void invert_char(unsigned int col, unsigned int row)
{
unsigned int x;
unsigned int y;
 
for (x = 0; x < COL_WIDTH; x++)
for (y = 0; y < FONT_SCANLINES; y++)
invert_pixel(col * COL_WIDTH + x,
row * FONT_SCANLINES + y);
}
 
/** Draw character at default position */
static void draw_char(char chr)
{
draw_glyph(chr, position % columns, position / columns);
}
 
static void draw_logo(unsigned int startx, unsigned int starty)
{
unsigned int x;
unsigned int y;
unsigned int byte;
unsigned int rowbytes;
 
rowbytes = (helenos_width - 1) / 8 + 1;
 
for (y = 0; y < helenos_height; y++)
for (x = 0; x < helenos_width; x++) {
byte = helenos_bits[rowbytes * y + x / 8];
byte >>= x % 8;
if (byte & 1)
putpixel(startx + x, starty + y,
COLOR(LOGOCOLOR));
}
}
 
/***************************************************************/
/* Stdout specific functions */
 
static void invert_cursor(void)
{
invert_char(position % columns, position / columns);
}
 
/** Print character to screen
*
* Emulate basic terminal commands
* Emulate basic terminal commands.
*
*/
static void fb_putchar(chardev_t *dev, char ch)
static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
{
spinlock_lock(&fb_lock);
switch (ch) {
case '\n':
invert_cursor();
position += columns;
position -= position % columns;
cursor_remove(silent);
position += cols;
position -= position % cols;
break;
case '\r':
invert_cursor();
position -= position % columns;
cursor_remove(silent);
position -= position % cols;
break;
case '\b':
invert_cursor();
if (position % columns)
cursor_remove(silent);
if (position % cols)
position--;
break;
case '\t':
invert_cursor();
cursor_remove(silent);
do {
draw_char(' ');
glyph_draw(fb_font_glyph(' '), position % cols,
position / cols, silent, false);
position++;
} while ((position % 8) && position < columns * rows);
} while ((position % 8) && (position < cols * rows));
break;
default:
draw_char(ch);
glyph_draw(fb_font_glyph(ch), position % cols,
position / cols, silent, false);
position++;
}
if (position >= columns * rows) {
position -= columns;
scroll_screen();
if (position >= cols * rows) {
position -= cols;
screen_scroll(silent);
}
invert_cursor();
cursor_put(silent);
spinlock_unlock(&fb_lock);
}
 
static chardev_t framebuffer;
static chardev_operations_t fb_ops = {
.write = fb_putchar,
static outdev_t fb_console;
static outdev_operations_t fb_ops = {
.write = fb_putchar
};
 
 
/** Initialize framebuffer as a chardev output device
/** Render glyphs
*
* Convert glyphs from device independent font
* description to current visual representation.
*
*/
static void glyphs_render(void)
{
/* Prerender glyphs */
uint16_t glyph;
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
uint32_t fg_color;
if (glyph == FONT_GLYPHS - 1)
fg_color = INV_COLOR;
else
fg_color = FG_COLOR;
unsigned int y;
for (y = 0; y < FONT_SCANLINES; y++) {
unsigned int x;
for (x = 0; x < FONT_WIDTH; x++) {
void *dst = &glyphs[GLYPH_POS(glyph, y) +
x * pixelbytes];
uint32_t rgb = (fb_font[glyph][y] &
(1 << (7 - x))) ? fg_color : BG_COLOR;
rgb_conv(dst, rgb);
}
}
}
/* Prerender background scanline */
unsigned int x;
for (x = 0; x < xres; x++)
rgb_conv(&bgscan[x * pixelbytes], BG_COLOR);
}
 
 
/** Refresh the screen
*
*/
void fb_redraw(void)
{
if (ylogo > 0) {
unsigned int y;
for (y = 0; y < LOGO_HEIGHT; y++) {
unsigned int x;
for (x = 0; x < xres; x++)
rgb_conv(&fb_addr[FB_POS(x, y)],
(x < LOGO_WIDTH) ?
fb_logo[y * LOGO_WIDTH + x] :
LOGO_COLOR);
}
}
unsigned int row;
for (row = 0; row < rowtrim; row++) {
unsigned int y = ylogo + ROW2Y(row);
unsigned int yd;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
unsigned int x;
unsigned int col;
for (col = 0, x = 0; col < cols;
col++, x += FONT_WIDTH) {
uint16_t glyph = backbuf[BB_POS(col, row)];
void *dst = &fb_addr[FB_POS(x, y + yd)];
void *src = &glyphs[GLYPH_POS(glyph, yd)];
memcpy(dst, src, glyphscanline);
}
}
}
if (COL2X(cols) < xres) {
unsigned int y;
unsigned int size = (xres - COL2X(cols)) * pixelbytes;
for (y = ylogo; y < yres; y++)
memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size);
}
if (ROW2Y(rowtrim) + ylogo < yres) {
unsigned int y;
for (y = ROW2Y(rowtrim) + ylogo; y < yres; y++)
memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes);
}
}
 
 
/** Initialize framebuffer as a output character device
*
* @param addr Physical address of the framebuffer
* @param x Screen width in pixels
* @param y Screen height in pixels
457,106 → 446,102
* @param visual Color model
*
*/
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan,
unsigned int visual)
void fb_init(fb_properties_t *props)
{
switch (visual) {
switch (props->visual) {
case VISUAL_INDIRECT_8:
rgb2scr = rgb_byte8;
scr2rgb = byte8_rgb;
rgb_conv = rgb_323;
pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
rgb2scr = rgb_byte555;
scr2rgb = byte555_rgb;
rgb_conv = rgb_555;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
rgb2scr = rgb_byte565;
scr2rgb = byte565_rgb;
rgb_conv = rgb_565;
pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
rgb2scr = rgb_byte888;
scr2rgb = byte888_rgb;
rgb_conv = rgb_888;
pixelbytes = 3;
break;
case VISUAL_BGR_8_8_8:
rgb_conv = bgr_888;
pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
rgb2scr = rgb_byte888;
scr2rgb = byte888_rgb;
rgb_conv = rgb_888;
pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
rgb2scr = rgb_byte0888;
scr2rgb = byte0888_rgb;
rgb_conv = rgb_0888;
pixelbytes = 4;
break;
case VISUAL_BGR_0_8_8_8:
rgb2scr = bgr_byte0888;
scr2rgb = byte0888_bgr;
rgb_conv = bgr_0888;
pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
rgb2scr = bgr_byte8880;
scr2rgb = byte8880_bgr;
pixelbytes = 4;
break;
default:
panic("Unsupported visual.\n");
panic("Unsupported visual.");
}
unsigned int fbsize = scan * y;
xres = props->x;
yres = props->y;
scanline = props->scan;
/* Map the framebuffer */
fbaddress = (uint8_t *) hw_map((uintptr_t) addr, fbsize);
cols = X2COL(xres);
rows = Y2ROW(yres);
xres = x;
yres = y;
scanline = scan;
if (yres > ylogo) {
ylogo = LOGO_HEIGHT;
rowtrim = rows - Y2ROW(ylogo);
if (ylogo % FONT_SCANLINES > 0)
rowtrim--;
ytrim = ROW2Y(rowtrim);
} else {
ylogo = 0;
ytrim = yres;
rowtrim = rows;
}
rows = y / FONT_SCANLINES;
columns = x / COL_WIDTH;
 
fb_parea.pbase = (uintptr_t) addr;
fb_parea.vbase = (uintptr_t) fbaddress;
fb_parea.frames = SIZE2FRAMES(fbsize);
fb_parea.cacheable = false;
ddi_parea_register(&fb_parea);
 
glyphscanline = FONT_WIDTH * pixelbytes;
glyphbytes = ROW2Y(glyphscanline);
bgscanbytes = xres * pixelbytes;
size_t fbsize = scanline * yres;
size_t bbsize = cols * rows * sizeof(uint16_t);
size_t glyphsize = FONT_GLYPHS * glyphbytes;
backbuf = (uint16_t *) malloc(bbsize, 0);
if (!backbuf)
panic("Unable to allocate backbuffer.");
glyphs = (uint8_t *) malloc(glyphsize, 0);
if (!glyphs)
panic("Unable to allocate glyphs.");
bgscan = malloc(bgscanbytes, 0);
if (!bgscan)
panic("Unable to allocate background pixel.");
memsetw(backbuf, cols * rows, 0);
glyphs_render();
fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 1);
sysinfo_set_item_val("fb.width", NULL, xres);
sysinfo_set_item_val("fb.height", NULL, yres);
sysinfo_set_item_val("fb.scanline", NULL, scan);
sysinfo_set_item_val("fb.visual", NULL, visual);
sysinfo_set_item_val("fb.address.physical", NULL, addr);
sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors);
 
/* Allocate double buffer */
unsigned int order = fnzb(SIZE2FRAMES(fbsize) - 1) + 1;
dbbuffer = (uint8_t *) frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
if (!dbbuffer)
printf("Failed to allocate scroll buffer.\n");
dboffset = 0;
 
/* Initialized blank line */
blankline = (uint8_t *) malloc(ROW_BYTES, FRAME_ATOMIC);
if (!blankline)
panic("Failed to allocate blank line for framebuffer.");
for (y = 0; y < FONT_SCANLINES; y++)
for (x = 0; x < xres; x++)
(*rgb2scr)(&blankline[POINTPOS(x, y)], COLOR(BGCOLOR));
sysinfo_set_item_val("fb.scanline", NULL, scanline);
sysinfo_set_item_val("fb.visual", NULL, props->visual);
sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
clear_screen();
 
/* Update size of screen to match text area */
yres = rows * FONT_SCANLINES;
 
draw_logo(xres - helenos_width, 0);
invert_cursor();
 
chardev_initialize("fb", &framebuffer, &fb_ops);
stdout = &framebuffer;
fb_redraw();
outdev_initialize("fb", &fb_console, &fb_ops);
stdout = &fb_console;
}
 
/** @}
/branches/arm/kernel/genarch/src/fb/font-8x16.c
1,5 → 1,6
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2000 Dmitry Bolkhovityanov
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
34,4616 → 35,3235
 
#include <genarch/fb/font-8x16.h>
 
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = {
/** Convert character to font glyph index
*
* The font does not cover all Unicode characters.
* This function converts the character to an appropriate
* glyph in the font or returns an index to the question
* mark glyph if no specific glyph exists.
*/
uint16_t fb_font_glyph(const wchar_t ch)
{
if (ch == 0x0000)
return 0;
if ((ch >= 0x0020) && (ch <= 0x007f))
return (ch - 32);
if ((ch >= 0x00a0) && (ch <= 0x021f))
return (ch - 64);
if ((ch >= 0x0222) && (ch <= 0x0233))
return (ch - 66);
if ((ch >= 0x0250) && (ch <= 0x02ad))
return (ch - 94);
if ((ch >= 0x02b0) && (ch <= 0x02cf))
return (ch - 96);
if ((ch >= 0x02d8) && (ch <= 0x02dd))
return (ch - 104);
if (ch == 0x02ee)
return 630;
if ((ch >= 0x0300) && (ch <= 0x0301))
return (ch - 137);
if (ch == 0x0303)
return 633;
if (ch == 0x0309)
return 634;
if ((ch >= 0x0312) && (ch <= 0x0314))
return (ch - 151);
if (ch == 0x0323)
return 638;
if ((ch >= 0x0340) && (ch <= 0x0341))
return (ch - 193);
if ((ch >= 0x0374) && (ch <= 0x0375))
return (ch - 243);
if (ch == 0x037a)
return 643;
if (ch == 0x037e)
return 644;
if ((ch >= 0x0384) && (ch <= 0x038a))
return (ch - 255);
if (ch == 0x038c)
return 652;
if ((ch >= 0x038e) && (ch <= 0x03a1))
return (ch - 257);
if ((ch >= 0x03a3) && (ch <= 0x03ce))
return (ch - 258);
if ((ch >= 0x03d0) && (ch <= 0x03d7))
return (ch - 259);
if ((ch >= 0x03da) && (ch <= 0x03f3))
return (ch - 261);
if ((ch >= 0x0400) && (ch <= 0x0486))
return (ch - 273);
if ((ch >= 0x0488) && (ch <= 0x04ce))
return (ch - 274);
if ((ch >= 0x04d0) && (ch <= 0x04f5))
return (ch - 275);
if ((ch >= 0x04f8) && (ch <= 0x04f9))
return (ch - 277);
if ((ch >= 0x0500) && (ch <= 0x050f))
return (ch - 283);
if ((ch >= 0x0530) && (ch <= 0x0556))
return (ch - 315);
if ((ch >= 0x0559) && (ch <= 0x055f))
return (ch - 317);
if ((ch >= 0x0561) && (ch <= 0x0587))
return (ch - 318);
if ((ch >= 0x0589) && (ch <= 0x058a))
return (ch - 319);
if ((ch >= 0x0591) && (ch <= 0x05a1))
return (ch - 325);
if ((ch >= 0x05a3) && (ch <= 0x05b9))
return (ch - 326);
if ((ch >= 0x05bb) && (ch <= 0x05c4))
return (ch - 327);
if ((ch >= 0x05d0) && (ch <= 0x05ea))
return (ch - 338);
if ((ch >= 0x05f0) && (ch <= 0x05f4))
return (ch - 343);
if (ch == 0x060c)
return 1182;
if (ch == 0x061b)
return 1183;
if (ch == 0x061f)
return 1184;
if ((ch >= 0x0621) && (ch <= 0x063a))
return (ch - 384);
if ((ch >= 0x0640) && (ch <= 0x0655))
return (ch - 389);
if ((ch >= 0x0660) && (ch <= 0x066d))
return (ch - 399);
if ((ch >= 0x0670) && (ch <= 0x06ed))
return (ch - 401);
if ((ch >= 0x06f0) && (ch <= 0x06fe))
return (ch - 403);
if (ch == 0x10d3)
return 1388;
if (ch == 0x10d7)
return 1389;
if (ch == 0x10da)
return 1390;
if (ch == 0x10dd)
return 1391;
if (ch == 0x10e6)
return 1392;
if ((ch >= 0x1e00) && (ch <= 0x1e9b))
return (ch - 6287);
if ((ch >= 0x1ea0) && (ch <= 0x1ef9))
return (ch - 6291);
if ((ch >= 0x1f00) && (ch <= 0x1f07))
return (ch - 6297);
if ((ch >= 0x2000) && (ch <= 0x2027))
return (ch - 6545);
if ((ch >= 0x2030) && (ch <= 0x2046))
return (ch - 6553);
if ((ch >= 0x2048) && (ch <= 0x204d))
return (ch - 6554);
if (ch == 0x2070)
return 1716;
if ((ch >= 0x2074) && (ch <= 0x208f))
return (ch - 6591);
if ((ch >= 0x20a0) && (ch <= 0x20af))
return (ch - 6607);
if ((ch >= 0x2100) && (ch <= 0x213a))
return (ch - 6687);
if ((ch >= 0x2153) && (ch <= 0x2183))
return (ch - 6711);
if ((ch >= 0x2190) && (ch <= 0x21f3))
return (ch - 6723);
if ((ch >= 0x2200) && (ch <= 0x22f1))
return (ch - 6735);
if (ch == 0x2300)
return 2211;
if (ch == 0x2302)
return 2212;
if ((ch >= 0x2308) && (ch <= 0x230b))
return (ch - 6755);
if (ch == 0x2310)
return 2217;
if (ch == 0x2318)
return 2218;
if ((ch >= 0x231a) && (ch <= 0x231b))
return (ch - 6767);
if ((ch >= 0x2320) && (ch <= 0x2321))
return (ch - 6771);
if ((ch >= 0x2329) && (ch <= 0x232a))
return (ch - 6778);
if ((ch >= 0x239b) && (ch <= 0x23bd))
return (ch - 6890);
if (ch == 0x23ce)
return 2260;
if ((ch >= 0x2409) && (ch <= 0x240d))
return (ch - 6964);
if ((ch >= 0x2423) && (ch <= 0x2424))
return (ch - 6985);
if (ch == 0x2426)
return 2268;
if ((ch >= 0x2500) && (ch <= 0x2595))
return (ch - 7203);
if ((ch >= 0x25a0) && (ch <= 0x25f7))
return (ch - 7213);
if ((ch >= 0x2600) && (ch <= 0x2602))
return (ch - 7221);
if ((ch >= 0x2605) && (ch <= 0x260d))
return (ch - 7223);
if ((ch >= 0x2610) && (ch <= 0x2613))
return (ch - 7225);
if (ch == 0x2620)
return 2523;
if (ch == 0x2622)
return 2524;
if (ch == 0x2626)
return 2525;
if ((ch >= 0x2628) && (ch <= 0x262b))
return (ch - 7242);
if ((ch >= 0x262e) && (ch <= 0x2637))
return (ch - 7244);
if ((ch >= 0x2639) && (ch <= 0x2653))
return (ch - 7245);
if ((ch >= 0x2660) && (ch <= 0x2667))
return (ch - 7257);
if ((ch >= 0x2669) && (ch <= 0x266f))
return (ch - 7258);
if ((ch >= 0xfb00) && (ch <= 0xfb05))
return (ch - 61674);
if ((ch >= 0xfb50) && (ch <= 0xfbb1))
return (ch - 61748);
if ((ch >= 0xfbd3) && (ch <= 0xfbe9))
return (ch - 61781);
if ((ch >= 0xfbfc) && (ch <= 0xfbff))
return (ch - 61799);
if ((ch >= 0xfc5b) && (ch <= 0xfc63))
return (ch - 61890);
if (ch == 0xfc90)
return 2722;
if ((ch >= 0xfcf2) && (ch <= 0xfcf4))
return (ch - 62031);
if ((ch >= 0xfd3c) && (ch <= 0xfd3f))
return (ch - 62102);
if (ch == 0xfdf2)
return 2730;
if ((ch >= 0xfe50) && (ch <= 0xfe52))
return (ch - 62373);
if ((ch >= 0xfe54) && (ch <= 0xfe66))
return (ch - 62374);
if ((ch >= 0xfe68) && (ch <= 0xfe6b))
return (ch - 62375);
if ((ch >= 0xfe70) && (ch <= 0xfe72))
return (ch - 62379);
if (ch == 0xfe74)
return 2760;
if ((ch >= 0xfe76) && (ch <= 0xfefc))
return (ch - 62381);
if (ch == 0xfeff)
return 2896;
return 2898;
}
 
/* 0 0x00 '^@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 1 0x01 '^A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x81, /* 10000001 */
0xa5, /* 10100101 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 2 0x02 '^B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xdb, /* 11011011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 3 0x03 '^C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 4 0x04 '^D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 5 0x05 '^E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 6 0x06 '^F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 7 0x07 '^G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 8 0x08 '^H' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xe7, /* 11100111 */
0xc3, /* 11000011 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 9 0x09 '^I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x42, /* 01000010 */
0x42, /* 01000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 10 0x0a '^J' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0x99, /* 10011001 */
0xbd, /* 10111101 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0xc3, /* 11000011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 11 0x0b '^K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x1a, /* 00011010 */
0x32, /* 00110010 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 12 0x0c '^L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 13 0x0d '^M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x33, /* 00110011 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x70, /* 01110000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 14 0x0e '^N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x67, /* 01100111 */
0xe7, /* 11100111 */
0xe6, /* 11100110 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 15 0x0f '^O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xdb, /* 11011011 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0x3c, /* 00111100 */
0xdb, /* 11011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 16 0x10 '^P' */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0xf0, /* 11110000 */
0xf8, /* 11111000 */
0xfe, /* 11111110 */
0xf8, /* 11111000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 17 0x11 '^Q' */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0e, /* 00001110 */
0x1e, /* 00011110 */
0x3e, /* 00111110 */
0xfe, /* 11111110 */
0x3e, /* 00111110 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 18 0x12 '^R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 19 0x13 '^S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 20 0x14 '^T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7b, /* 01111011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 21 0x15 '^U' */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 22 0x16 '^V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 23 0x17 '^W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 24 0x18 '^X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 25 0x19 '^Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 26 0x1a '^Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 27 0x1b '^[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xfe, /* 11111110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 28 0x1c '^\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 29 0x1d '^]' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x28, /* 00101000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x28, /* 00101000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 30 0x1e '^^' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 31 0x1f '^_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 32 0x20 ' ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 33 0x21 '!' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 34 0x22 '"' */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x24, /* 00100100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 35 0x23 '#' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 36 0x24 '$' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x86, /* 10000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 37 0x25 '%' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 38 0x26 '&' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 39 0x27 ''' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 40 0x28 '(' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 41 0x29 ')' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 42 0x2a '*' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0xff, /* 11111111 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 43 0x2b '+' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 44 0x2c ',' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 45 0x2d '-' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 46 0x2e '.' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 47 0x2f '/' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 48 0x30 '0' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 49 0x31 '1' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x38, /* 00111000 */
0x78, /* 01111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 50 0x32 '2' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 51 0x33 '3' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x3c, /* 00111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 52 0x34 '4' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x1c, /* 00011100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 53 0x35 '5' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 54 0x36 '6' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 55 0x37 '7' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 56 0x38 '8' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 57 0x39 '9' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 58 0x3a ':' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 59 0x3b ';' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 60 0x3c '<' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 61 0x3d '=' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 62 0x3e '>' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 63 0x3f '?' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 64 0x40 '@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xdc, /* 11011100 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 65 0x41 'A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 66 0x42 'B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 67 0x43 'C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 68 0x44 'D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 69 0x45 'E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 70 0x46 'F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 71 0x47 'G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xde, /* 11011110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x66, /* 01100110 */
0x3a, /* 00111010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 72 0x48 'H' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 73 0x49 'I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 74 0x4a 'J' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 75 0x4b 'K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe6, /* 11100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 76 0x4c 'L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 77 0x4d 'M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xee, /* 11101110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 78 0x4e 'N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 79 0x4f 'O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 80 0x50 'P' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 81 0x51 'Q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xde, /* 11011110 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 82 0x52 'R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 83 0x53 'S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 84 0x54 'T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x5a, /* 01011010 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 85 0x55 'U' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 86 0x56 'V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 87 0x57 'W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0xee, /* 11101110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 88 0x58 'X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 89 0x59 'Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 90 0x5a 'Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 91 0x5b '[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 92 0x5c '\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0x70, /* 01110000 */
0x38, /* 00111000 */
0x1c, /* 00011100 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 93 0x5d ']' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 94 0x5e '^' */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 95 0x5f '_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 96 0x60 '`' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 97 0x61 'a' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 98 0x62 'b' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 99 0x63 'c' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 100 0x64 'd' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 101 0x65 'e' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 102 0x66 'f' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x36, /* 00110110 */
0x32, /* 00110010 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 103 0x67 'g' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 104 0x68 'h' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x6c, /* 01101100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 105 0x69 'i' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 106 0x6a 'j' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
 
/* 107 0x6b 'k' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 108 0x6c 'l' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 109 0x6d 'm' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 110 0x6e 'n' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 111 0x6f 'o' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 112 0x70 'p' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
 
/* 113 0x71 'q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
 
/* 114 0x72 'r' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 115 0x73 's' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 116 0x74 't' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0xfc, /* 11111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x36, /* 00110110 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 117 0x75 'u' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 118 0x76 'v' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 119 0x77 'w' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 120 0x78 'x' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 121 0x79 'y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
 
/* 122 0x7a 'z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 123 0x7b '{' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 124 0x7c '|' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 125 0x7d '}' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 126 0x7e '~' */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 127 0x7f '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 128 0x80 '€' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 129 0x81 '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 130 0x82 '‚' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 131 0x83 'ƒ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 132 0x84 '„' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 133 0x85 '…' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 134 0x86 '†' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 135 0x87 '‡' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 136 0x88 'ˆ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 137 0x89 '‰' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 138 0x8a 'Š' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 139 0x8b '‹' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 140 0x8c 'Œ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 141 0x8d '' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 142 0x8e 'Ž' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 143 0x8f '' */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 144 0x90 '' */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 145 0x91 '‘' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x6e, /* 01101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 146 0x92 '’' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3e, /* 00111110 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xce, /* 11001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 147 0x93 '“' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 148 0x94 '”' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 149 0x95 '•' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 150 0x96 '–' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 151 0x97 '—' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 152 0x98 '˜' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 153 0x99 '™' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 154 0x9a 'š' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 155 0x9b '›' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 156 0x9c 'œ' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x64, /* 01100100 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xe6, /* 11100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 157 0x9d '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 158 0x9e 'ž' */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xf8, /* 11111000 */
0xc4, /* 11000100 */
0xcc, /* 11001100 */
0xde, /* 11011110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 159 0x9f 'Ÿ' */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 160 0xa0 ' ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 161 0xa1 '¡' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 162 0xa2 '¢' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 163 0xa3 '£' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 164 0xa4 '¤' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 165 0xa5 '¥' */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 166 0xa6 '¦' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 167 0xa7 '§' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 168 0xa8 '¨' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 169 0xa9 '©' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 170 0xaa 'ª' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 171 0xab '«' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xdc, /* 11011100 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 172 0xac '¬' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x66, /* 01100110 */
0xce, /* 11001110 */
0x9a, /* 10011010 */
0x3f, /* 00111111 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 173 0xad '­' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 174 0xae '®' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 175 0xaf '¯' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 176 0xb0 '°' */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
 
/* 177 0xb1 '±' */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
 
/* 178 0xb2 '²' */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
 
/* 179 0xb3 '³' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 180 0xb4 '´' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 181 0xb5 'µ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 182 0xb6 '¶' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 183 0xb7 '·' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 184 0xb8 '¸' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 185 0xb9 '¹' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 186 0xba 'º' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 187 0xbb '»' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 188 0xbc '¼' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 189 0xbd '½' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 190 0xbe '¾' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 191 0xbf '¿' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 192 0xc0 'À' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 193 0xc1 'Á' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 194 0xc2 'Â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 195 0xc3 'Ã' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 196 0xc4 'Ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 197 0xc5 'Å' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 198 0xc6 'Æ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 199 0xc7 'Ç' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 200 0xc8 'È' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 201 0xc9 'É' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 202 0xca 'Ê' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 203 0xcb 'Ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 204 0xcc 'Ì' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 205 0xcd 'Í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 206 0xce 'Î' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 207 0xcf 'Ï' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 208 0xd0 'Ð' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 209 0xd1 'Ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 210 0xd2 'Ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 211 0xd3 'Ó' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 212 0xd4 'Ô' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 213 0xd5 'Õ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 214 0xd6 'Ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 215 0xd7 '×' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 216 0xd8 'Ø' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 217 0xd9 'Ù' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 218 0xda 'Ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 219 0xdb 'Û' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 220 0xdc 'Ü' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 221 0xdd 'Ý' */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
 
/* 222 0xde 'Þ' */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
 
/* 223 0xdf 'ß' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 224 0xe0 'à' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 225 0xe1 'á' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xd8, /* 11011000 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 226 0xe2 'â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 227 0xe3 'ã' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 228 0xe4 'ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 229 0xe5 'å' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 230 0xe6 'æ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
 
/* 231 0xe7 'ç' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 232 0xe8 'è' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 233 0xe9 'é' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 234 0xea 'ê' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xee, /* 11101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 235 0xeb 'ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x3e, /* 00111110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 236 0xec 'ì' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 237 0xed 'í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x03, /* 00000011 */
0x06, /* 00000110 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xf3, /* 11110011 */
0x7e, /* 01111110 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 238 0xee 'î' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 239 0xef 'ï' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 240 0xf0 'ð' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 241 0xf1 'ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 242 0xf2 'ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 243 0xf3 'ó' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 244 0xf4 'ô' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 245 0xf5 'õ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 246 0xf6 'ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 247 0xf7 '÷' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 248 0xf8 'ø' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 249 0xf9 'ù' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 250 0xfa 'ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 251 0xfb 'û' */
0x00, /* 00000000 */
0x0f, /* 00001111 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xec, /* 11101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3c, /* 00111100 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 252 0xfc 'ü' */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 253 0xfd 'ý' */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x32, /* 00110010 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 254 0xfe 'þ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 255 0xff 'ÿ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0xc6, 0x00, 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, 0x00, 0x00},
{0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa1, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x44, 0xba, 0xb2, 0xaa, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x30, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x30, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x3c, 0x42, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7a, 0xc4, 0xce, 0xce, 0xd6, 0xd6, 0xe6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x66, 0xec, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0x1c, 0x3c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xc4, 0xce, 0xd6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x7c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x0c, 0x18, 0x0e, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x3e, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x10, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xff, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7e, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x3c, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x3c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x30, 0x1c, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf7, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7b, 0x7b, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0xee, 0x66, 0x66, 0x66, 0x66, 0x66, 0xf6, 0x06, 0x66, 0x3c, 0x00},
{0x08, 0x1c, 0x22, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x0e, 0x1b, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x30, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x66, 0x66, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x36, 0x36, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x78, 0xe0, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x1e, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x60, 0xc0, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6e, 0xd8, 0xd8, 0xd8, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd6, 0xd6, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x18, 0x0c, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0xfc, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x30, 0x60, 0x38, 0x00},
{0x10, 0x38, 0x44, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xb3, 0xb3, 0x33, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x64, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x62, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xe6, 0xe6, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xe0, 0xe0, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x06, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x03, 0x3e, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x7e, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xb6, 0xb3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x4c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x4c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x18, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xfe, 0xcc, 0x8c, 0x2c, 0x3c, 0x2c, 0x0c, 0x8c, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc2, 0xc0, 0x78, 0xc0, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x32, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00},
{0x00, 0x03, 0x3e, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x38, 0x6c, 0x38, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x6d, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc8, 0x38, 0x70, 0xd0, 0x38, 0x38, 0x6c, 0x64, 0xc6, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0xec, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x73, 0xdf, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x03, 0x03, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xdf, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x03, 0x03, 0x03, 0x00},
{0x00, 0x00, 0x7e, 0xb3, 0xb3, 0x33, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x6c, 0xe6, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x38, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x0c, 0x38, 0x60, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x0c, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x7e, 0xfe, 0x9a, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00},
{0x03, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0x6c, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0xb3, 0xb3, 0x33, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0xf0, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x7e, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0xfc, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x7c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x78, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x7c, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x7e, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x60, 0x60, 0x78, 0x0c, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x60, 0x78, 0x0c, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x18, 0x4c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x70, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x1b, 0x0e, 0x04, 0xf7, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf5, 0xda, 0xd8, 0xdf, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3d, 0x1a, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xcb, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf3, 0x63, 0x60, 0x67, 0x63, 0x63, 0x63, 0x67, 0x6f, 0xff, 0x03, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0xe3, 0x63, 0x60, 0x67, 0x63, 0x63, 0x63, 0x63, 0x63, 0xf3, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xf8, 0xff, 0xfb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xb7, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x33, 0x1e, 0x00},
{0x6c, 0x38, 0x10, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x28, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x78, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x30, 0x30, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xdf, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x3e, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x10, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0x0c, 0x18, 0x30, 0x7c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x1b, 0x0e, 0x04, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xf7, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0xd8, 0xd8, 0xdf, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xdb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x70, 0x60, 0x60, 0x60, 0x60, 0xe0, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x38, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x38, 0x6c, 0x38, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7a, 0xc4, 0xce, 0xce, 0xd6, 0xe6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7a, 0xc4, 0xce, 0xd6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x3c, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x1c, 0x74, 0x06, 0x06, 0x06, 0x06, 0x1c, 0xf0, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0e, 0x3c, 0x06, 0x06, 0x1c, 0xf0, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfc, 0x06, 0x0c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc0, 0xfc, 0x06, 0x0c, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x7c, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x3c, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x5c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xdc, 0xe6, 0x7c, 0x80, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0d, 0x06, 0x00},
{0x00, 0x00, 0x06, 0x0d, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6c, 0x8e, 0x16, 0x26, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xcd, 0x0d, 0x38, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xdc, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x06, 0x06, 0x1f, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x46, 0x6c, 0x2c, 0x2c, 0x38, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x64, 0x28, 0x38, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x6c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x7b, 0xde, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x78, 0x58, 0x3e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x7f, 0x63, 0x66, 0x6c, 0x7e, 0x63, 0xf3, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xd8, 0xd8, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x6c, 0x0c, 0x0d, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xfc, 0xc0, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x98, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x98, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x3b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x06, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xcb, 0xfe, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x7e, 0xc7, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x76, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x7e, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7e, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcc, 0x6c, 0x3c, 0x3c, 0x6c, 0xcc, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x1c, 0x18, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0x70, 0x30, 0xfc, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xdb, 0xdb, 0xde, 0xde, 0xdb, 0x6b, 0x03, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xdb, 0xdd, 0x6f, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x60, 0x60, 0xf6, 0x6d, 0x6c, 0x66, 0x63, 0x6b, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x26, 0x6d, 0x6c, 0xfc, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x3c, 0x0c, 0x2c, 0x18, 0x00},
{0x00, 0x00, 0x20, 0x60, 0x60, 0xf6, 0x6d, 0x6c, 0x6c, 0x6e, 0x6d, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xc0, 0xfe, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x03, 0x0e, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6d, 0x6c, 0x66, 0x63, 0x6b, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6f, 0x6b, 0x63, 0x66, 0x6c, 0x6d, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0x7c, 0x6c, 0x28, 0xc6, 0xd6, 0x7c, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xf0, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xf0, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xb0, 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0xd8, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0xd8, 0x68, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xd8, 0xd8, 0xf0, 0xd8, 0xd8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xd6, 0x7c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0x78, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xc0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x70, 0xc0, 0x70, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x70, 0x18, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x20, 0x70, 0x70, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xd8, 0xd8, 0x70, 0x70, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x34, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00},
{0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3e, 0x32, 0x30, 0x34, 0x3c, 0x34, 0x30, 0x30, 0x32, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x82, 0x44, 0x7c, 0x44, 0x00, 0x82, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x92, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x46, 0x6c, 0x2c, 0x2c, 0x38, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x30, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x46, 0x7c, 0x18, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x20, 0x30, 0x10, 0x38, 0x38, 0x6c, 0x64, 0xc6, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x66, 0x6c, 0x3c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x3c, 0x30, 0x60, 0x3c, 0x60, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x46, 0x2c, 0x2c, 0x18, 0x30, 0x68, 0x68, 0xc4, 0xc2, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x6c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x36, 0x1e, 0xc6, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc2, 0x65, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x21, 0x32, 0x12, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc2, 0x65, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa6, 0x2c, 0x38, 0x68, 0xca, 0xc4, 0x0c, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0x60, 0x3c, 0x06, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x32, 0x30, 0x30, 0x3c, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00},
{0x00, 0x60, 0x30, 0x30, 0x60, 0x63, 0xff, 0xc6, 0x06, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x60, 0x60, 0xfe, 0xfe, 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xac, 0x26, 0x26, 0x0b, 0x0b, 0x1b, 0x1b, 0x1b, 0x1b, 0x03, 0x02, 0x04, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x28, 0x4c, 0x14, 0x24, 0x06, 0x02, 0x02, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6d, 0x03, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6d, 0x03, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xd6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x76, 0x9c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0xd6, 0x66, 0x06, 0x06, 0x66, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x3c, 0x60, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x26, 0x1c, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0x68, 0x38, 0x30, 0x38, 0x38, 0x4c, 0x4c, 0x86, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xba, 0x30, 0x38, 0x28, 0x4c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xc0, 0xcc, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xdc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x7e, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1c, 0x18, 0x7e, 0x58, 0x18, 0x18, 0x18, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa6, 0x2c, 0x38, 0x68, 0xca, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0x60, 0x3c, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x30, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xb2, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x03, 0x06, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xf8, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xd8, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xb2, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x18, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x38, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xc6, 0x82, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfe, 0x06, 0x02, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xff, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xb0, 0xb0, 0x30, 0x3c, 0x36, 0x36, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x3e, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x9c, 0xb6, 0xb6, 0xb6, 0xf6, 0xb6, 0xb6, 0xb6, 0xb6, 0x9c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xcc, 0xcc, 0xcc, 0x7c, 0x6c, 0x6c, 0x6c, 0x6c, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x7c, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xc6, 0x82, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfe, 0x06, 0x02, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xff, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb0, 0x30, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb6, 0xb6, 0xf6, 0xb6, 0xb6, 0x9c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xcc, 0xcc, 0x7c, 0x6c, 0x6c, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xf8, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x38, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0xfc, 0xb4, 0x30, 0x3c, 0x36, 0x36, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x30, 0xfc, 0xb4, 0x30, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xce, 0xdb, 0xd9, 0xd8, 0xfe, 0xd8, 0xd8, 0xd9, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xdb, 0xd8, 0xfe, 0xd8, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0x6c, 0xfe, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x7c, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x88, 0x8c, 0x9c, 0x96, 0xf6, 0xb6, 0xbf, 0xab, 0xeb, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x9c, 0xf6, 0xbe, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x6c, 0x6c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x6c, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xa3, 0xb2, 0x96, 0xfc, 0x9c, 0xbe, 0xaa, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xa3, 0x96, 0xfe, 0xab, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0x06, 0x06, 0x7c, 0x06, 0x06, 0x06, 0x7c, 0xc0, 0x7c, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0x86, 0x06, 0x7c, 0x06, 0x06, 0x7c, 0xc0, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x96, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x96, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc2, 0xc6, 0xc6, 0xc4, 0xcc, 0x6c, 0x68, 0x78, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x64, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xc2, 0xc6, 0xc4, 0xc4, 0x6c, 0x68, 0x78, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xc2, 0xc6, 0x64, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6f, 0x03, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6f, 0x03, 0x06, 0x1c, 0x00},
{0x00, 0x10, 0x7c, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xc6, 0xc6, 0xc6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00},
{0x04, 0x7c, 0x40, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x40, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x54, 0x00, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x54, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x60, 0x3c, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0x78, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x3c, 0x0f, 0x18, 0x18, 0xf0, 0x3c, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x7c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0xc3, 0x00, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x50, 0x46, 0x00, 0x82, 0x41, 0x00, 0x62, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x6e, 0x64, 0x7a, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x6e, 0x64, 0x7a, 0x60, 0x60, 0xf0, 0x00},
{0x02, 0x06, 0xfe, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x06, 0xfe, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0xf8, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0xf8, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xf6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x78, 0x6c, 0x66, 0xf6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xdc, 0xf8, 0xdc, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xdc, 0xf8, 0xdc, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0xf6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0xf0, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf3, 0xb3, 0xb3, 0x36, 0x3c, 0x3c, 0x36, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xb6, 0xbc, 0x3c, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xdf, 0xdb, 0xd9, 0xd8, 0xf8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xdb, 0xd9, 0xf8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xd8, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x0b, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xdb, 0x03, 0x0b, 0x06, 0x00},
{0x00, 0x00, 0x7c, 0xc2, 0xcc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc2, 0xcc, 0xd6, 0xd6, 0xcc, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0c, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0c, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0x7e, 0x16, 0x16, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0x7e, 0x16, 0x16, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0xb3, 0xb3, 0x7f, 0x30, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xb3, 0x7f, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0xb3, 0xb3, 0x7f, 0x30, 0x30, 0x30, 0x33, 0x1e, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xb3, 0x7f, 0x30, 0x30, 0x33, 0x1e, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0e, 0x0c, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0e, 0x0c, 0x08, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x3e, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x3e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x7c, 0xcd, 0xcd, 0xcd, 0xcd, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcd, 0xcd, 0xcd, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x8c, 0x0c, 0x38, 0x0d, 0x0d, 0x0d, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x0c, 0x39, 0x0d, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0xcd, 0xcd, 0xcd, 0xcd, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xfd, 0xcd, 0xcd, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xce, 0xc6, 0xc6, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x1b, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x64, 0x94, 0xba, 0x52, 0x4c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x7b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x7e, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0c, 0xd8, 0xfe, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xcf, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xf6, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x7f, 0x24, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0xf0, 0x3c, 0x0e, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x6c, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x30, 0x60, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcf, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x7c, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x60, 0x60, 0x60, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x6c, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x16, 0x16, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x76, 0x1e, 0x0e, 0x0c, 0xd8, 0xfe, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x30, 0x18, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x63, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xfe, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd0, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0x16, 0xd6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x3c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x0c, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xcf, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xca, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x60, 0x38, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x1c, 0x0c, 0x18, 0x3c, 0x64, 0x66, 0x62, 0x63, 0x3d, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x0e, 0x18, 0x30, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0f, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x76, 0x1c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0xdc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xfe, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0x16, 0x16, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcc, 0xcc, 0xcc, 0xcc, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x6c},
{0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x38, 0x10, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x60, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0c, 0x00},
{0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x74, 0xd6, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x18, 0x30, 0x00},
{0x0c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1b, 0x36, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x44, 0xaa, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x0a, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x50, 0xe0, 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, 0x0c, 0x0c, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x6c, 0xd8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x08, 0x30},
{0x60, 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0xa0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x10, 0x10},
{0x18, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x00},
{0x48, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x33, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x60, 0x66, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18},
{0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x18, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x66, 0x76, 0xdc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x36, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x66, 0x66, 0x66, 0x2c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x4c, 0xcc, 0xcc, 0xec, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x46, 0xc6, 0xc6, 0xe6, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x6c, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x34, 0x18, 0x0c, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x66, 0x64, 0x6c, 0x6e, 0x60, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xf6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0xc6, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x3c, 0x40, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x20, 0x1c, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x28, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x30, 0x4e, 0x49, 0x39, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x24, 0x00},
{0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x12, 0xca, 0x2c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00},
{0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00},
{0x0a, 0x2a, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x7e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x10, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x0c, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x70, 0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0xfc, 0xf8, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4a, 0xfe, 0xf4, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x20, 0x40, 0x30, 0x10, 0x20, 0x42, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x2c, 0x44, 0x42, 0x82, 0x82, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xf8, 0x78, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xc6, 0xc6, 0x6c, 0x28, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x28, 0x6c, 0xc6, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xf8, 0x88, 0xf8, 0x78, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x91, 0x92, 0x64, 0x08, 0x10, 0x26, 0x49, 0x89, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0xfe, 0x7c, 0x38, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x28, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x06, 0x28, 0x5e, 0x00, 0x00, 0x00},
{0x00, 0x07, 0x08, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x14, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x04, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x54, 0x33, 0x24, 0x40, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x04, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00},
{0x06, 0x08, 0x06, 0x08, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x08, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x94, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x88, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x94, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x08, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x1c, 0x6a, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x14, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x12, 0x04, 0x18, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x15, 0x88, 0x88, 0x8a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x88, 0x90, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x00, 0x0a, 0x00, 0x01, 0x15, 0x88, 0x88, 0x90, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x90, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x2a, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x00, 0x50, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x20, 0x40, 0x3e, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x05, 0x0b, 0x48, 0x84, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x29, 0x01, 0x19, 0x21, 0x19, 0xa1, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x05, 0x0b, 0x48, 0x84, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x44, 0x09, 0xa2, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x08, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x02, 0x2a, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x14, 0x00, 0x08, 0x00},
{0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x08, 0x14, 0x08, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x38, 0x40, 0x38, 0x40, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x40, 0x38, 0x40, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x12, 0x2c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0x47, 0x88, 0x08, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x50, 0x20, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x08, 0x00, 0x08},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x14, 0x00, 0x08},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x80, 0x60, 0x80, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x40, 0x43, 0x55, 0x7e, 0x80, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x2a, 0x20, 0x26, 0x2a, 0x7c, 0x80, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0e, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x14, 0x08, 0x14, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x2c, 0x10, 0x28, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x15, 0x8a, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x5a, 0xa5, 0x66, 0x5b, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x5a, 0x66, 0xa5, 0x5a, 0x00},
{0x00, 0x00, 0x18, 0x66, 0x42, 0x42, 0x81, 0x99, 0x99, 0x81, 0x42, 0x42, 0x66, 0x18, 0x00, 0x00},
{0x08, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x26, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x8a, 0x90, 0x60},
{0x32, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x0c, 0x04, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x30, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x54, 0xaa, 0x92, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x82, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x14, 0x08},
{0x08, 0x14, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x10, 0x10, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x70, 0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0xfc, 0xf8, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4a, 0xfe, 0xf4, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4e, 0xf0, 0xfe, 0x7c, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x38, 0x2c, 0x44, 0x42, 0x82, 0x92, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x60, 0x7e, 0x3c, 0x30, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xc6, 0xc6, 0x6c, 0x28, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x28, 0x6c, 0xc6, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xf8, 0x88, 0xf8, 0x78, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x88, 0x88, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x54, 0x54, 0x54, 0x54, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x4c, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xaa, 0xaa, 0xaa, 0x82, 0x82, 0x40, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x82, 0x82, 0x44, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x82, 0x82, 0x40, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0x38},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x38, 0x6c, 0x38},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0c, 0xec, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x7c, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x30, 0x30, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x60, 0x0c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x10, 0x38, 0x6c, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x76, 0xdc, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x38, 0x6c, 0x64, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x60, 0x30, 0xe0, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x76, 0xdc, 0x00},
{0x0c, 0x18, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0c, 0xec, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x60, 0x6c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x60, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x44, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x44, 0x38, 0x10, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x18, 0x18, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x16, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x08, 0x1c, 0x36, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x6c, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x6c, 0x6c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x72, 0x9c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x76, 0xdc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x18, 0x18, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x18, 0x0c, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x38, 0x6c, 0x64, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x16, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x16, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x68, 0x1c, 0x36, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x68, 0x1c, 0x36, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x28, 0x54, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x0c, 0x18, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x54, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x54, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x72, 0x9c, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x72, 0x9c, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x76, 0x88, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x26, 0x70, 0xd8, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc4, 0x6e, 0x11, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x64, 0x0e, 0x1b, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x76, 0x88, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x26, 0x70, 0xd8, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc4, 0x6e, 0x11, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x64, 0x0e, 0x1b, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x28, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x18, 0x33, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x33, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x1b, 0x33, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x1b, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x68, 0xb3, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x68, 0xb3, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x18, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x33, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x33, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x1b, 0x33, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x1b, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x68, 0xb3, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x68, 0xb3, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x0c, 0x18, 0xf6, 0x06, 0x00},
{0x38, 0x0c, 0x18, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x3a, 0x5c, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x6c, 0xc6, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xcc, 0x66, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x66, 0xcc, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc6, 0x6c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x34, 0x58, 0x0c, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x34, 0x58, 0x30, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xfe, 0x00, 0xa4, 0xaa, 0xea, 0xea, 0xa6, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xa4, 0xea, 0xaa, 0xaa, 0xa6, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x8a, 0xce, 0x8e, 0xea, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x8e, 0xca, 0x8a, 0xea, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xca, 0x2e, 0x4a, 0x2a, 0xca, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xaa, 0xae, 0xea, 0x2a, 0x2a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x6a, 0x8e, 0xca, 0xaa, 0x4a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x38, 0x20, 0x30, 0x20, 0x20, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x30, 0x28, 0x30, 0x20, 0x20, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x4a, 0x4e, 0x4a, 0x4a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x28, 0x28, 0x38, 0x28, 0x28, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0xa2, 0xa2, 0xe2, 0xea, 0xa4, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0x08, 0x08, 0x08, 0x28, 0x10, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x80, 0x80, 0x80, 0xf0, 0x28, 0x30, 0x28, 0x0a, 0x0e, 0x0e, 0x0a, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xc0, 0xa0, 0xc0, 0xa0, 0x20, 0x20, 0x38, 0x0a, 0x0e, 0x0e, 0x0a, 0x00, 0xfe, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x9c, 0xd2, 0xbc, 0x92, 0x9c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x00, 0xcc, 0xcc, 0xcc, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x6b, 0x6b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x92, 0x44, 0x28, 0x92, 0x28, 0x44, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xc3, 0xdb, 0x1b, 0x1e, 0x1c, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x7c, 0x00, 0x00},
{0x7c, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x28, 0x00, 0x00, 0x44, 0xee, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7b, 0xcf, 0xcf, 0x1b, 0x33, 0x33, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xde, 0xf3, 0xf3, 0xc6, 0xcc, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x06, 0x06, 0x0c, 0x0c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xdb, 0xdb, 0xdb, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3e, 0x72, 0xf2, 0xf2, 0xf2, 0x72, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x9c, 0x9e, 0x9e, 0x9e, 0x9c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x38, 0x78, 0xd8, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xf8, 0xc0, 0xf0, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x78, 0xc0, 0xf0, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xf8, 0xd8, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 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, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xb0, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0xd8, 0xfc, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc0, 0xf0, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xf0, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd8, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0xf0, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 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, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcf, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x04, 0x7c, 0xce, 0xc8, 0xc8, 0xd0, 0xd0, 0xd0, 0xe0, 0xe6, 0x7c, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xd6, 0xd8, 0xd8, 0xd8, 0xde, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xc0, 0xc0, 0xc0, 0xf0, 0xcd, 0xce, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0xf8, 0x60, 0xf8, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0xd6, 0xde, 0xd6, 0xd6, 0xf6, 0xd6, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x76, 0xff, 0x76, 0x6e, 0xff, 0x6e, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xf8, 0xe0, 0xf3, 0xd6, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x81, 0x81, 0x81, 0x5a, 0xff, 0x5a, 0xff, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf2, 0x8a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa2, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x3e, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x60, 0xfc, 0x60, 0xf8, 0x60, 0x60, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0xfe, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x1e, 0x78, 0x1e, 0x78, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x7c, 0xb6, 0x36, 0x33, 0x33, 0x33, 0x63, 0x66, 0xf6, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd0, 0xd2, 0xd6, 0x7c, 0x18, 0x30, 0x6e, 0xd8, 0x98, 0x18, 0x0e, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd0, 0xd2, 0xd6, 0x7c, 0x18, 0x30, 0x6e, 0xd8, 0x8c, 0x06, 0x1c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x62, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x62, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4e, 0xb9, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x7c, 0xda, 0xd8, 0xd8, 0xda, 0x7c, 0x19, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x18, 0x30, 0x6e, 0xdb, 0x9b, 0x1b, 0x0e, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x18, 0x30, 0x7b, 0xdb, 0x9b, 0x1b, 0x0d, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc2, 0xc0, 0x78, 0xc0, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x26, 0x3e, 0x26, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0xb9, 0x58, 0x1a, 0x1e, 0x1a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x66, 0x46, 0x87, 0x8c, 0x8c, 0x7c, 0x98, 0x98, 0x70, 0x00},
{0x00, 0x00, 0x52, 0xb5, 0x15, 0x16, 0x2c, 0x34, 0x68, 0xa9, 0xaa, 0x4c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x48, 0xb0, 0x80, 0x48, 0x7c, 0x66, 0x26, 0x26, 0xa6, 0x46, 0x06, 0x34, 0x48, 0x00},
{0x00, 0x00, 0xe2, 0xa2, 0xa2, 0xa2, 0xbe, 0xa2, 0xa2, 0xa2, 0xa2, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x36, 0x3b, 0x3b, 0x33, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x1e, 0x18, 0x76, 0x3b, 0x3b, 0x33, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x33, 0x4e, 0x06, 0x06, 0x0c, 0x0c, 0x1f, 0x6c, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x71, 0x8e, 0x04, 0x0c, 0x06, 0x03, 0x63, 0xc3, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x46, 0x49, 0x39, 0x1e, 0x18, 0x30, 0x70, 0xb1, 0xba, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x19, 0x31, 0x32, 0x64, 0x68, 0x70, 0xe1, 0x66, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xff, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe2, 0xa2, 0xb2, 0xb2, 0xaa, 0xaa, 0xa6, 0xa6, 0xa2, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcf, 0xed, 0xff, 0xfc, 0xdf, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0xb9, 0xa5, 0xa5, 0xb9, 0xa1, 0xa1, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x40, 0x8e, 0x93, 0xa3, 0x63, 0x4b, 0x6a, 0xa4, 0xb0, 0xb0, 0x60, 0x00},
{0x00, 0x00, 0xfc, 0xa2, 0xa2, 0xa2, 0xa2, 0xbc, 0xa0, 0xa0, 0xa0, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xaa, 0xa6, 0x7e, 0x01, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x4d, 0x4d, 0x19, 0x1e, 0x1c, 0x34, 0x34, 0xb5, 0x62, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x58, 0xa6, 0xa3, 0x6c, 0xb8, 0x26, 0x26, 0x26, 0xa7, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0xa2, 0xa2, 0xa2, 0xa2, 0xbc, 0xb0, 0xa8, 0xa4, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x6d, 0x67, 0x66, 0xee, 0x08, 0x00, 0x00, 0x00},
{0x30, 0x0c, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xd8, 0xdc, 0xdc, 0xe6, 0xe6, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x71, 0xdb, 0x35, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x52, 0x5a, 0x52, 0x5f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf1, 0x5b, 0x55, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x18, 0xce, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xe6, 0x6c, 0x38, 0x50, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x0a, 0x14, 0x14, 0x28, 0x28, 0x50, 0x50, 0xa0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x9c, 0x30, 0xfe, 0x0c, 0x18, 0x38, 0x0c, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0x6c, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x26, 0x03, 0x13, 0x0c, 0x13, 0x03, 0x03, 0x66, 0x98, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x2d, 0x2d, 0x1a, 0x1e, 0x1b, 0x31, 0x31, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x6b, 0xc8, 0xcc, 0xc6, 0xc6, 0xcc, 0xc0, 0x63, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xe7, 0xff, 0xe0, 0x67, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x26, 0x44, 0xf8, 0xc0, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4c, 0x52, 0x3c, 0x10, 0x3c, 0x60, 0xc0, 0xc3, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x73, 0xce, 0x18, 0x3a, 0x5c, 0x18, 0x30, 0x30, 0xb0, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x2c, 0x3c, 0x2c, 0x8c, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x12, 0x12, 0x12, 0x16, 0x36, 0x3e, 0x3a, 0x5a, 0x52, 0x91, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x26, 0x46, 0xc6, 0xc4, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0xc6, 0xe7, 0x7a, 0x38, 0x5c, 0xce, 0xe7, 0x63, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xfc, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x7e, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x78, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x7e, 0xf2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xfe, 0x7e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x38, 0x00, 0x78, 0x38, 0x38, 0x38, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xff, 0x83, 0x86, 0x82, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0xc6, 0xfc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0xc6, 0xfc, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x30, 0x70, 0xb2, 0xf6, 0x3c, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0xb0, 0x3c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0xc0, 0xe2, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb0, 0x3c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0x80, 0xe2, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0x30, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0xce, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x73, 0x23, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x65, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xce, 0xce, 0xce, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0x73, 0x73, 0x73, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x95, 0x95, 0x95, 0x65, 0x65, 0x65, 0x95, 0x95, 0x95, 0x95, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x23, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x05, 0x05, 0x00, 0x95, 0x95, 0x95, 0x95, 0x95, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x15, 0x15, 0x00, 0xb5, 0xb5, 0xb5, 0xb5, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0xdb, 0xdb, 0xce, 0xce, 0xce, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xdb, 0xdb, 0x73, 0x73, 0x73, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x05, 0x05, 0x00, 0x95, 0x95, 0x65, 0x65, 0x95, 0x95, 0x95, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xe6, 0xd6, 0xd6, 0xd6, 0xd6, 0xe6, 0xcc, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0x99, 0xbd, 0xdb, 0xdb, 0xbd, 0x99, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x06, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb0, 0x18, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x07, 0x0d, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0d, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0c, 0x18, 0xb0, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x62, 0xff, 0x64, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x26, 0xff, 0x46, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xce, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x73, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xff, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x36, 0xff, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xfc, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x3f, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x63, 0xff, 0x63, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xff, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x33, 0x63, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0xc6, 0x7f, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x3b, 0x6b, 0xfe, 0x68, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xdc, 0xd6, 0x7f, 0x16, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x5a, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x6e, 0xff, 0x76, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x60, 0x63, 0xff, 0xc6, 0x16, 0x1c, 0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x66, 0x36, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0xcc, 0xd8, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, 0xcc, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x3f, 0x1e, 0x0c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x0c, 0x3f, 0x1e, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x00, 0xf0, 0xe0, 0xb0, 0x18, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x98, 0xb0, 0xff, 0xb0, 0x98, 0x19, 0x0d, 0xff, 0x0d, 0x19, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x1e, 0x1c, 0x16, 0x03, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x38, 0x68, 0xc0, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1c, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x30, 0x60, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x2e, 0x3f, 0x24, 0x24, 0x24, 0x24, 0xfc, 0x74, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x60, 0xff, 0x60, 0x30, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x7e, 0xff, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0xff, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x00, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x00, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x7f, 0xc4, 0x7f, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x7e, 0xcb, 0x7e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xfe, 0x23, 0xfe, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xc0, 0x7f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x7c, 0xee, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0x03, 0xfe, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x7e, 0xc3, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x7c, 0xee, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb0, 0xd8, 0xec, 0xb6, 0x1b, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x07, 0x0d, 0x1b, 0x37, 0x6d, 0xd8, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x20, 0x30, 0xd8, 0x6d, 0x37, 0x1b, 0x0d, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x0c, 0x1b, 0xb6, 0xec, 0xd8, 0xb0, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x60, 0xff, 0x60, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x06, 0xff, 0x06, 0xfc, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x6a, 0xff, 0x65, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xa6, 0xff, 0x56, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xd5, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x66, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xab, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xb0, 0xff, 0xb0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0d, 0xff, 0x0d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x41, 0x81, 0x41, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x82, 0x81, 0x82, 0xfc, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44, 0xc6, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x7c, 0x00, 0x7c, 0x44, 0x7c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x7c, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x54, 0xd6, 0x54, 0x54, 0x54, 0xd6, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x54, 0xee, 0x44, 0xc6, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x54, 0xee, 0x44, 0xc6, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe8, 0xbc, 0x82, 0x81, 0x82, 0xbc, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x80, 0xbc, 0xb8, 0xac, 0x86, 0x83, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x01, 0x81, 0xc1, 0x61, 0x35, 0x1d, 0x3d, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xfe, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x06, 0x06, 0x3e, 0x66, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x7e, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xfe, 0x16, 0x16, 0x16, 0x7e, 0x16, 0x26, 0x26, 0x26, 0xfe, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x3e, 0x66, 0xcf, 0xdb, 0xdb, 0xf3, 0x66, 0x7c, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xc0, 0xfe, 0xc0, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x3e, 0x64, 0xc8, 0xc8, 0xfe, 0xc8, 0xd0, 0x70, 0x3e, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfe, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0x06, 0xfe, 0x06, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xf8, 0x1c, 0x16, 0x26, 0xfe, 0x26, 0x26, 0x4c, 0xf8, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0xfe, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe7, 0x00, 0x00},
{0x00, 0x00, 0xe7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xc1, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xff, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x06, 0x06, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe3, 0x33, 0x66, 0x36, 0xe6, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x33, 0x73, 0xb6, 0xf6, 0x36, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdb, 0xdb, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x16, 0x0c, 0x1c, 0x34, 0x62, 0xff, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x1a, 0x1c, 0x38, 0x58, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6e, 0x7c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x2a, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0xa8, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0x99, 0x99, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x33, 0x66, 0x66, 0x66, 0x7e, 0xe7, 0xe7, 0xe7, 0xe7, 0x7e, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x2a, 0x54, 0x54, 0x54, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x54, 0x54, 0x54, 0xa8, 0x00, 0x00},
{0x18, 0x34, 0x30, 0x30, 0x38, 0x35, 0x33, 0x37, 0x30, 0x30, 0x30, 0x30, 0xb0, 0x60, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0xfa, 0x5a, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0x5f, 0x5a, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0xfc, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x7e, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x76, 0xdc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xdb, 0xdb, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xdb, 0xdb, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x76, 0xdc, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0xfe, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0xfe, 0x20, 0xfe, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0x76, 0xdc, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0xdf, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0xfb, 0x00, 0x00, 0xfb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x28, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x10, 0x7c, 0x28, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x44, 0x7c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x26, 0x7c, 0xb4, 0x6c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x68, 0x54, 0x54, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x08, 0x10, 0x00, 0x10, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x08, 0x7e, 0x08, 0x10, 0x7e, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0xfe, 0x08, 0x10, 0xfe, 0x10, 0x20, 0xfe, 0x20, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1b, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xce, 0x7c, 0x10, 0x7c, 0xe6, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x76, 0xdc, 0x20, 0x20, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0x76, 0xdc, 0x80, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x38, 0xe8, 0x38, 0x1e, 0xf0, 0x38, 0x2e, 0x38, 0xe0, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xe8, 0x38, 0x0e, 0x38, 0xf0, 0x1e, 0x38, 0xe0, 0x38, 0x2e, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0xf2, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x9e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x06, 0x0c, 0x38, 0xe8, 0x38, 0x1c, 0x16, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0xd0, 0x70, 0x38, 0x2e, 0x38, 0x60, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x7e, 0xc8, 0xc8, 0xd0, 0xd0, 0x7e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0xfc, 0x16, 0x16, 0x26, 0x26, 0xfc, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x7e, 0xc8, 0xc8, 0xd0, 0xd0, 0x7e, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xfc, 0x16, 0x16, 0x26, 0x26, 0xfc, 0x40, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x08, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x92, 0xa2, 0xfa, 0xa2, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xba, 0xba, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xba, 0x92, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x54, 0x92, 0xfe, 0x92, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0xfe, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0xaa, 0x92, 0xaa, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x8a, 0x92, 0xa2, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xba, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xaa, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x54, 0xd6, 0xba, 0xd6, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0xba, 0x82, 0xba, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0xba, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0xfe, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x92, 0xba, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0xdf, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xa8, 0xa8, 0xa8, 0xa8, 0xaf, 0xa8, 0xa8, 0xa8, 0xa8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xdf, 0xd8, 0xdf, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc4, 0xc4, 0xff, 0xc8, 0xc8, 0xd0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc4, 0xc4, 0xff, 0xc8, 0xff, 0xd0, 0xd0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd9, 0xda, 0xda, 0xdf, 0xda, 0xda, 0xdc, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd9, 0xda, 0xdf, 0xda, 0xdf, 0xda, 0xdc, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0c, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x1e, 0x76, 0xc6, 0x76, 0x1e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xf0, 0xdc, 0xc6, 0xdc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x1e, 0x76, 0xc6, 0x76, 0x1e, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xf0, 0xdc, 0xc6, 0xdc, 0xf0, 0xc0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0xc6, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf0, 0xc8, 0xc4, 0xc4, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0b, 0x13, 0x23, 0x43, 0x83, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x38, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x92, 0x44, 0x28, 0x92, 0x28, 0x44, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0xc4, 0xa8, 0x90, 0xa8, 0xc4, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x46, 0x2a, 0x12, 0x2a, 0x46, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x60, 0xce, 0xd8, 0xd8, 0xce, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf8, 0x0c, 0xe6, 0x36, 0x36, 0xe6, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x54, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x64, 0xce, 0x64, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x4c, 0xe6, 0x4c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x54, 0xa8, 0x54, 0x2a, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xa8, 0x54, 0x2a, 0x15, 0x2a, 0x54, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00},
{0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf2, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x9e, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x0e, 0x1c, 0xf0, 0x1c, 0x16, 0xf2, 0x1c, 0x26, 0x22, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x88, 0xc8, 0x70, 0x1e, 0x70, 0xd0, 0x9e, 0x70, 0xe0, 0xa0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0xfe, 0xc8, 0xc8, 0xd0, 0xd0, 0xfe, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xfe, 0x16, 0x16, 0x26, 0x26, 0xfe, 0x40, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x08, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x0e, 0x1e, 0x76, 0xd6, 0x76, 0x1e, 0x26, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xc8, 0xf0, 0xdc, 0xd6, 0xdc, 0xf0, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x1e, 0x76, 0xd6, 0x76, 0x1e, 0x26, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xc8, 0xf0, 0xdc, 0xd6, 0xdc, 0xf0, 0xe0, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3d, 0x66, 0xc7, 0xcb, 0xd3, 0xe3, 0x66, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x42, 0xa5, 0x7e, 0x24, 0x24, 0x7e, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x54, 0x8a, 0xf6, 0x82, 0x54, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xfe, 0xfe, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00},
{0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x03, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x00, 0x00},
{0x00, 0xc0, 0x60, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0xc0, 0x00, 0x00},
{0x00, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3f, 0x00, 0x00},
{0x00, 0xfc, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xfc, 0x00, 0x00},
{0x00, 0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0},
{0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07},
{0x00, 0x00, 0xff, 0xc1, 0xc0, 0x60, 0x60, 0x60, 0x60, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x60, 0x60, 0x60, 0x60, 0xc0, 0xc1, 0xff, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x78, 0x78, 0x38, 0x38, 0x18, 0x18, 0x00, 0x00},
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03},
{0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x07, 0x05, 0x05, 0x05, 0x05, 0x25, 0x79, 0xc2, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xf8, 0xd8, 0xd8, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xf0, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xf8, 0x70, 0x20, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0xc0, 0xe0, 0xc0, 0xc0, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xc0, 0xc0, 0xc0, 0x70, 0x1e, 0x1b, 0x1e, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x98, 0xd8, 0xf8, 0xd8, 0xd8, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xfe, 0xc6, 0xc6, 0x60, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0e, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80},
{0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01},
{0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{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, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
{0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc},
{0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8},
{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0},
{0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0},
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
{0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f},
{0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44},
{0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa},
{0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77},
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
{0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0xba, 0xba, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x8a, 0xc6, 0xa2, 0x92, 0x8a, 0xc6, 0xa2, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xa2, 0xc6, 0x8a, 0x92, 0xa2, 0xc6, 0x8a, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x42, 0x84, 0x84, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x44, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x80, 0xc0, 0xa0, 0x90, 0x88, 0x84, 0x88, 0x90, 0xa0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x78, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x48, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x98, 0x86, 0x98, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x06, 0x0a, 0x12, 0x22, 0x42, 0x22, 0x12, 0x0a, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x78, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x48, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x32, 0xc2, 0x32, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x54, 0xba, 0xba, 0x54, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xbd, 0xbd, 0xbd, 0xbd, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x82, 0x82, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x28, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa5, 0xa5, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x72, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0x72, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x4e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x70, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0xbd, 0xc3, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xbd, 0xc3, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x30, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0xff, 0xff},
{0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff},
{0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0x80, 0x80},
{0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xff, 0xfd, 0xf9, 0xf1, 0xf1, 0xe1, 0xc1, 0x81, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x81, 0x83, 0x87, 0x8f, 0x8f, 0x9f, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x28, 0x28, 0x44, 0x44, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x74, 0x74, 0xf2, 0xf2, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x5c, 0x5c, 0x9e, 0x9e, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0x92, 0xf2, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0xf2, 0x92, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x9e, 0x92, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0x92, 0x9e, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4a, 0x89, 0x89, 0x89, 0xf9, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xf9, 0x89, 0x89, 0x89, 0x4a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x9f, 0x91, 0x91, 0x91, 0x52, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x52, 0x91, 0x91, 0x91, 0x9f, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x7c, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x7c, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0xfe, 0x7c, 0x38, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x28, 0xee, 0x44, 0x54, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x34, 0x1c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcd, 0xc7, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x92, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0xa5, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xa5, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x36, 0x1c, 0x18, 0x30, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x86, 0x8a, 0xba, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0xee, 0xba, 0xba, 0xee, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x82, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x82, 0xaa, 0x82, 0x44, 0x7c, 0x44, 0x38, 0x00, 0x44, 0xc6, 0x38, 0xc6, 0x44, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0xee, 0xfe, 0x92, 0xba, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xff, 0x18, 0x1e, 0x78, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x10, 0x10, 0x92, 0xfe, 0x92, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x72, 0xe0, 0xc4, 0xdf, 0xce, 0xca, 0xe0, 0x72, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x54, 0x28, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0x99, 0x99, 0x99, 0xbd, 0xff, 0xdb, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x85, 0xb1, 0xf9, 0xff, 0xdf, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0x81, 0x99, 0xa5, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xa5, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x28, 0xc6, 0x28, 0x54, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0x14, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x14, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x28, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x28, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x06, 0x0e, 0x1a, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x03, 0x03, 0x7b, 0xcf, 0xcf, 0xcf, 0x0f, 0x1b, 0x33, 0xff, 0x03, 0x03, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf0, 0x60, 0x6e, 0x73, 0x63, 0x63, 0x66, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0x54, 0x54, 0x7c, 0x54, 0x54, 0xd6, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0xdb, 0xdb, 0xdb, 0xdb, 0x7e, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0xa5, 0xa5, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc3, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7e, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xdb, 0xd8, 0x70, 0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1b, 0x7b, 0xdb, 0xdb, 0x73, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x94, 0x7c, 0x55, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x06, 0x0b, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x24, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x94, 0x7c, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x04, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x1f, 0x07, 0x8f, 0xdb, 0x73, 0x70, 0xd8, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x90, 0x50, 0x70, 0x68, 0x48, 0x48, 0x4e, 0x49, 0x09, 0x0e, 0x10, 0x20, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x2a, 0x7e, 0xaa, 0x00, 0x00, 0x2a, 0x7e, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x82, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x81, 0x81, 0x66, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x24, 0x3c, 0xe7, 0xa5, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x3c, 0x3e, 0x32, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x7f, 0x6f, 0x63, 0x63, 0x63, 0x63, 0xe3, 0xe7, 0xc7, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x63, 0xe7, 0xe7, 0xc6, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xcc, 0xde, 0xe6, 0xc4, 0xd8, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x40, 0x44, 0x5c, 0x74, 0x44, 0x44, 0x5c, 0x74, 0x44, 0x04, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x46, 0x5c, 0x74, 0xc4, 0x46, 0x5c, 0x74, 0xc4, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6e, 0x66, 0x60, 0xfe, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6e, 0x66, 0x66, 0xfe, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6e, 0xdb, 0xdb, 0xd8, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6f, 0xdb, 0xdb, 0xdb, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x6c, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x88, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x88, 0x80, 0x88, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x94, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x94, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x94, 0x80, 0x88, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x94, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x94, 0x80, 0x94, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x28, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x28, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x28, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x28, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa2, 0x0c, 0x13, 0x0c, 0x10, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa2, 0x0c, 0x13, 0x0c, 0x10, 0x10, 0x08, 0x04, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x00, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x40, 0x38, 0x40, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x80, 0x70, 0x80, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x10, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf7, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x80, 0x70, 0x80, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x00, 0x07, 0x18, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x29, 0x01, 0x19, 0x21, 0x19, 0xa1, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x2a, 0x02, 0x32, 0x42, 0x32, 0xc6, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0xa3, 0x0c, 0x10, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0xa3, 0x0c, 0x10, 0x10, 0x08, 0x04, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x23, 0x54, 0x33, 0x24, 0x40, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x10, 0x00, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x10, 0x00, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x20, 0x20, 0x20, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x98, 0x60, 0xc2, 0x12, 0x92, 0x9c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x92, 0x9c, 0x60, 0x0e, 0x70, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x60, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x10, 0x60, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x54, 0x58, 0x20, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x0e, 0xf0, 0x02, 0x92, 0x9c, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x60, 0x02, 0x92, 0x9c, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x12, 0x9c, 0x60, 0x0e, 0x70, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x50, 0x28, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x28, 0x14, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0x10, 0x54, 0x38, 0x54, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x10, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x2a, 0x14, 0x00, 0x21, 0x69, 0xa9, 0x69, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x20, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x38, 0x38, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x54, 0x30, 0x18, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x08, 0x10, 0x10, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x54, 0x58, 0x40, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x12, 0xca, 0x2c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00},
{0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x14, 0x18, 0x60, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x06, 0x18, 0x60, 0x00, 0x00},
{0x0a, 0x2a, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x12, 0x92, 0x9c, 0x60, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x3c, 0x40, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x3e, 0x40, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x20, 0x1c, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x10, 0x0e, 0x10, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x0c, 0x10, 0x0e, 0x10, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x0c, 0x10, 0x0e, 0x10, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x28, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x50, 0x00, 0x10, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x88, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x80, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x80, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x15, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x2a, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0x22, 0x41, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0x22, 0x41, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x0e, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x00, 0x06, 0x09, 0x49, 0x87, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x32, 0x42, 0x32, 0x42, 0x02, 0x86, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x4b, 0x4a, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x32, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x30, 0x4e, 0x49, 0x39, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x24, 0x28, 0xf3, 0x24, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x24, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x24, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x68, 0x90, 0x02, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x68, 0x90, 0x02, 0x32, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x80, 0x72, 0xa2, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x40, 0x3a, 0x52, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00},
{0x00, 0x00, 0x22, 0x12, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00},
{0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x22, 0x12, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xf1, 0x35, 0x55, 0x8a, 0xe0, 0x06, 0x95, 0xd6, 0xb5, 0x97, 0x00, 0xee, 0x8a, 0xee, 0x28, 0xe8},
{0x00, 0x38, 0x7c, 0x7c, 0xc6, 0x92, 0xf2, 0xe6, 0xfe, 0xe6, 0x7c, 0x7c, 0x38, 0x00, 0x00, 0x00},
/* Special glyph for unknown character */
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}
};
 
/** @}
/branches/arm/kernel/genarch/src/fb/logo-196x66.c
0,0 → 1,13110
/*
* Copyright (c) 2008 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup genarch
* @{
*/
/** @file
*/
 
#include <genarch/fb/logo-196x66.h>
 
uint32_t fb_logo[LOGO_WIDTH * LOGO_HEIGHT] = {
 
/* Scanline 0 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 1 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 2 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 3 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xf9f9f8,
0xf5f3f1,
0xf3f1ee,
0xf3f2ef,
0xf7f7f6,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 4 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xf9f9f8,
0xf3f1ed,
0xeeeae4,
0xece8df,
0xebe6de,
0xeae5dd,
0xeae5dd,
0xeae5de,
0xeae8e4,
0xf1f1f0,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 5 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xf9f9f8,
0xf4f2ef,
0xefebe5,
0xf0ece5,
0xeeeae4,
0xe3e0db,
0xdfdcd8,
0xe2e0db,
0xeeebe6,
0xeeebe5,
0xeae5dd,
0xe8e4db,
0xe5e1db,
0xe9e9e8,
0xfafafa,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 6 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xfaf9f9,
0xf4f3ef,
0xefece6,
0xf0ece5,
0xeeebe5,
0xdfdcd7,
0xc6c4bd,
0xbebcb5,
0xcfcdc8,
0xd3d2cd,
0xd1cfca,
0xc0beb7,
0xcccac3,
0xeae7e3,
0xe9e5dd,
0xe7e3da,
0xdedbd8,
0xe8e8e7,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 7 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfafafa,
0xf5f4f0,
0xf1eee8,
0xf0ece4,
0xf0ede7,
0xe1ded9,
0xc9c7c1,
0xbebcb4,
0xd1cfca,
0xecebe8,
0xf9f9f7,
0xfaf9f7,
0xf8f6f4,
0xf7f5f2,
0xf4f3f1,
0xdcdad6,
0xc2c0b9,
0xe6e4de,
0xe5e2dc,
0xe2ddd8,
0xd7d5d4,
0xf2f2f1,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 8 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfbfbfb,
0xf6f5f2,
0xf1eee9,
0xf1ede5,
0xf1ede6,
0xe4e1db,
0xcecbc4,
0xbebcb5,
0xcfcdc8,
0xe7e6e4,
0xf8f8f6,
0xfafaf8,
0xf9f7f5,
0xf7f5f2,
0xf5f3f0,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xd9d7d2,
0xc8c5bf,
0xe9e5e0,
0xe4dfd8,
0xd5d2ce,
0xe1e1e1,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 9 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfbfbfb,
0xf7f6f3,
0xf2efea,
0xf1ede6,
0xf1eee7,
0xe5e3de,
0xd0cec7,
0xbfbdb5,
0xcdcbc5,
0xe4e3e0,
0xf7f7f6,
0xfbfaf9,
0xf9f8f6,
0xf8f6f3,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf1efeb,
0xc5c2bb,
0xe2dfdb,
0xe5e0da,
0xded9d3,
0xd3d2d1,
0xf4f4f4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 10 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfcfcfb,
0xf8f6f4,
0xf3f0eb,
0xf1eee7,
0xf2efe8,
0xe8e5df,
0xd3d1cb,
0xc0beb6,
0xcbc9c3,
0xe1e0dc,
0xf5f4f3,
0xfbfaf8,
0xfaf9f7,
0xf8f7f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ec,
0xf2efec,
0xdbd9d4,
0xcdcbc4,
0xe8e4de,
0xe3ded7,
0xd0cecb,
0xe7e7e6,
0xfdfdfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 11 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfcfcfb,
0xf8f7f4,
0xf4f1ed,
0xf2eee8,
0xf3efe9,
0xeae7e1,
0xd6d4cd,
0xc3c1b9,
0xcac8c2,
0xdddcd8,
0xf3f2f1,
0xfafaf8,
0xfbfaf7,
0xf9f7f5,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf1efeb,
0xf1eeeb,
0xece9e5,
0xc3c1ba,
0xe5e3de,
0xe3ded7,
0xd9d5d0,
0xd6d5d5,
0xf7f7f7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 12 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfcfcfc,
0xf9f8f5,
0xf5f2ee,
0xf3efe8,
0xf4f0e9,
0xece9e3,
0xd9d7d1,
0xc4c2bb,
0xc8c6c0,
0xd9d8d4,
0xf1f0ef,
0xfaf9f8,
0xfbfaf8,
0xfaf8f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xd2cfc9,
0xd3d2cc,
0xe4e0db,
0xded9d3,
0xcfccca,
0xededec,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 13 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xf9f9f7,
0xf5f3f0,
0xf3efe8,
0xf4f0e9,
0xeeeae5,
0xdddad4,
0xc7c4bd,
0xc7c6bf,
0xd7d6d1,
0xeeedeb,
0xf9f9f8,
0xfcfbfa,
0xfaf9f6,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf1efeb,
0xf1eeeb,
0xf1eeea,
0xf0ede9,
0xefece8,
0xefece8,
0xe4e2dd,
0xc4c2bb,
0xe5e2de,
0xdfdad3,
0xd3d0cb,
0xdbdbdb,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 14 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xfaf9f7,
0xf6f4f0,
0xf3f0e9,
0xf4f0ea,
0xefece6,
0xdfddd7,
0xcbc8c1,
0xc7c5be,
0xd4d3ce,
0xebebe8,
0xf8f8f6,
0xfcfcfa,
0xfbfaf7,
0xfaf9f6,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xc8c6bf,
0xdcdad5,
0xe1dcd6,
0xdbd7d0,
0xd0cfcd,
0xf1f0f0,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 15 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfafaf9,
0xf7f5f1,
0xf4f1ea,
0xf5f1ea,
0xf1ede7,
0xe2e0da,
0xcccac3,
0xc6c5be,
0xd1cfca,
0xe9e8e6,
0xf8f7f6,
0xfcfcfb,
0xfbfaf8,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xedeae5,
0xdedbd5,
0xc7c6bf,
0xe5e2dd,
0xded9d3,
0xcfcdc9,
0xe2e2e2,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 16 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfbfbf9,
0xf6f3ed,
0xf4f1e9,
0xf4f1eb,
0xe7e4df,
0xcfcdc6,
0xc7c5be,
0xceccc7,
0xe6e5e2,
0xf7f6f5,
0xfdfcfb,
0xfcfbf9,
0xfaf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xe0dedb,
0xb4b2b1,
0xb6b5b4,
0xe0dddb,
0xf1eeeb,
0xf1eeea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e4,
0xe8e6e1,
0xc3c1ba,
0xdfddd9,
0xddd9d3,
0xd6d3cd,
0xd3d2d1,
0xf5f5f4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 17 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafaf9,
0xf4f0e8,
0xf5f1ea,
0xf3f1ed,
0xcbc9c3,
0xcac8c2,
0xe3e2df,
0xf5f4f3,
0xfdfcfb,
0xfdfbfa,
0xfcfaf8,
0xfbf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xe1dedc,
0x7f7e7e,
0x706f6f,
0x757374,
0x8c8c8b,
0xe1dedb,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae5,
0xece9e4,
0xebe9e4,
0xeae8e3,
0xeae8e3,
0xd4d2cb,
0xcdcbc5,
0xe1ded8,
0xdad6cf,
0xcdcbc8,
0xe8e8e8,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 18 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xf4f0eb,
0xf4f0e7,
0xf8f6f3,
0xc6c4bd,
0xdcdad7,
0xfbfbfa,
0xfdfcfb,
0xfcfaf8,
0xfcfaf8,
0xfbfaf7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xb3b1af,
0x716f70,
0x7c7b7b,
0x898989,
0x8f8e8e,
0xbdbbba,
0xeeebe7,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e4,
0xebe8e3,
0xeae8e3,
0xe9e7e2,
0xe8e6e1,
0xe2e0db,
0xc1bfb8,
0xe2dfdb,
0xdad7d0,
0xd2d0cb,
0xd7d7d7,
0xf8f8f7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 19 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf0f0ef,
0xf1ede4,
0xf8f6f0,
0xdbd9d4,
0xd3d2cd,
0xfdfcfb,
0xfcfbf9,
0xfcfaf8,
0xfcfaf8,
0xfbfaf7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xaeacab,
0x7a7979,
0x8f8e8e,
0xa3a2a2,
0xabaaab,
0xafaead,
0xe8e5e1,
0xeeebe7,
0xedeae6,
0xece9e4,
0xebe8e4,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe7e5e0,
0xe7e4df,
0xcac8c1,
0xd4d2cc,
0xdcd9d3,
0xd6d3ce,
0xcdccca,
0xeeeeed,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 20 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xe1e0dd,
0xf0ebe2,
0xfbfaf7,
0xc3c1ba,
0xf3f2f0,
0xfcfbf9,
0xfcfaf8,
0xfcfaf8,
0xfbf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ee,
0xf2f0ec,
0xf2f0ec,
0xf1eeeb,
0xd5d3d1,
0x838282,
0x9d9c9c,
0xb4b3b3,
0xbdbcbd,
0xb6b5b5,
0xd7d4d1,
0xedeae6,
0xece9e5,
0xeae8e3,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xdbd8d3,
0xc3c0ba,
0xe1ded9,
0xd8d4ce,
0xcdcac6,
0xdedddd,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 21 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xd2d1cd,
0xefeae1,
0xfcfaf8,
0xc3c1ba,
0xf9f8f7,
0xfcfaf8,
0xfcfaf8,
0xfbf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf0eeeb,
0xebe9e6,
0xf3f1ee,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeea,
0xefece9,
0x9c9b9a,
0xa1a0a0,
0xb9b7b8,
0xc2c0c1,
0xbfbdbe,
0xc2c1c0,
0xe9e6e2,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe3dfda,
0xc4c1ba,
0xdbd9d4,
0xd8d5ce,
0xd4d0cb,
0xcfcecd,
0xf2f2f2,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xe3e3e3,
0xbbbbbb,
0x9d9d9d,
0x989898,
0xa4a4a4,
0xbfbfbf,
0xeaeaea,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf1f1f1,
0xc4c4c4,
0xa6a6a6,
0x989898,
0xa2a2a2,
0xc5c5c5,
0xf1f0f0,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 22 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0xb9b8b6,
0xeae5dd,
0xf9f6f3,
0xc4c2bb,
0xf2f2f0,
0xfbfaf7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf6f4f1,
0xd2d0ce,
0x908f8e,
0x888686,
0xb3b1b0,
0xedebe8,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xc6c4c2,
0x9c9b9b,
0xb4b3b3,
0xc1bfc0,
0xc1c0c0,
0xbab9b9,
0xdeddd9,
0xe9e7e2,
0xe9e7e2,
0xe7e5e0,
0xe7e4df,
0xe7e4df,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe4e0db,
0xe3dfda,
0xd4d1cb,
0xc6c4bd,
0xdfdcd7,
0xd7d3cc,
0xcbc9c6,
0xe4e4e4,
0xfcfcfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xcbcbcb,
0x5f5f5f,
0x343434,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x363636,
0x737272,
0xdedede,
0xffffff,
0xffffff,
0xffffff,
0xf2f1f1,
0x8e8e8e,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x393939,
0x8a8a8a,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 23 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0xbbbbba,
0xc8c4bd,
0xf4f1eb,
0xd6d4cf,
0xdbd9d5,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f3,
0xf7f5f2,
0xf6f4f1,
0xe4e2df,
0x7f7e7e,
0x717071,
0x7a7878,
0x807f7f,
0xbbbab9,
0xf3f1ee,
0xf2f0ec,
0xf2f0ec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xe7e4e0,
0x999897,
0xacabab,
0xbebcbd,
0xc3c1c2,
0xbebcbd,
0xc9c8c7,
0xe7e5e0,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe3dfda,
0xe2ded9,
0xdedad5,
0xc0beb6,
0xdedad5,
0xd6d2cb,
0xd1cec8,
0xd2d2d2,
0xf6f6f6,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb0afaf,
0x383838,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x414141,
0xc8c8c8,
0xffffff,
0xefefef,
0x626262,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x575656,
0xefefef,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 24 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfc,
0xd9d9d9,
0x9a9893,
0xede9e0,
0xefede8,
0xc3c1bb,
0xf7f6f3,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xcac9c7,
0x717071,
0x7e7e7e,
0x908f8f,
0x9a9998,
0xa5a4a3,
0xebeae6,
0xf2efec,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xb5b3b1,
0xa2a1a1,
0xb8b7b7,
0xc2c0c1,
0xc1bfc0,
0xbcbaba,
0xe1dfda,
0xe7e4df,
0xe6e3de,
0xe5e1dc,
0xe4e0db,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe1ddd8,
0xe1ddd8,
0xe0dbd6,
0xcbc8c1,
0xceccc7,
0xdad7d1,
0xd4d0ca,
0xcbc9c7,
0xeaeae9,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd6d6d6,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x555555,
0xececec,
0x919191,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x7e7e7e,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 25 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xe9e9e9,
0x989694,
0xd8d4cc,
0xf5f3ed,
0xc8c6bf,
0xe8e6e2,
0xf9f7f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f3,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xd8d6d4,
0x7d7d7c,
0x8f8e8e,
0xa6a5a6,
0xb3b2b3,
0xb1b0b0,
0xd7d5d2,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae6,
0xece9e5,
0xd3d0cd,
0x999897,
0xb1afb0,
0xc0bebf,
0xc3c1c2,
0xbbbabb,
0xd2d0cc,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe3dfda,
0xe2ded9,
0xe1ddd8,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xd9d5cf,
0xbfbdb6,
0xdedcd8,
0xd4d0ca,
0xcccac6,
0xd9d8d8,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7a7a7a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x494949,
0x666565,
0x3f3f3f,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x939392,
0x4e4e4e,
0x323232,
0x323232,
0x323232,
0x323232,
0x3f3f3f,
0x686868,
0x4c4c4c,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0xe8e7e7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 26 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf5f5f4,
0xbcbbba,
0xaaa7a2,
0xbebcb6,
0xa19f9c,
0xa5a4a1,
0xf4f2f0,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xedebe8,
0x9c9b9a,
0x999898,
0xb3b1b2,
0xc0bebf,
0xbebcbd,
0xc2c0c0,
0xefece9,
0xefece8,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xedeae6,
0xe4e1de,
0xc7c5c2,
0x9b9a99,
0x8d8c8c,
0xa9a8a8,
0xbdbbbb,
0xc3c1c2,
0xc0bebe,
0xc1bfbe,
0xe1ded9,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1ddd8,
0xe0dbd6,
0xe0dbd6,
0xdedad5,
0xdddad5,
0xdcd8d3,
0xc4c1bb,
0xd5d3ce,
0xd6d2cc,
0xd2cec9,
0xcbcac9,
0xefefef,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf6f6f6,
0x424242,
0x323232,
0x323232,
0x323232,
0x323232,
0x565656,
0xebebeb,
0xffffff,
0xd4d4d4,
0x414141,
0x323232,
0x323232,
0x323232,
0x323232,
0x414141,
0x343434,
0x323232,
0x323232,
0x323232,
0x434343,
0xe1e1e0,
0xffffff,
0xf1f1f1,
0x575757,
0x323232,
0x323232,
0x323232,
0x333333,
0xaeaeae,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 27 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xe0e0e0,
0x8e8c89,
0x696865,
0x343434,
0x343434,
0xc8c7c7,
0xf8f6f4,
0xf7f5f3,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ed,
0xc4c2c1,
0x989797,
0xb3b1b2,
0xc1bfc0,
0xc2c0c1,
0xbcbabb,
0xe1dfdc,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xebe8e4,
0xdedbd8,
0xb0aeac,
0x828181,
0x6f6e6f,
0x797877,
0x8c8c8c,
0xa7a6a6,
0xbab9ba,
0xc3c1c2,
0xc2c0c1,
0xb9b8b8,
0xd7d4d0,
0xe3dfda,
0xe2deda,
0xe1ddd8,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xdedad5,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xd2cfca,
0xc0beb7,
0xdddad6,
0xd4d0ca,
0xcbc8c5,
0xdfdfdf,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xdedede,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x929291,
0xffffff,
0xffffff,
0xfdfdfd,
0x616161,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x5c5c5c,
0xffffff,
0xffffff,
0xfefefe,
0x848484,
0x323232,
0x323232,
0x323232,
0x323232,
0x858585,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 28 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xefefef,
0xacaaaa,
0x83807c,
0x403f3f,
0x323232,
0x7d7c7c,
0xf4f2f0,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xe5e2e0,
0x9e9d9d,
0xacabab,
0xbebcbd,
0xc2c1c1,
0xbdbcbc,
0xcccac8,
0xedeae6,
0xe8e5e2,
0xcdcbc9,
0x9b9a98,
0x767575,
0x717070,
0x777676,
0x7e7e7d,
0x8b8a8a,
0x9c9b9b,
0xafaeae,
0xbdbcbc,
0xc3c1c2,
0xc3c1c2,
0xbebdbd,
0xc6c4c2,
0xe1ddd9,
0xe1dcd7,
0xe0dbd6,
0xe0dbd6,
0xdfdad5,
0xddd9d4,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xd9d6d1,
0xd8d5cf,
0xc0bdb6,
0xdbd9d4,
0xd4d0ca,
0xd1cdc8,
0xcecdcc,
0xf3f3f3,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe0e0e0,
0xbfbfbf,
0xb4b4b4,
0xc0c0c0,
0xdfdfdf,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xebebeb,
0xc8c8c8,
0xb4b4b4,
0xbababa,
0xd5d4d4,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf1f1f1,
0xc7c7c7,
0xb4b4b4,
0xbfbfbf,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x474747,
0xebebeb,
0xffffff,
0xffffff,
0xa3a3a3,
0x323232,
0x323232,
0x323232,
0x323232,
0x747474,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 29 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf9f9f9,
0xd0d0d0,
0x8c8a85,
0x595958,
0x333333,
0x414141,
0xe0dfdc,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf0edea,
0xb7b5b4,
0xa2a1a1,
0xb9b8b8,
0xc2c0c1,
0xc1c0c0,
0xbbb9ba,
0xcac8c5,
0x999797,
0x747373,
0x737272,
0x7a7979,
0x848382,
0x8f8e8e,
0x9a9999,
0xa6a5a5,
0xb1b0b1,
0xbbb9ba,
0xc1bfc0,
0xc4c2c3,
0xc4c2c3,
0xc1bfc0,
0xbbb9b9,
0xdad6d2,
0xe0dbd6,
0xdfdbd6,
0xdedad5,
0xddd9d4,
0xdcd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd9d6d0,
0xccc9c3,
0xc6c4be,
0xdbd8d3,
0xd4d0ca,
0xcac8c5,
0xe6e6e6,
0xfdfdfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xb1b0b0,
0x505050,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0x5c5c5c,
0xd1d1d1,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xcfcfcf,
0x676767,
0x363636,
0x323232,
0x323232,
0x323232,
0x323232,
0x484847,
0xacacac,
0xfbfbfb,
0xffffff,
0xffffff,
0xe2e2e2,
0x4d4d4d,
0x4e4e4e,
0xa4a4a4,
0xfaf9f9,
0x979797,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x585857,
0xcbcbcb,
0xffffff,
0xffffff,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x757575,
0xf4f4f4,
0xffffff,
0xf2f2f2,
0xe3e3e3,
0xe3e3e3,
0xe3e3e3,
0xe4e4e4,
0xebebeb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 30 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe9e9e9,
0x9f9d9a,
0x787672,
0x393939,
0x323232,
0xa2a1a0,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf1efec,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xd8d6d3,
0x999898,
0xb1b0b0,
0xbfbebe,
0xc2c0c1,
0xbbbabb,
0xa9a8a8,
0x929191,
0x868585,
0x8a8888,
0x939292,
0xa09f9f,
0xabaaaa,
0xb4b2b3,
0xbbb9ba,
0xc3c1c2,
0xceccca,
0xc3c1c2,
0xc3c1c2,
0xc3c1c2,
0xc3c1c2,
0xbcbbbb,
0xcbc8c6,
0xdfdad5,
0xddd9d4,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd5d1cb,
0xbdbbb3,
0xdcd9d6,
0xd4d0ca,
0xd0cdc7,
0xd3d3d3,
0xf7f7f7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xf4f4f4,
0x7b7a7a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x373737,
0xbcbcbc,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xa7a7a7,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0x888888,
0xf9f9f9,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x8f8f8f,
0x7f7f7f,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x353535,
0xc4c4c4,
0xffffff,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x424242,
0x484848,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x595959,
0xc7c7c7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 31 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f4f4,
0xbdbcbb,
0x898782,
0x4b4a4a,
0x323232,
0x5d5d5d,
0xebe9e7,
0xf4f2ef,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf1efec,
0xf1eeeb,
0xf0eeea,
0xf0edea,
0xf0ede9,
0xefece8,
0xe9e6e3,
0xa7a6a5,
0xa7a6a6,
0xbcbabb,
0xc3c1c2,
0xc0bebf,
0xb6b4b5,
0xa8a7a7,
0xa2a0a0,
0xa5a5a5,
0xafaeae,
0xb8b6b6,
0xbdbcbc,
0xc9c7c6,
0xd7d5d2,
0xe2deda,
0xe3dfda,
0xc6c4c3,
0xbdbbbc,
0xc1bfc0,
0xc3c1c2,
0xc0bebf,
0xbebcbc,
0xdad7d2,
0xdcd9d4,
0xdbd8d3,
0xdad7d2,
0xdad7d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xc4c2ba,
0xd0cec8,
0xd7d3cd,
0xd3cfc9,
0xc9c8c6,
0xececec,
0xfefefd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xfafafa,
0x838383,
0x323232,
0x323232,
0x424242,
0x9f9f9f,
0xdbdbdb,
0xe3e3e3,
0xcfcfcf,
0x858585,
0x353535,
0x323232,
0x3a3a39,
0xe3e3e3,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xb6b6b6,
0x383838,
0x323232,
0x363636,
0x818181,
0xcfcfcf,
0xe4e4e4,
0xd9d9d9,
0xa1a0a0,
0x454545,
0x323232,
0x353535,
0xaaaaaa,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x444343,
0x323232,
0x4b4b4b,
0xa9a8a8,
0xdedede,
0xe3e3e3,
0xc3c3c2,
0x5d5d5d,
0x323232,
0x323232,
0x525252,
0xfafafa,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x4f4f4f,
0x6f6f6f,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x353535,
0x777777,
0xe7e7e7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 32 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfb,
0xe0e0e0,
0x92908b,
0x6a6966,
0x353535,
0x343434,
0xc7c6c6,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf1efec,
0xf1eeeb,
0xf0edea,
0xf0edea,
0xefece9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xc8c7c4,
0x9c9b9b,
0xb5b4b4,
0xc1bfc0,
0xc3c1c2,
0xbfbdbe,
0xbab8b9,
0xb8b6b7,
0xbab9ba,
0xc1c0c0,
0xd0cecc,
0xdfdcd8,
0xe4e0db,
0xe3dfda,
0xe3dfda,
0xe2deda,
0xcfccc9,
0xafaeae,
0xbab8b9,
0xc1c0c0,
0xc2c0c1,
0xbab9b9,
0xcfcdc9,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd2cec8,
0xbdbbb3,
0xdedbd7,
0xd4d0ca,
0xcbc9c5,
0xdbdbda,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0x515151,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x454545,
0x323232,
0x323232,
0xababab,
0xffffff,
0xc6c6c6,
0x363636,
0x323232,
0x4e4e4e,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xadacad,
0x323232,
0x323232,
0x808080,
0xfefefe,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xefefef,
0x4c4c4c,
0x323232,
0x393939,
0xb5b5b5,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd6d6d6,
0x464646,
0x323232,
0x525252,
0xeeeeee,
0xdedede,
0x323232,
0x323232,
0x323232,
0x575757,
0xececec,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf3f3f3,
0x464646,
0x323232,
0x323232,
0xd5d5d5,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xd3d3d3,
0x4b4b4b,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x3d3d3d,
0x9f9f9f,
0xfcfcfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 33 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xefefef,
0xacaba9,
0x83807c,
0x424141,
0x323232,
0x7c7c7b,
0xf0efec,
0xf2f0ec,
0xf1eeec,
0xf1eeeb,
0xf0edea,
0xf0edea,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae6,
0xe2e0dc,
0x9f9d9d,
0xacabab,
0xbebcbd,
0xc3c1c2,
0xc3c1c2,
0xc3c1c2,
0xc9c7c6,
0xd8d6d3,
0xe3e0dc,
0xe5e2dd,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe2deda,
0xe1ddd8,
0xdcd8d4,
0xa3a1a1,
0xadacac,
0xbdbcbc,
0xc2c0c1,
0xbebcbd,
0xc1bfbe,
0xd9d6d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xc0bdb5,
0xd6d4d0,
0xd4d0cb,
0xd2cfc9,
0xcbcac9,
0xf1f1f0,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0xababab,
0xfbfbfb,
0x757575,
0x323232,
0x3c3c3c,
0xc6c6c6,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0x605f5f,
0x323232,
0x393938,
0xf3f3f3,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xacacac,
0x343434,
0x323232,
0x939393,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x9a9a9a,
0x323232,
0x353535,
0xb8b8b8,
0xdedede,
0x323232,
0x323232,
0x3a3a3a,
0xc6c6c6,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x8a8a8a,
0x323232,
0x323232,
0xb2b2b2,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xd4d4d4,
0x505050,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0x6e6e6e,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 34 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f7,
0xcecdcd,
0x8d8b86,
0x5c5b59,
0x333333,
0x434343,
0xdcdbd9,
0xf1eeeb,
0xf0eeea,
0xf0edea,
0xefece9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e5,
0xeae8e3,
0xb5b4b2,
0xa1a0a0,
0xb7b6b7,
0xc2c1c1,
0xc4c2c3,
0xc6c4c5,
0xe2dfdb,
0xe5e2dd,
0xe4e1dc,
0xe3dfda,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe0dcd7,
0xe0dbd6,
0xe0dbd6,
0xb4b2b0,
0xa09f9f,
0xb7b6b7,
0xc2c0c1,
0xc1c0c0,
0xbbb9b9,
0xd3d1cc,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xcdcac3,
0xc0beb7,
0xdddad5,
0xd4d0ca,
0xc9c7c4,
0xe1e1e1,
0xfcfcfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0xababab,
0xe6e6e6,
0x4b4b4b,
0x323232,
0x5b5b5b,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xa8a8a7,
0x323232,
0x323232,
0xbebebe,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0x707070,
0x323232,
0x393939,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xdadada,
0x3e3e3e,
0x323232,
0x808080,
0xdedede,
0x323232,
0x323232,
0x535353,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb0b0b0,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xffffff,
0xececec,
0x7a7a7a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0x8b8b8b,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 35 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe8e7e7,
0x9c9a96,
0x797873,
0x3a3a3a,
0x323232,
0xa2a1a0,
0xf2efec,
0xf0edea,
0xefece9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e5,
0xebe8e4,
0xe9e7e2,
0xd6d5d1,
0x999898,
0xb0afaf,
0xbfbebe,
0xc4c2c3,
0xc3c1c2,
0xd6d3d0,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe2deda,
0xe1ddd8,
0xe0dcd7,
0xe0dbd6,
0xdfdbd6,
0xddd9d4,
0xcecbc7,
0x999999,
0xaeadae,
0xbebdbe,
0xc3c1c2,
0xbcbbbb,
0xc9c7c3,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd3cfc9,
0xbdbab3,
0xdbd8d4,
0xd4d0ca,
0xd1cec8,
0xcececd,
0xf5f4f4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xcbcbcb,
0x323232,
0x323232,
0x878686,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xcacaca,
0x323232,
0x323232,
0x9c9c9b,
0xffffff,
0x565656,
0x323232,
0x494949,
0xeaeaea,
0x454545,
0x323232,
0x575757,
0xf0f0f0,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xeaeaea,
0x515151,
0x323232,
0x5d5d5d,
0xdedede,
0x323232,
0x323232,
0x777777,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xffffff,
0xffffff,
0xfdfdfd,
0xc1c1c1,
0x525252,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0xe1e1e1,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 36 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f4f3,
0xbabab9,
0x898782,
0x4e4d4c,
0x323232,
0x5e5e5e,
0xe7e5e3,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae6,
0xece9e5,
0xebe8e4,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe4e3de,
0xa8a7a5,
0xa6a5a5,
0xbbb9ba,
0xc3c1c2,
0xc3c1c2,
0xc4c1c1,
0xe1ded9,
0xe2deda,
0xe1ddd9,
0xe1ddd8,
0xe0dbd6,
0xe0dbd6,
0xdedad5,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xa4a3a2,
0xa5a4a4,
0xbab9b9,
0xc2c0c1,
0xc0bebf,
0xcbc8c6,
0xd8d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xc7c5be,
0xc9c6c0,
0xd9d5d0,
0xd4d0ca,
0xc9c8c5,
0xe8e8e7,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xb3b3b3,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x7e7e7e,
0xfefefe,
0x565656,
0x323232,
0x494949,
0xd6d6d6,
0x404040,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x4e4e4e,
0xcecece,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf5f5f5,
0x949494,
0x373737,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x9d9d9d,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 37 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0xdddddd,
0x8f8d8a,
0x6c6a68,
0x363636,
0x363636,
0xc5c4c3,
0xefece8,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e5,
0xebe8e4,
0xeae7e3,
0xe9e7e2,
0xe8e6e1,
0xe8e6e1,
0xe7e5e0,
0xc7c5c2,
0x9a9a9a,
0xb4b3b3,
0xc1bfc0,
0xc3c1c2,
0xbdbbbc,
0xd5d2ce,
0xe1ddd9,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xdedad5,
0xdcd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xc6c3c0,
0x9f9d9d,
0xb2b1b2,
0xc1bfc0,
0xc5c3c3,
0xd4d0cc,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd1cec7,
0xbbb8b1,
0xdddad6,
0xd4d0ca,
0xcfcbc6,
0xd4d4d4,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xa5a5a5,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x7a7a7a,
0xfefefe,
0x565656,
0x323232,
0x494949,
0xcbcbcb,
0x3d3d3d,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x4d4d4d,
0xcccccc,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x424242,
0xa4a4a4,
0xb4b4b4,
0xb4b4b4,
0xb4b4b4,
0xdadada,
0xffffff,
0xfefefe,
0xc6c6c6,
0x3d3d3d,
0x323232,
0x323232,
0x323232,
0x323232,
0x7b7b7b,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 38 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xefeeee,
0xaaa8a7,
0x827f7b,
0x434242,
0x323232,
0x7d7d7c,
0xeeece9,
0xedeae6,
0xece9e5,
0xebe8e4,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe8e5e0,
0xe7e4df,
0xe6e3de,
0xdddad6,
0x9d9c9b,
0xabaaaa,
0xbdbcbc,
0xc3c1c2,
0xbfbdbe,
0xc3c1c0,
0xe0dcd7,
0xe0dbd6,
0xdedad5,
0xddd9d4,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd8d5d0,
0xcac8c3,
0xc0bebc,
0xc9c7c5,
0xd4d0cc,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd2cfc8,
0xc1beb8,
0xc7c4be,
0xd5d1cb,
0xd4d0ca,
0xc3c0b9,
0xd3d1cc,
0xd6d2cc,
0xd3cfca,
0xc8c7c6,
0xeeeeed,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xa8a8a8,
0x323232,
0x323232,
0x747474,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xe0e0e0,
0xffffff,
0x565656,
0x323232,
0x494949,
0xcecece,
0x3e3e3e,
0x323232,
0x505050,
0xc4c4c4,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xd5d5d5,
0xd9d9d9,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x9a9a9a,
0xffffff,
0xffffff,
0xfefefe,
0x898988,
0x323232,
0x323232,
0x323232,
0x323232,
0x696969,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 39 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f7,
0xcbcbcb,
0x8d8a86,
0x5e5d5b,
0x343433,
0x454545,
0xd9d8d6,
0xece9e5,
0xebe8e4,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe8e6e1,
0xe7e5e0,
0xe6e4df,
0xe5e2dd,
0xe5e2dd,
0xe4e0db,
0xb7b5b3,
0xa09fa0,
0xb7b6b6,
0xc2c0c1,
0xc1c0c0,
0xbab8b8,
0xd9d5d1,
0xdedad5,
0xdcd9d4,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xacaaa3,
0x817f7b,
0x93918e,
0xd7d4d0,
0xd4d0ca,
0xcecac4,
0xc3c1ba,
0xe1deda,
0xd4d0ca,
0xcac8c4,
0xdcdcdc,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xc1c1c1,
0x323232,
0x323232,
0x7c7c7c,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xe1e1e1,
0x434343,
0x323232,
0x505050,
0xededed,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xdedede,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0xa3a3a3,
0xffffff,
0xffffff,
0xffffff,
0x6d6d6d,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x9a9a9a,
0xffffff,
0xffffff,
0xffffff,
0xa3a3a3,
0x323232,
0x323232,
0x323232,
0x323232,
0x696969,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 40 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe7e7e7,
0x9a9896,
0x797773,
0x3b3b3b,
0x323232,
0xa2a1a0,
0xedeae6,
0xe9e7e2,
0xe8e6e1,
0xe8e6e1,
0xe8e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xd3d0cd,
0x999898,
0xafaeae,
0xbfbebe,
0xc3c1c2,
0xbcbbbb,
0xc9c6c4,
0xdcd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xdad7d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xb5b3ae,
0xadaba4,
0xd2d0ca,
0xe6e4e2,
0xd4d0ca,
0xd1cdc7,
0xc2c0b9,
0xe9e6e4,
0xd4d0ca,
0xd2cfc9,
0xcac9c9,
0xf3f3f3,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xdfdfdf,
0x414141,
0x323232,
0x535353,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xcfcfcf,
0x7d7d7d,
0x7d7d7d,
0xcacaca,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0x5f5f5f,
0x323232,
0x353535,
0xd7d7d7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xebebeb,
0x898989,
0x7d7d7d,
0xa2a2a2,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xf6f6f6,
0x3e3e3e,
0x323232,
0x323232,
0x323232,
0x323232,
0x747474,
0xfbfbfb,
0xffffff,
0xefeeee,
0x515151,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x717170,
0xffffff,
0xffffff,
0xfcfcfc,
0x7f7f7f,
0x323232,
0x323232,
0x323232,
0x323232,
0x828282,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 41 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f4f3,
0xb9b9b8,
0x898781,
0x4f4e4d,
0x323232,
0x5f5f5f,
0xe5e3e1,
0xe8e6e1,
0xe8e6e1,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xdedad7,
0xa8a6a5,
0xa5a4a4,
0xbbb9ba,
0xc2c0c1,
0xc0bebf,
0xc1bfbe,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd6d2cc,
0xe5e3e0,
0xecebe8,
0xdad6d1,
0xd4d0ca,
0xcbc8c2,
0xc7c5bf,
0xeae8e6,
0xd4d0ca,
0xd3cfc9,
0xbfbebc,
0xeaeaea,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xf8f8f8,
0x6a696a,
0x323232,
0x383838,
0xb8b8b8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0x6c6c6c,
0x323232,
0x323232,
0xe1e1e1,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xa1a0a0,
0x333333,
0x323232,
0x848484,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xa8a8a7,
0x323232,
0x323232,
0xa3a3a3,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0x696969,
0x323232,
0x323232,
0x323232,
0x323232,
0x373737,
0x9b9b9a,
0xcccccc,
0x878686,
0x353535,
0x323232,
0x323232,
0x323232,
0x323232,
0x5c5c5c,
0x323232,
0x323232,
0x323232,
0x323232,
0x393939,
0x969595,
0xcecece,
0xa4a4a4,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x333333,
0xaeaeae,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 42 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfa,
0xdbdbdb,
0x918e8b,
0x6d6c68,
0x363636,
0x363636,
0xbfbebd,
0xe9e7e2,
0xe7e5e0,
0xe6e4df,
0xe5e2dd,
0xe4e1dc,
0xe4e1dc,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1ddd9,
0xe0dcd7,
0xc5c2bf,
0x9a9999,
0xb3b2b3,
0xc1bfc0,
0xc3c1c2,
0xcac8c6,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0cb,
0xd5d1cb,
0xd4d0ca,
0xd3cfc9,
0xbdbbb3,
0xdeddd9,
0xe3e0dc,
0xd4d0ca,
0xd3cfc9,
0xb5b4b3,
0xe4e4e4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xc3c3c3,
0x363636,
0x323232,
0x494949,
0xd4d4d4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f8,
0x8f8f8f,
0x323232,
0x323232,
0x767676,
0xfefefe,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xececec,
0x4b4b4b,
0x323232,
0x373736,
0xacacac,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xbababa,
0x414141,
0x323232,
0x4f4f4f,
0xe7e7e7,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0xacacac,
0x343434,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x3d3d3d,
0xa3a3a3,
0x3a3a3a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x3b3b3b,
0xefeeee,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 43 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeee,
0xa9a8a7,
0x82807b,
0x454544,
0x323232,
0x787877,
0xeae8e4,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1dcd8,
0xe0dbd6,
0xdfdad5,
0xdbd7d2,
0xb5b3b1,
0xadabac,
0xbdbcbc,
0xc8c6c6,
0xd7d4d0,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd2cec8,
0xc1beb6,
0xc5c4bd,
0xf4f3f1,
0xd7d3cd,
0xd4d0ca,
0xccc9c3,
0xadacac,
0xe4e4e4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xfbfbfb,
0x8c8c8c,
0x323232,
0x323232,
0x373737,
0x777777,
0xa9a9a9,
0xb3b3b3,
0x9b9b9b,
0x545454,
0x323232,
0x323232,
0x484848,
0xe7e7e7,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xbfbfbf,
0x3a3a3a,
0x323232,
0x323232,
0x616161,
0x9d9d9d,
0xb4b4b4,
0xa7a7a7,
0x6c6b6b,
0x353535,
0x323232,
0x3b3b3b,
0xb6b6b6,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0xf3f3f3,
0x5c5c5c,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x868586,
0xfafafa,
0x8a8a8a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0xa09f9f,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 44 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf7f7f7,
0xcacaca,
0x8b8984,
0x5f5e5c,
0x343434,
0x454545,
0xd5d4d2,
0xe5e2dd,
0xe4e1dc,
0xe3e0db,
0xe3dfda,
0xe1ddd9,
0xe1ddd9,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xddd9d4,
0xddd9d4,
0xdad7d2,
0xd2d0cc,
0xd4d2ce,
0xd8d6d1,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd3cfc9,
0xcecac3,
0xc3c0b8,
0xbbb9b1,
0xcfcdc7,
0xf2f1ef,
0xdfdcd8,
0xd4d0ca,
0xd3cfc9,
0x9c9a96,
0xb4b3b3,
0xeaeae9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xf8f8f8,
0x919191,
0x373737,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x545454,
0xe1e1e1,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xbcbbbb,
0x444444,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x424242,
0xb5b5b5,
0xffffff,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0xffffff,
0xe6e6e6,
0x626262,
0x333333,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0x7f7e7e,
0xf4f4f4,
0xffffff,
0xf7f7f7,
0x898989,
0x343434,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0x9a9a9a,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 45 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe7e6e6,
0x989795,
0x797873,
0x3c3c3c,
0x323232,
0x9c9c9b,
0xe8e5e1,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1ddd8,
0xe0dcd7,
0xdfdbd6,
0xdedad5,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xcecbc5,
0xc5c3bb,
0xbdbab2,
0xc2c0ba,
0xd7d6d1,
0xecebe9,
0xeeedea,
0xdcd9d4,
0xd4d0ca,
0xd3cfc9,
0x9d9b97,
0x6f6f6e,
0xc3c2c2,
0xf2f2f1,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xbfbfbf,
0x989898,
0x989898,
0xd4d4d4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xbebebe,
0x989898,
0x989898,
0xd5d5d5,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xd8d8d7,
0x868585,
0x535353,
0x353535,
0x333333,
0x454545,
0x666565,
0xadadad,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xababab,
0x989898,
0xa4a4a4,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xebebeb,
0x9d9d9d,
0x605f5f,
0x3b3b3b,
0x323232,
0x3d3d3d,
0x5a5959,
0x949494,
0xe8e8e8,
0xffffff,
0xffffff,
0xffffff,
0xeeeeee,
0x989898,
0x989898,
0xc0c0c0,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd9d9d9,
0x999999,
0x989898,
0xd5d5d5,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xc1c1c1,
0x7a7a7a,
0x555554,
0x363636,
0x323232,
0x3a3a3a,
0x595958,
0x878787,
0xd0d0d0,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xd5d5d5,
0x8b8b8b,
0x5b5a5a,
0x3c3c3c,
0x323232,
0x383838,
0x5b5b5b,
0x898989,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 46 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f3f3,
0xb9b8b8,
0x878580,
0x51514f,
0x323232,
0x5c5c5c,
0xe2e0dd,
0xe2deda,
0xe1ddd9,
0xe1dcd7,
0xe0dbd6,
0xdfdad5,
0xded9d4,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd0ccc6,
0xc7c4be,
0xbcbab2,
0xc0bfb8,
0xd1d0cb,
0xe9e8e6,
0xeeedeb,
0xe7e5e1,
0xdbd8d3,
0xd5d1cb,
0xd1cdc7,
0xb5b2ae,
0x7a7978,
0x4b4b4b,
0x969595,
0xd6d6d6,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 47 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xdadada,
0x8f8d8a,
0x6e6c69,
0x373636,
0x373737,
0xbebdbc,
0xe4e0db,
0xe0dcd7,
0xdfdbd6,
0xdedad5,
0xddd9d4,
0xdcd9d4,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd1cdc7,
0xcac6c0,
0xbfbcb5,
0xbebcb5,
0xceccc7,
0xe5e4e1,
0xefeeec,
0xeae8e4,
0xdddad5,
0xd6d2cc,
0xd2cec8,
0xbdbab4,
0x94928f,
0x626160,
0x424141,
0x444343,
0x807f7f,
0xbcbbbc,
0xeaeaea,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 48 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeee,
0xa8a7a5,
0x817f7a,
0x464544,
0x333333,
0xa6a5a5,
0xe6e3e0,
0xdfdbd6,
0xded9d4,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd2cec8,
0xcbc8c1,
0xc0bdb5,
0xbebcb5,
0xc9c7c1,
0xe2e1de,
0xeeedeb,
0xeceae8,
0xdfdcd8,
0xd7d3cd,
0xd3cfc9,
0xc2beb9,
0x9f9d98,
0x6b6a67,
0x4a4948,
0x3b3b3b,
0x474746,
0x626161,
0x8b8a8a,
0xb7b6b6,
0xe0e0df,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 49 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf7f7f7,
0xc9c8c8,
0x8b8884,
0x5f5f5d,
0x5d5c5c,
0xd3d2d0,
0xe2dfdb,
0xddd9d4,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xd0cdc8,
0xc7c4c0,
0xd4d2cd,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd3cfc9,
0xcdc9c3,
0xc2bfb8,
0xbdbbb3,
0xc5c3bd,
0xdddcd8,
0xedecea,
0xeeedeb,
0xe1deda,
0xd8d4cf,
0xd3d0ca,
0xc6c2bd,
0xa8a5a1,
0x747371,
0x4f4f4f,
0x3d3d3d,
0x444444,
0x5b5b5a,
0x777777,
0x939392,
0xababab,
0xc8c7c7,
0xe4e4e4,
0xf7f7f7,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 50 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe6e6e6,
0x989794,
0x83817d,
0xc4c3c2,
0xcbc9c2,
0xd5d3ce,
0xdfdbd6,
0xdbd8d3,
0xdbd8d3,
0xd5d2cd,
0x94928d,
0x85837e,
0xaaa8a4,
0xe1deda,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd3cfc9,
0xcfcbc5,
0xc5c2ba,
0xbebbb3,
0xc2c0b9,
0xd8d7d3,
0xebeae8,
0xefeeec,
0xe4e1dd,
0xd9d6d0,
0xd4d0ca,
0xcac6c0,
0xafaca8,
0x807f7c,
0x565655,
0x3e3e3e,
0x444343,
0x555454,
0x717070,
0x8d8b8c,
0xa6a5a5,
0xbcbbbb,
0xd0d0d0,
0xe2e2e2,
0xf1f1f1,
0xfafafa,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 51 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f3f3,
0xb8b8b7,
0x9d9b96,
0xd8d5d1,
0xd3d0ca,
0xc2c0ba,
0xe1deda,
0xdbd8d3,
0xdad7d2,
0xd5d3ce,
0xa7a5a2,
0xc2c0b9,
0xd8d7d5,
0xe3e1dd,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xcfccc5,
0xc7c4be,
0xbdbbb3,
0xc0beb7,
0xd3d2cd,
0xe8e8e5,
0xf1f0ef,
0xe6e4e0,
0xdbd8d3,
0xd4d1cb,
0xccc8c3,
0xb8b5b0,
0x898785,
0x5f5e5c,
0x444343,
0x444443,
0x515151,
0x6b6b6a,
0x868685,
0xa09f9f,
0xb6b5b5,
0xcccbcb,
0xdedede,
0xececec,
0xf6f6f6,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 52 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xd9d9d9,
0x8c8a87,
0xbfbcb7,
0xd8d4ce,
0xc0beb7,
0xdcd9d4,
0xdbd8d3,
0xdad7d2,
0xd9d6d0,
0xe0ddd9,
0xebeae7,
0xeae9e6,
0xd9d5d0,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd2cec8,
0xc9c7c0,
0xbebbb4,
0xbdbbb4,
0xceccc7,
0xe6e5e2,
0xf1f0ee,
0xe9e7e4,
0xdcd9d4,
0xd5d1cb,
0xd0ccc6,
0xbdbab4,
0x95938f,
0x656463,
0x474747,
0x444443,
0x4f4f4e,
0x646464,
0x807f7e,
0x9b9a9a,
0xb1b0b0,
0xc7c6c6,
0xdadada,
0xe9e9e9,
0xf4f4f4,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 53 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeed,
0x9c9b9a,
0x92908d,
0xd5d2cc,
0xceccc6,
0xc4c2bb,
0xdcd9d4,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd3cfc9,
0xcdc9c3,
0xc0beb6,
0xbdbbb3,
0xc9c8c1,
0xe2e1de,
0xf1f1ef,
0xebe9e6,
0xdfdcd7,
0xd5d1cb,
0xd1cdc7,
0xc2bfba,
0x9d9a96,
0x6f6e6b,
0x4d4c4b,
0x464544,
0x4c4c4b,
0x60605f,
0x7a7a79,
0x959595,
0xababab,
0xc1c1c1,
0xd6d5d5,
0xe7e7e6,
0xf3f2f2,
0xfafaf9,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 54 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf7f7f7,
0xc7c7c6,
0x787775,
0xc8c4be,
0xd7d4cf,
0xc3c1b9,
0xc4c2ba,
0xd4d1cb,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd5d1cb,
0xcfcbc5,
0xc3c0b8,
0xbdbbb4,
0xc3c1bb,
0xdfdedb,
0xefeeed,
0xefedeb,
0xe0deda,
0xd7d3cd,
0xd2cec8,
0xc7c3bd,
0xa6a39e,
0x757371,
0x525150,
0x454544,
0x4b4a49,
0x5c5b5a,
0x767575,
0x909090,
0xa7a6a6,
0xbdbdbd,
0xd1d1d1,
0xe2e2e1,
0xf0efef,
0xf8f8f8,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 55 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfc,
0xe6e6e5,
0x848382,
0xa5a39e,
0xd6d2cc,
0xd7d4ce,
0xc8c5be,
0xbcbab2,
0xc4c1ba,
0xcbc8c1,
0xccc9c2,
0xc4c1ba,
0xbdbbb3,
0xc1bfb8,
0xd8d7d3,
0xededeb,
0xf1f0ee,
0xe3e1dd,
0xd8d4cf,
0xd3cfca,
0xcac6c1,
0xafaca7,
0x7d7b78,
0x555452,
0x454443,
0x494847,
0x575555,
0x706f6f,
0x8a8989,
0xa2a1a1,
0xb8b7b8,
0xcecdcd,
0xe0e0df,
0xeeeeed,
0xf7f7f7,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 56 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f3f3,
0xb2b2b2,
0x797875,
0xcdc9c3,
0xd6d3cd,
0xd9d6d0,
0xdcd9d5,
0xd8d7d2,
0xcfcdc7,
0xd0cec9,
0xdcdad7,
0xeae9e6,
0xf3f2f1,
0xe6e3e0,
0xdad6d0,
0xd4d0ca,
0xcdc9c3,
0xb5b2ad,
0x878581,
0x5d5c5a,
0x464544,
0x474645,
0x515050,
0x696968,
0x848483,
0x9d9c9c,
0xb3b2b2,
0xc8c8c8,
0xdcdcdc,
0xebebeb,
0xf6f6f5,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 57 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xd8d8d8,
0x71706f,
0x92908c,
0xd1cec8,
0xd6d2cc,
0xd7d3cd,
0xd8d4ce,
0xdfdbd6,
0xe2dfdb,
0xe1deda,
0xdbd7d2,
0xd4d0ca,
0xcfcbc5,
0xbfbcb6,
0x8e8c89,
0x646260,
0x494847,
0x494847,
0x504f4e,
0x646362,
0x7e7d7d,
0x979696,
0xadacac,
0xc4c3c3,
0xd8d7d7,
0xe8e8e8,
0xf3f3f3,
0xfafafa,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 58 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeed,
0x9f9e9e,
0x5a5958,
0x878683,
0xc6c2bd,
0xd3cfc9,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd1cdc7,
0xc4c0bb,
0x9a9894,
0x6c6b68,
0x4d4c4b,
0x494847,
0x4d4c4b,
0x5f5e5d,
0x777776,
0x929292,
0xa8a7a7,
0xbebdbe,
0xd4d3d2,
0xe5e5e5,
0xf1f1f1,
0xf9f9f9,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 59 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f7,
0xd5d4d4,
0x7c7c7b,
0x555452,
0x5f5e5c,
0x82807c,
0x989692,
0x9a9894,
0x92908c,
0x747371,
0x525251,
0x4a4948,
0x4e4d4c,
0x5a5a59,
0x717171,
0x8c8b8c,
0xa3a2a2,
0xb9b9b9,
0xd0cfcf,
0xe1e1e1,
0xeeeeee,
0xf7f7f7,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 60 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xefefef,
0xc5c5c5,
0x807f7e,
0x585755,
0x525150,
0x51504f,
0x4f4f4e,
0x4e4e4d,
0x4f4f4e,
0x595857,
0x6d6c6b,
0x878787,
0x9e9d9d,
0xb4b3b4,
0xcacaca,
0xdddddd,
0xededec,
0xf7f7f6,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 61 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfb,
0xebebea,
0xcacaca,
0xa09f9f,
0x7b7b7a,
0x6b6b6a,
0x686868,
0x6f6f6e,
0x838281,
0x9a9999,
0xafaeae,
0xc5c5c5,
0xdadad9,
0xe9e9e9,
0xf4f4f3,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 62 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfb,
0xf0f0f0,
0xdcdcdb,
0xc7c7c7,
0xb8b7b7,
0xb2b2b2,
0xb6b6b6,
0xc4c3c3,
0xd5d5d5,
0xe6e6e6,
0xf3f3f2,
0xfafafa,
0xfefefd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 63 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 64 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 65 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
};
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/Makefile.inc
33,75 → 33,96
genarch/src/acpi/acpi.c \
genarch/src/acpi/madt.c
endif
 
ifeq ($(CONFIG_PAGE_PT),y)
GENARCH_SOURCES += \
genarch/src/mm/page_pt.c \
genarch/src/mm/as_pt.c
endif
 
ifeq ($(CONFIG_PAGE_HT),y)
GENARCH_SOURCES += \
genarch/src/mm/page_ht.c \
genarch/src/mm/as_ht.c
endif
 
ifeq ($(CONFIG_ASID),y)
GENARCH_SOURCES += \
genarch/src/mm/asid.c
endif
 
ifeq ($(CONFIG_ASID_FIFO),y)
GENARCH_SOURCES += \
genarch/src/mm/asid_fifo.c
endif
 
ifeq ($(CONFIG_SOFTINT),y)
GENARCH_SOURCES += \
genarch/src/softint/division.c
endif
 
## Framebuffer
ifeq ($(CONFIG_FB),y)
GENARCH_SOURCES += \
genarch/src/fb/font-8x16.c \
genarch/src/fb/logo-196x66.c \
genarch/src/fb/fb.c
DEFS += -DCONFIG_FB
endif
 
## i8042 controller
ifeq ($(CONFIG_I8042),y)
ifeq ($(CONFIG_DSRLNIN),y)
GENARCH_SOURCES += \
genarch/src/kbd/i8042.c \
genarch/src/kbd/key.c \
genarch/src/kbd/scanc_pc.c
genarch/src/drivers/dsrln/dsrlnin.c
endif
 
## pl050 controller
ifeq ($(CONFIG_PL050),y)
ifeq ($(CONFIG_DSRLNOUT),y)
GENARCH_SOURCES += \
genarch/src/kbd/key.c \
genarch/src/kbd/scanc_pl050.c
DEFS += -DCONFIG_PL050
genarch/src/drivers/dsrln/dsrlnout.c
endif
## Sun keyboard
ifeq ($(CONFIG_SUN_KBD),y)
 
ifeq ($(CONFIG_I8042),y)
GENARCH_SOURCES += \
genarch/src/kbd/key.c \
genarch/src/kbd/scanc_sun.c
genarch/src/drivers/i8042/i8042.c
endif
 
## z8530 controller
ifeq ($(CONFIG_NS16550),y)
GENARCH_SOURCES += \
genarch/src/drivers/ns16550/ns16550.c
endif
 
ifeq ($(CONFIG_Z8530),y)
GENARCH_SOURCES += \
genarch/src/kbd/z8530.c
genarch/src/drivers/z8530/z8530.c
endif
 
## ns16550 controller
ifeq ($(CONFIG_NS16550),y)
ifeq ($(CONFIG_VIA_CUDA),y)
GENARCH_SOURCES += \
genarch/src/kbd/ns16550.c
genarch/src/drivers/via-cuda/cuda.c
endif
 
ifeq ($(CONFIG_PC_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_pc.c
endif
 
## OpenFirmware Device Tree
ifeq ($(CONFIG_OFW_TREE), y)
ifeq ($(CONFIG_SUN_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_sun.c
endif
 
ifeq ($(CONFIG_MAC_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_mac.c
endif
 
ifeq ($(CONFIG_SRLN),y)
GENARCH_SOURCES += \
genarch/src/srln/srln.c
endif
 
ifeq ($(CONFIG_OFW_TREE),y)
GENARCH_SOURCES += \
genarch/src/ofw/ofw_tree.c \
genarch/src/ofw/ebus.c \
genarch/src/ofw/fhc.c \
109,3 → 130,13
genarch/src/ofw/sbus.c \
genarch/src/ofw/upa.c
endif
 
ifeq ($(CONFIG_MULTIBOOT), y)
GENARCH_SOURCES += \
genarch/src/multiboot/multiboot.c
endif
 
ifeq ($(CONFIG_EGA), y)
GENARCH_SOURCES += \
genarch/src/drivers/ega/ega.c
endif
/branches/arm/kernel/doc/mm
5,10 → 5,10
 
1.1 Hierarchical 4-level per address space page tables
 
SPARTAN kernel deploys generic interface for 4-level page tables
for these architectures: amd64, ia32, mips32 and ppc32. In this
setting, page tables are hierarchical and are not shared by
address spaces (i.e. one set of page tables per address space).
SPARTAN kernel deploys generic interface for 4-level page tables for these
architectures: amd64, arm32, ia32, mips32 and ppc32. In this setting, page
tables are hierarchical and are not shared by address spaces (i.e. one set of
page tables per address space).
 
 
VADDR
/branches/arm/kernel/Makefile
30,23 → 30,28
## Include configuration
#
 
-include ../version
-include Makefile.config
include ../version
-include ../Makefile.config
-include ../config.defs
 
INCLUDES = generic/include
OPTIMIZATION = 3
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
## Common compiler flags
#
 
DEFS = -D$(ARCH) -DARCH=\"$(ARCH)\" -DRELEASE=\"$(RELEASE)\" "-DNAME=\"$(NAME)\"" \
-DKERNEL
DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
 
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \
-nostdlib -nostdinc
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \
-Wmissing-prototypes -Werror -nostdlib -nostdinc -pipe
 
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
-fno-builtin -Wall -Wmissing-prototypes -Werror \
-nostdlib -nostdinc \
-wd170
58,15 → 63,7
LFLAGS = -M
AFLAGS =
 
ifdef REVISION
DEFS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
-include arch/$(ARCH)/Makefile.inc
-include arch/$(KARCH)/Makefile.inc
-include genarch/Makefile.inc
 
## The at-sign
84,76 → 81,6
#
SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;"
 
## Setup kernel configuration
#
ifeq ($(CONFIG_DEBUG),y)
DEFS += -DCONFIG_DEBUG
endif
 
ifeq ($(CONFIG_EDEBUG),y)
DEFS += -DCONFIG_EDEBUG
endif
 
ifeq ($(CONFIG_DEBUG_SPINLOCK),y)
DEFS += -DCONFIG_DEBUG_SPINLOCK
endif
 
ifeq ($(CONFIG_DEBUG_AS_WATCHPOINT),y)
DEFS += -DCONFIG_DEBUG_AS_WATCHPOINT
endif
 
ifeq ($(CONFIG_FPU_LAZY),y)
DEFS += -DCONFIG_FPU_LAZY
endif
 
ifeq ($(CONFIG_DEBUG_ALLREGS),y)
DEFS += -DCONFIG_DEBUG_ALLREGS
endif
 
ifeq ($(CONFIG_VHPT),y)
DEFS += -DCONFIG_VHPT
endif
 
ifeq ($(CONFIG_TSB),y)
DEFS += -DCONFIG_TSB
endif
 
ifeq ($(CONFIG_Z8530),y)
DEFS += -DCONFIG_Z8530
endif
 
ifeq ($(CONFIG_NS16550),y)
DEFS += -DCONFIG_NS16550
endif
 
ifeq ($(CONFIG_VIRT_IDX_DCACHE),y)
DEFS += -DCONFIG_VIRT_IDX_DCACHE
endif
 
ifeq ($(CONFIG_FB),y)
ifeq ($(ARCH),ia32)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
ifeq ($(ARCH),amd64)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
ifeq ($(ARCH),ia32xen)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
endif
 
ifeq ($(CONFIG_UDEBUG),y)
DEFS += -DCONFIG_UDEBUG
endif
 
## Simple detection for the type of the host system
#
HOST = $(shell uname)
178,6 → 105,7
OBJDUMP = $(BINUTILS_PREFIX)objdump
LIBDIR = /usr/lib
CFLAGS = $(GCC_CFLAGS)
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
ifeq ($(COMPILER),icc_native)
189,6 → 117,7
OBJDUMP = objdump
LIBDIR = /usr/lib
CFLAGS = $(ICC_CFLAGS)
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
ifeq ($(COMPILER),suncc_native)
200,6 → 129,8
OBJDUMP = $(BINUTILS_PREFIX)objdump
LIBDIR = /usr/lib
CFLAGS = $(SUNCC_CFLAGS)
DEFS += $(CONFIG_DEFS)
DEPEND_DEFS = $(DEFS)
endif
 
ifeq ($(COMPILER),gcc_cross)
211,6 → 142,7
OBJDUMP = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objdump
LIBDIR = $(TOOLCHAIN_DIR)/lib
CFLAGS = $(GCC_CFLAGS)
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
## Generic kernel sources
224,12 → 156,11
generic/src/adt/list.c \
generic/src/console/chardev.c \
generic/src/console/console.c \
generic/src/console/kconsole.c \
generic/src/console/cmd.c \
generic/src/cpu/cpu.c \
generic/src/ddi/ddi.c \
generic/src/ddi/irq.c \
generic/src/ddi/device.c \
generic/src/debug/symtab.c \
generic/src/interrupt/interrupt.c \
generic/src/main/main.c \
generic/src/main/kinit.c \
256,16 → 187,14
generic/src/lib/func.c \
generic/src/lib/memstr.c \
generic/src/lib/sort.c \
generic/src/lib/string.c \
generic/src/lib/elf.c \
generic/src/lib/rd.c \
generic/src/printf/printf_core.c \
generic/src/printf/printf.c \
generic/src/printf/sprintf.c \
generic/src/printf/snprintf.c \
generic/src/printf/vprintf.c \
generic/src/printf/vsprintf.c \
generic/src/printf/vsnprintf.c \
generic/src/debug/symtab.c \
generic/src/time/clock.c \
generic/src/time/timeout.c \
generic/src/time/delay.c \
284,9 → 213,19
generic/src/ipc/sysipc.c \
generic/src/ipc/ipcrsc.c \
generic/src/ipc/irq.c \
generic/src/ipc/event.c \
generic/src/security/cap.c \
generic/src/sysinfo/sysinfo.c
 
## Kernel console support
#
 
ifeq ($(CONFIG_KCONSOLE),y)
GENERIC_SOURCES += \
generic/src/console/kconsole.c \
generic/src/console/cmd.c
endif
 
## Udebug interface sources
#
 
302,7 → 241,6
#
 
ifeq ($(CONFIG_TEST),y)
DEFS += -DCONFIG_TEST
CFLAGS += -Itest/
GENERIC_SOURCES += \
test/test.c \
309,17 → 247,12
test/atomic/atomic1.c \
test/btree/btree1.c \
test/avltree/avltree1.c \
test/debug/mips1.c \
test/fault/fault1.c \
test/fpu/fpu1.c \
test/fpu/sse1.c \
test/fpu/mips2.c \
test/mm/falloc1.c \
test/mm/falloc2.c \
test/mm/mapping1.c \
test/mm/slab1.c \
test/mm/slab2.c \
test/mm/purge1.c \
test/synch/rwlock1.c \
test/synch/rwlock2.c \
test/synch/rwlock3.c \
328,8 → 261,63
test/synch/semaphore1.c \
test/synch/semaphore2.c \
test/print/print1.c \
test/print/print2.c \
test/print/print3.c \
test/print/print4.c \
test/thread/thread1.c \
test/sysinfo/sysinfo1.c
ifeq ($(KARCH),mips32)
GENERIC_SOURCES += test/debug/mips1.c
else
GENERIC_SOURCES += test/debug/mips1_skip.c
endif
ifeq ($(KARCH),ia64)
GENERIC_SOURCES += test/mm/purge1.c
else
GENERIC_SOURCES += test/mm/purge1_skip.c
endif
ifeq ($(CONFIG_FPU),y)
ifeq ($(KARCH),ia32)
TEST_FPU1 = y
TEST_SSE1 = y
GENERIC_SOURCES += test/fpu/fpu1_x86.c
endif
ifeq ($(KARCH),amd64)
TEST_FPU1 = y
TEST_SSE1 = y
GENERIC_SOURCES += test/fpu/fpu1_x86.c
endif
ifeq ($(KARCH),ia64)
TEST_FPU1 = y
GENERIC_SOURCES += test/fpu/fpu1_ia64.c
endif
ifeq ($(KARCH),mips32)
TEST_MIPS2 = y
endif
endif
ifneq ($(TEST_FPU1),y)
GENERIC_SOURCES += test/fpu/fpu1_skip.c
endif
ifeq ($(TEST_SSE1),y)
GENERIC_SOURCES += test/fpu/sse1.c
else
GENERIC_SOURCES += test/fpu/sse1_skip.c
endif
ifeq ($(TEST_MIPS2),y)
GENERIC_SOURCES += test/fpu/mips2.c
else
GENERIC_SOURCES += test/fpu/mips2_skip.c
endif
endif
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
336,25 → 324,24
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
.PHONY: all build config distclean clean archlinks depend disasm
ifeq ($(CONFIG_SYMTAB),y)
SYMTAB_OBJECTS := generic/src/debug/real_map.o
else
SYMTAB_OBJECTS :=
endif
 
all:
../tools/config.py kernel.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(MACHINE)
.PHONY: all build clean archlinks depend disasm
 
all: ../Makefile.config ../config.h ../config.defs
-rm Makefile.depend
$(MAKE) -C . build
 
build: kernel.bin disasm
 
config:
-rm Makefile.depend
../tools/config.py kernel.config
 
-include Makefile.depend
 
distclean: clean
-rm Makefile.config
 
clean:
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(ARCH)/_link.ld
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(KARCH)/_link.ld
find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
for arch in arch/* ; do \
[ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \
361,24 → 348,24
done ; exit 0
 
archlinks:
ln -sfn ../../arch/$(ARCH)/include/ generic/include/arch
ln -sfn ../../arch/$(KARCH)/include/ generic/include/arch
ln -sfn ../../genarch/include/ generic/include/genarch
 
depend: archlinks
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
arch/$(KARCH)/_link.ld: arch/$(KARCH)/_link.ld.in
$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@
 
generic/src/debug/real_map.bin: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
generic/src/debug/real_map.bin: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o generic/src/debug/empty_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
# Do it once again, this time to get correct even the symbols
# on architectures, that have bss after symtab
echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o generic/src/debug/sizeok_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
 
385,8 → 372,8
generic/src/debug/real_map.o: generic/src/debug/real_map.bin
echo $(SYMTAB_SECTION)" .incbin \"$<\"" | $(AS) $(AFLAGS) -o $@
 
kernel.raw: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/real_map.o -o $@ -Map kernel.map
kernel.raw: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS) -o $@ -Map kernel.map
 
kernel.bin: kernel.raw
$(OBJCOPY) -O $(BFD) kernel.raw kernel.bin
/branches/arm/kernel/test/avltree/avltree1.c
41,7 → 41,7
*/
static avltree_node_t avltree_nodes[NODE_COUNT];
 
/*
/*
* head of free nodes' list:
*/
static avltree_node_t *first_free_node = NULL;
58,11 → 58,11
if (!node)
return NULL;
 
if (node->lft) {
tmp = test_tree_parents(node->lft);
if (tmp != node) {
printf("Bad parent pointer key: %" PRIu64
TPRINTF("Bad parent pointer key: %" PRIu64
", address: %p\n", tmp->key, node->lft);
}
}
69,7 → 69,7
if (node->rgt) {
tmp = test_tree_parents(node->rgt);
if (tmp != node) {
printf("Bad parent pointer key: %" PRIu64
TPRINTF("Bad parent pointer key: %" PRIu64
", address: %p\n",
tmp->key,node->rgt);
}
80,49 → 80,50
int test_tree_balance(avltree_node_t *node)
{
int h1, h2, diff;
 
if (!node)
return 0;
h1 = test_tree_balance(node->lft);
h2 = test_tree_balance(node->rgt);
diff = h2 - h1;
if (diff != node->balance || (diff != -1 && diff != 0 && diff != 1)) {
printf("Bad balance\n");
}
return h1 > h2 ? h1 + 1 : h2 + 1;
if ((diff != node->balance) || ((diff != -1) && (diff != 0) && (diff != 1)))
TPRINTF("Bad balance\n");
return ((h1 > h2) ? (h1 + 1) : (h2 + 1));
}
 
/**
* Prints the structure of the node, which is level levels from the top of the
* tree.
* tree.
*/
static void
print_tree_structure_flat(avltree_node_t *node, int level)
static void print_tree_structure_flat(avltree_node_t *node, int level)
{
/*
* You can set the maximum level as high as you like.
* Most of the time, you'll want to debug code using small trees,
* so that a large level indicates a loop, which is a bug.
* Most of the time, you'll want to debug code using small trees,
* so that a large level indicates a loop, which is a bug.
*/
if (level > 16) {
printf("[...]");
TPRINTF("[...]");
return;
}
 
if (node == NULL)
return;
 
printf("%" PRIu64 "[%" PRIu8 "]", node->key, node->balance);
TPRINTF("%" PRIu64 "[%" PRIu8 "]", node->key, node->balance);
if (node->lft != NULL || node->rgt != NULL) {
printf("(");
 
TPRINTF("(");
print_tree_structure_flat(node->lft, level + 1);
if (node->rgt != NULL) {
printf(",");
TPRINTF(",");
print_tree_structure_flat(node->rgt, level + 1);
}
 
printf(")");
TPRINTF(")");
}
}
 
129,10 → 130,10
static void alloc_avltree_node_prepare(void)
{
int i;
 
for (i = 0; i < NODE_COUNT - 1; i++) {
for (i = 0; i < NODE_COUNT - 1; i++)
avltree_nodes[i].par = &avltree_nodes[i + 1];
}
avltree_nodes[i].par = NULL;
/*
139,37 → 140,44
* Node keys which will be used for insertion. Up to NODE_COUNT size of
* array.
*/
 
/* First tree node and same key */
avltree_nodes[0].key = 60;
avltree_nodes[1].key = 60;
avltree_nodes[2].key = 60;
/* LL rotation */
avltree_nodes[3].key = 50;
avltree_nodes[4].key = 40;
avltree_nodes[5].key = 30;
/* LR rotation */
avltree_nodes[6].key = 20;
avltree_nodes[7].key = 20;
avltree_nodes[8].key = 25;
avltree_nodes[9].key = 25;
/* LL rotation in lower floor */
avltree_nodes[10].key = 35;
/* RR rotation */
avltree_nodes[11].key = 70;
avltree_nodes[12].key = 80;
/* RL rotation */
avltree_nodes[13].key = 90;
avltree_nodes[14].key = 85;
/* Insert 0 key */
avltree_nodes[15].key = 0;
avltree_nodes[16].key = 0;
/* Insert reverse */
avltree_nodes[17].key = 600;
avltree_nodes[18].key = 500;
avltree_nodes[19].key = 400;
avltree_nodes[20].key = 300;
 
for (i = 21; i < NODE_COUNT; i++)
avltree_nodes[i].key = i * 3;
179,40 → 187,35
static avltree_node_t *alloc_avltree_node(void)
{
avltree_node_t *node;
 
node = first_free_node;
first_free_node = first_free_node->par;
 
return node;
}
 
static void test_tree_insert(avltree_t *tree, count_t node_count, bool quiet)
static void test_tree_insert(avltree_t *tree, size_t node_count)
{
unsigned int i;
avltree_node_t *newnode;
 
avltree_create(tree);
if (!quiet)
printf("Inserting %" PRIc " nodes...", node_count);
 
TPRINTF("Inserting %" PRIs " nodes...", node_count);
for (i = 0; i < node_count; i++) {
newnode = alloc_avltree_node();
avltree_insert(tree, newnode);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
}
 
 
static void test_tree_delete(avltree_t *tree, count_t node_count,
int node_position, bool quiet)
static void test_tree_delete(avltree_t *tree, size_t node_count,
int node_position)
{
avltree_node_t *delnode;
unsigned int i;
219,71 → 222,61
switch (node_position) {
case 0:
if (!quiet)
printf("Deleting root nodes...");
TPRINTF("Deleting root nodes...");
while (tree->root != NULL) {
delnode = tree->root;
avltree_delete(tree, delnode);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
break;
case 1:
if (!quiet)
printf("Deleting nodes according to creation time...");
TPRINTF("Deleting nodes according to creation time...");
for (i = 0; i < node_count; i++) {
avltree_delete(tree, &avltree_nodes[i]);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
break;
break;
}
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
}
 
static void test_tree_delmin(avltree_t *tree, count_t node_count, bool quiet)
static void test_tree_delmin(avltree_t *tree, size_t node_count)
{
unsigned int i = 0;
if (!quiet)
printf("Deleting minimum nodes...");
TPRINTF("Deleting minimum nodes...");
while (tree->root != NULL) {
i++;
avltree_delete_min(tree);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
 
if (!quiet && (i != node_count))
printf("Bad node count. Some nodes have been lost!\n");
 
if (!quiet)
printf("done.\n");
if (i != node_count)
TPRINTF("Bad node count. Some nodes have been lost!\n");
TPRINTF("done.\n");
}
 
char *test_avltree1(bool quiet)
char *test_avltree1(void)
{
alloc_avltree_node_prepare();
test_tree_insert(&avltree, NODE_COUNT, quiet);
test_tree_delete(&avltree, NODE_COUNT, 0, quiet);
 
test_tree_insert(&avltree, NODE_COUNT);
test_tree_delete(&avltree, NODE_COUNT, 0);
alloc_avltree_node_prepare();
test_tree_insert(&avltree, NODE_COUNT, quiet);
test_tree_delete(&avltree, NODE_COUNT, 1, quiet);
 
test_tree_insert(&avltree, NODE_COUNT);
test_tree_delete(&avltree, NODE_COUNT, 1);
alloc_avltree_node_prepare();
test_tree_insert(&avltree, NODE_COUNT, quiet);
test_tree_delmin(&avltree, NODE_COUNT, quiet);
 
test_tree_insert(&avltree, NODE_COUNT);
test_tree_delmin(&avltree, NODE_COUNT);
return NULL;
}
 
/branches/arm/kernel/test/avltree/avltree1.def
1,6 → 1,6
{
"avltree1",
"Test Avl tree operations",
"Test AVL tree operations",
&test_avltree1,
true
},
/branches/arm/kernel/test/synch/rwlock4.c
40,13 → 40,12
#include <synch/synch.h>
#include <synch/spinlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static atomic_t thread_count;
static rwlock_t rwlock;
static atomic_t threads_fault;
static bool sh_quiet;
 
SPINLOCK_INITIALIZE(rw_lock);
 
57,10 → 56,10
static uint32_t random(uint32_t max)
{
uint32_t rc;
 
spinlock_lock(&rw_lock);
spinlock_lock(&rw_lock);
rc = seed % max;
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc;
seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc;
spinlock_unlock(&rw_lock);
return rc;
}
70,43 → 69,39
int rc, to;
thread_detach(THREAD);
waitq_sleep(&can_start);
 
to = random(40000);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w+ (%d)\n", CPU->id, THREAD->tid, to);
TPRINTF("cpu%u, tid %" PRIu64 " w+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_write_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w!\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " w!\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
return;
}
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w=\n", CPU->id, THREAD->tid);
 
TPRINTF("cpu%u, tid %" PRIu64 " w=\n", CPU->id, THREAD->tid);
if (rwlock.readers_in) {
if (!sh_quiet)
printf("Oops.");
TPRINTF("Oops.\n");
atomic_inc(&threads_fault);
atomic_dec(&thread_count);
return;
}
thread_usleep(random(1000000));
if (rwlock.readers_in) {
if (!sh_quiet)
printf("Oops.");
TPRINTF("Oops.\n");
atomic_inc(&threads_fault);
atomic_dec(&thread_count);
return;
}
 
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w-\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " w-\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
118,33 → 113,28
to = random(2000);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r+ (%d)\n", CPU->id, THREAD->tid, to);
TPRINTF("cpu%u, tid %" PRIu64 " r+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_read_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r!\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " r!\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
return;
}
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r=\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " r=\n", CPU->id, THREAD->tid);
thread_usleep(30000);
rwlock_read_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r-\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " r-\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
char * test_rwlock4(bool quiet)
char *test_rwlock4(void)
{
context_t ctx;
uint32_t i;
sh_quiet = quiet;
waitq_initialize(&can_start);
rwlock_initialize(&rwlock);
158,28 → 148,25
thread_t *thrd;
context_save(&ctx);
if (!quiet) {
printf("sp=%#x, readers_in=%" PRIc "\n", ctx.sp, rwlock.readers_in);
printf("Creating %" PRIu32 " readers\n", rd);
}
TPRINTF("sp=%#x, readers_in=%" PRIs "\n", ctx.sp, rwlock.readers_in);
TPRINTF("Creating %" PRIu32 " readers\n", rd);
for (i = 0; i < rd; i++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
if (thrd)
thread_ready(thrd);
else if (!quiet)
printf("Could not create reader %" PRIu32 "\n", i);
else
TPRINTF("Could not create reader %" PRIu32 "\n", i);
}
 
if (!quiet)
printf("Creating %" PRIu32 " writers\n", wr);
TPRINTF("Creating %" PRIu32 " writers\n", wr);
for (i = 0; i < wr; i++) {
thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
if (thrd)
thread_ready(thrd);
else if (!quiet)
printf("Could not create writer %" PRIu32 "\n", i);
else
TPRINTF("Could not create writer %" PRIu32 "\n", i);
}
thread_usleep(20000);
186,8 → 173,7
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&thread_count) > 0) {
if (!quiet)
printf("Threads left: %ld\n", atomic_get(&thread_count));
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
thread_sleep(1);
}
/branches/arm/kernel/test/synch/rwlock1.c
35,39 → 35,39
#include <synch/waitq.h>
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
char * test_rwlock1(bool quiet)
char *test_rwlock1(void)
{
rwlock_initialize(&rwlock);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_write_unlock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_write_unlock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_write_unlock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
/branches/arm/kernel/test/synch/rwlock2.c
34,38 → 34,34
 
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
static bool sh_quiet;
 
static void writer(void *arg)
{
if (!sh_quiet)
printf("Trying to lock rwlock for writing....\n");
TPRINTF("Trying to lock rwlock for writing....\n");
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("Trying to lock rwlock for reading....\n");
TPRINTF("Trying to lock rwlock for reading....\n");
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
}
 
char * test_rwlock2(bool quiet)
char *test_rwlock2(void)
{
thread_t *thrd;
sh_quiet = quiet;
rwlock_initialize(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
if (thrd)
72,7 → 68,7
thread_ready(thrd);
else
return "Could not create thread";
 
thread_sleep(1);
rwlock_read_unlock(&rwlock);
/branches/arm/kernel/test/synch/rwlock3.c
34,41 → 34,35
 
#include <synch/rwlock.h>
 
#define THREADS 4
#define THREADS 4
 
static atomic_t thread_count;
static rwlock_t rwlock;
static bool sh_quiet;
 
static void reader(void *arg)
{
thread_detach(THREAD);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 ": trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 ": trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
if (!sh_quiet) {
printf("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
printf("cpu%u, tid %" PRIu64 ": trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
}
 
TPRINTF("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 ": trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
char * test_rwlock3(bool quiet)
char *test_rwlock3(void)
{
int i;
thread_t *thrd;
sh_quiet = quiet;
atomic_set(&thread_count, THREADS);
79,16 → 73,15
thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
if (thrd)
thread_ready(thrd);
else if (!quiet)
printf("Could not create reader %d\n", i);
else
TPRINTF("Could not create reader %d\n", i);
}
 
thread_sleep(1);
rwlock_write_unlock(&rwlock);
while (atomic_get(&thread_count) > 0) {
if (!quiet)
printf("Threads left: %ld\n", atomic_get(&thread_count));
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
thread_sleep(1);
}
/branches/arm/kernel/test/synch/semaphore1.c
35,9 → 35,9
#include <synch/waitq.h>
#include <synch/semaphore.h>
 
#define AT_ONCE 3
#define PRODUCERS 50
#define CONSUMERS 50
#define AT_ONCE 3
#define PRODUCERS 50
#define CONSUMERS 50
 
static semaphore_t sem;
 
47,10 → 47,10
 
static void producer(void *arg)
{
thread_detach(THREAD);
 
thread_detach(THREAD);
waitq_sleep(&can_start);
semaphore_down(&sem);
atomic_inc(&items_produced);
thread_usleep(250);
59,7 → 59,7
 
static void consumer(void *arg)
{
thread_detach(THREAD);
thread_detach(THREAD);
waitq_sleep(&can_start);
69,7 → 69,7
semaphore_up(&sem);
}
 
char * test_semaphore1(bool quiet)
char *test_semaphore1(void)
{
int i, j, k;
int consumers, producers;
76,10 → 76,10
waitq_initialize(&can_start);
semaphore_initialize(&sem, AT_ONCE);
 
for (i = 1; i <= 3; i++) {
thread_t *thrd;
 
atomic_set(&items_produced, 0);
atomic_set(&items_consumed, 0);
86,8 → 86,8
consumers = i * CONSUMERS;
producers = (4 - i) * PRODUCERS;
printf("Creating %d consumers and %d producers...", consumers, producers);
TPRINTF("Creating %d consumers and %d producers...", consumers, producers);
for (j = 0; j < (CONSUMERS + PRODUCERS) / 2; j++) {
for (k = 0; k < i; k++) {
thrd = thread_create(consumer, NULL, TASK, 0, "consumer", false);
94,7 → 94,7
if (thrd)
thread_ready(thrd);
else
printf("could not create consumer %d\n", i);
TPRINTF("could not create consumer %d\n", i);
}
for (k = 0; k < (4 - i); k++) {
thrd = thread_create(producer, NULL, TASK, 0, "producer", false);
101,17 → 101,17
if (thrd)
thread_ready(thrd);
else
printf("could not create producer %d\n", i);
TPRINTF("could not create producer %d\n", i);
}
}
 
printf("ok\n");
 
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while ((items_consumed.count != consumers) || (items_produced.count != producers)) {
printf("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);
TPRINTF("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);
thread_sleep(1);
}
}
/branches/arm/kernel/test/synch/semaphore2.c
50,10 → 50,10
static uint32_t random(uint32_t max)
{
uint32_t rc;
 
spinlock_lock(&sem_lock);
spinlock_lock(&sem_lock);
rc = seed % max;
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc;
seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc;
spinlock_unlock(&sem_lock);
return rc;
}
67,21 → 67,21
waitq_sleep(&can_start);
to = random(20000);
printf("cpu%u, tid %" PRIu64 " down+ (%d)\n", CPU->id, THREAD->tid, to);
TPRINTF("cpu%u, tid %" PRIu64 " down+ (%d)\n", CPU->id, THREAD->tid, to);
rc = semaphore_down_timeout(&sem, to);
if (SYNCH_FAILED(rc)) {
printf("cpu%u, tid %" PRIu64 " down!\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " down!\n", CPU->id, THREAD->tid);
return;
}
printf("cpu%u, tid %" PRIu64 " down=\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " down=\n", CPU->id, THREAD->tid);
thread_usleep(random(30000));
semaphore_up(&sem);
printf("cpu%u, tid %" PRIu64 " up\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " up\n", CPU->id, THREAD->tid);
}
 
char * test_semaphore2(bool quiet)
char *test_semaphore2(void)
{
uint32_t i, k;
91,13 → 91,13
thread_t *thrd;
k = random(7) + 1;
printf("Creating %" PRIu32 " consumers\n", k);
TPRINTF("Creating %" PRIu32 " consumers\n", k);
for (i = 0; i < k; i++) {
thrd = thread_create(consumer, NULL, TASK, 0, "consumer", false);
if (thrd)
thread_ready(thrd);
else
printf("Error creating thread\n");
TPRINTF("Error creating thread\n");
}
thread_usleep(20000);
/branches/arm/kernel/test/synch/rwlock5.c
35,8 → 35,8
#include <synch/waitq.h>
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
47,9 → 47,9
static void writer(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
 
rwlock_write_lock(&rwlock);
atomic_inc(&items_written);
rwlock_write_unlock(&rwlock);
58,7 → 58,7
static void reader(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
rwlock_read_lock(&rwlock);
66,7 → 66,7
rwlock_read_unlock(&rwlock);
}
 
char * test_rwlock5(bool quiet)
char *test_rwlock5(void)
{
int i, j, k;
long readers, writers;
76,15 → 76,15
for (i = 1; i <= 3; i++) {
thread_t *thrd;
 
atomic_set(&items_read, 0);
atomic_set(&items_written, 0);
 
readers = i * READERS;
writers = (4 - i) * WRITERS;
 
printf("Creating %ld readers and %ld writers...", readers, writers);
TPRINTF("Creating %ld readers and %ld writers...", readers, writers);
for (j = 0; j < (READERS + WRITERS) / 2; j++) {
for (k = 0; k < i; k++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
91,7 → 91,7
if (thrd)
thread_ready(thrd);
else
printf("Could not create reader %d\n", k);
TPRINTF("Could not create reader %d\n", k);
}
for (k = 0; k < (4 - i); k++) {
thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
98,17 → 98,17
if (thrd)
thread_ready(thrd);
else
printf("Could not create writer %d\n", k);
TPRINTF("Could not create writer %d\n", k);
}
}
 
printf("ok\n");
 
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while ((items_read.count != readers) || (items_written.count != writers)) {
printf("%d readers remaining, %d writers remaining, readers_in=%d\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in);
TPRINTF("%d readers remaining, %d writers remaining, readers_in=%d\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in);
thread_usleep(100000);
}
}
/branches/arm/kernel/test/mm/falloc2.c
39,26 → 39,24
#include <memstr.h>
#include <arch.h>
 
#define MAX_FRAMES 256
#define MAX_ORDER 8
#define MAX_FRAMES 256
#define MAX_ORDER 8
 
#define THREAD_RUNS 1
#define THREADS 8
#define THREAD_RUNS 1
#define THREADS 8
 
static atomic_t thread_count;
static atomic_t thread_fail;
static bool sh_quiet;
 
static void falloc(void * arg)
static void falloc(void *arg)
{
int order, run, allocated, i;
uint8_t val = THREAD->tid % THREADS;
index_t k;
size_t k;
void **frames = (void **) malloc(MAX_FRAMES * sizeof(void *), FRAME_ATOMIC);
if (frames == NULL) {
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id);
atomic_inc(&thread_fail);
atomic_dec(&thread_count);
return;
65,11 → 63,10
}
thread_detach(THREAD);
 
for (run = 0; run < THREAD_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
allocated = 0;
for (i = 0; i < (MAX_FRAMES >> order); i++) {
81,17 → 78,13
break;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
TPRINTF("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id);
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id);
for (i = 0; i < allocated; i++) {
for (k = 0; k <= (((index_t) FRAME_SIZE << order) - 1); k++) {
for (k = 0; k <= (((size_t) FRAME_SIZE << order) - 1); k++) {
if (((uint8_t *) frames[i])[k] != val) {
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIi "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIs "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
atomic_inc(&thread_fail);
goto cleanup;
}
99,32 → 92,28
frame_free(KA2PA(frames[i]));
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id);
}
}
 
cleanup:
cleanup:
free(frames);
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id);
atomic_dec(&thread_count);
}
 
char * test_falloc2(bool quiet)
char *test_falloc2(void)
{
unsigned int i;
sh_quiet = quiet;
 
atomic_set(&thread_count, THREADS);
atomic_set(&thread_fail, 0);
for (i = 0; i < THREADS; i++) {
thread_t * thrd = thread_create(falloc, NULL, TASK, 0, "falloc", false);
if (!thrd) {
if (!quiet)
printf("Could not create thread %u\n", i);
TPRINTF("Could not create thread %u\n", i);
break;
}
thread_ready(thrd);
131,8 → 120,7
}
while (atomic_get(&thread_count) > 0) {
if (!quiet)
printf("Threads left: %ld\n", atomic_get(&thread_count));
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
thread_sleep(1);
}
/branches/arm/kernel/test/mm/purge1.c
26,8 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifdef ia64
 
#include <print.h>
#include <test.h>
#include <mm/page.h>
39,18 → 37,18
#include <debug.h>
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t va, count_t cnt);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t va, size_t cnt);
 
char * test_purge1(bool quiet)
char *test_purge1(void)
{
tlb_entry_t entryi;
tlb_entry_t entryd;
int i;
entryd.word[0] = 0;
entryd.word[1] = 0;
entryd.p = true; /* present */
entryd.ma = MA_WRITEBACK;
entryd.a = true; /* already accessed */
77,11 → 75,9
dtc_mapping_insert(0 + i * (1 << PAGE_WIDTH), 9, entryd);
}
tlb_invalidate_pages(8,0x0c000,14);
tlb_invalidate_pages(8, 0x0c000, 14);
/*tlb_invalidate_all();*/
/* tlb_invalidate_all(); */
return NULL;
}
 
#endif
/branches/arm/kernel/test/mm/slab2.c
36,18 → 36,18
#include <synch/condvar.h>
#include <synch/mutex.h>
 
#define ITEM_SIZE 256
#define ITEM_SIZE 256
 
/** Fill memory with 2 caches, when allocation fails,
* free one of the caches. We should have everything in magazines,
* now allocation should clean magazines and allow for full allocation.
*/
static void totalmemtest(bool quiet)
static void totalmemtest(void)
{
slab_cache_t *cache1;
slab_cache_t *cache2;
int i;
 
void *data1, *data2;
void *olddata1 = NULL, *olddata2 = NULL;
54,8 → 54,7
cache1 = slab_cache_create("cache1_tst", ITEM_SIZE, 0, NULL, NULL, 0);
cache2 = slab_cache_create("cache2_tst", ITEM_SIZE, 0, NULL, NULL, 0);
if (!quiet)
printf("Allocating...");
TPRINTF("Allocating...");
/* Use atomic alloc, so that we find end of memory */
do {
74,13 → 73,12
*((void **) data2) = olddata2;
olddata1 = data1;
olddata2 = data2;
} while (1);
} while (true);
if (!quiet) {
printf("done.\n");
printf("Deallocating cache2...");
}
TPRINTF("done.\n");
TPRINTF("Deallocating cache2...");
/* We do not have memory - now deallocate cache2 */
while (olddata2) {
data2 = *((void **) olddata2);
88,16 → 86,14
olddata2 = data2;
}
if (!quiet) {
printf("done.\n");
printf("Allocating to cache1...\n");
}
TPRINTF("done.\n");
TPRINTF("Allocating to cache1...\n");
for (i = 0; i < 30; i++) {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
if (!data1) {
if (!quiet)
printf("Incorrect memory size - use another test.");
TPRINTF("Incorrect memory size - use another test.");
return;
}
memsetb(data1, ITEM_SIZE, 0);
104,7 → 100,7
*((void **) data1) = olddata1;
olddata1 = data1;
}
while (1) {
while (true) {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
if (!data1)
break;
113,8 → 109,7
olddata1 = data1;
}
if (!quiet)
printf("Deallocating cache1...");
TPRINTF("Deallocating cache1...");
while (olddata1) {
data1 = *((void **) olddata1);
122,10 → 117,10
olddata1 = data1;
}
if (!quiet) {
printf("done.\n");
TPRINTF("done.\n");
if (!test_quiet)
slab_print_list();
}
slab_cache_destroy(cache1);
slab_cache_destroy(cache2);
135,9 → 130,8
static semaphore_t thr_sem;
static condvar_t thread_starter;
static mutex_t starter_mutex;
static bool sh_quiet;
 
#define THREADS 8
#define THREADS 8
 
static void slabtest(void *priv)
{
149,14 → 143,12
condvar_wait(&thread_starter,&starter_mutex);
mutex_unlock(&starter_mutex);
if (!sh_quiet)
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid);
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid);
 
/* Alloc all */
if (!sh_quiet)
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
while (1) {
while (true) {
/* Call with atomic to detect end of memory */
new = slab_alloc(thr_cache, FRAME_ATOMIC);
if (!new)
165,8 → 157,7
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
175,10 → 166,9
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
while (1) {
while (true) {
/* Call with atomic to detect end of memory */
new = slab_alloc(thr_cache, FRAME_ATOMIC);
if (!new)
187,8 → 177,7
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
197,14 → 186,15
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " finished\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid);
slab_print_list();
if (!test_quiet)
slab_print_list();
semaphore_up(&thr_sem);
}
 
static void multitest(int size, bool quiet)
static void multitest(int size)
{
/* Start 8 threads that just allocate as much as possible,
* then release everything, then again allocate, then release
212,48 → 202,42
thread_t *t;
int i;
if (!quiet)
printf("Running stress test with size %d\n", size);
TPRINTF("Running stress test with size %d\n", size);
condvar_initialize(&thread_starter);
mutex_initialize(&starter_mutex, MUTEX_PASSIVE);
 
thr_cache = slab_cache_create("thread_cache", size, 0, NULL, NULL, 0);
semaphore_initialize(&thr_sem,0);
for (i = 0; i < THREADS; i++) {
if (!(t = thread_create(slabtest, NULL, TASK, 0, "slabtest", false))) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("Could not create thread %d\n", i);
} else
thread_ready(t);
}
thread_sleep(1);
condvar_broadcast(&thread_starter);
 
for (i = 0; i < THREADS; i++)
semaphore_down(&thr_sem);
slab_cache_destroy(thr_cache);
if (!quiet)
printf("Stress test complete.\n");
TPRINTF("Stress test complete.\n");
}
 
char * test_slab2(bool quiet)
char *test_slab2(void)
{
sh_quiet = quiet;
TPRINTF("Running reclaim single-thread test .. pass 1\n");
totalmemtest();
if (!quiet)
printf("Running reclaim single-thread test .. pass 1\n");
totalmemtest(quiet);
if (!quiet)
printf("Running reclaim single-thread test .. pass 2\n");
totalmemtest(quiet);
if (!quiet)
printf("Reclaim test OK.\n");
TPRINTF("Running reclaim single-thread test .. pass 2\n");
totalmemtest();
multitest(128, quiet);
multitest(2048, quiet);
multitest(8192, quiet);
TPRINTF("Reclaim test OK.\n");
multitest(128);
multitest(2048);
multitest(8192);
return NULL;
}
/branches/arm/kernel/test/mm/falloc1.c
36,12 → 36,13
#include <debug.h>
#include <align.h>
 
#define MAX_FRAMES 1024
#define MAX_ORDER 8
#define TEST_RUNS 2
#define MAX_FRAMES 1024
#define MAX_ORDER 8
#define TEST_RUNS 2
 
char * test_falloc1(bool quiet) {
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), 0);
char *test_falloc1(void) {
uintptr_t *frames
= (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), 0);
int results[MAX_ORDER + 1];
int i, order, run;
52,11 → 53,10
if (frames == NULL)
return "Unable to allocate frames";
 
for (run = 0; run < TEST_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
if (!quiet)
printf("Allocating %d frames blocks ... ", 1 << order);
TPRINTF("Allocating %d frames blocks ... ", 1 << order);
allocated = 0;
for (i = 0; i < MAX_FRAMES >> order; i++) {
63,8 → 63,7
frames[allocated] = (uintptr_t) frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) {
if (!quiet)
printf("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10);
TPRINTF("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10);
return "Test failed";
}
71,15 → 70,13
if (frames[allocated])
allocated++;
else {
if (!quiet)
printf("done. ");
TPRINTF("done. ");
break;
}
}
if (!quiet)
printf("%d blocks allocated.\n", allocated);
TPRINTF("%d blocks allocated.\n", allocated);
if (run) {
if (results[order] != allocated)
return "Possible frame leak";
86,17 → 83,15
} else
results[order] = allocated;
if (!quiet)
printf("Deallocating ... ");
TPRINTF("Deallocating ... ");
for (i = 0; i < allocated; i++)
frame_free(KA2PA(frames[i]));
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
}
}
 
free(frames);
return NULL;
/branches/arm/kernel/test/mm/slab1.c
33,23 → 33,21
#include <arch.h>
#include <memstr.h>
 
#define VAL_COUNT 1024
#define VAL_COUNT 1024
 
static void * data[VAL_COUNT];
static void *data[VAL_COUNT];
 
static void testit(int size, int count, bool quiet)
static void testit(int size, int count)
{
slab_cache_t *cache;
int i;
if (!quiet)
printf("Creating cache, object size: %d.\n", size);
TPRINTF("Creating cache, object size: %d.\n", size);
cache = slab_cache_create("test_cache", size, 0, NULL, NULL,
SLAB_CACHE_NOMAGAZINE);
SLAB_CACHE_NOMAGAZINE);
if (!quiet)
printf("Allocating %d items...", count);
TPRINTF("Allocating %d items...", count);
for (i = 0; i < count; i++) {
data[i] = slab_alloc(cache, 0);
56,78 → 54,71
memsetb(data[i], size, 0);
}
if (!quiet) {
printf("done.\n");
printf("Freeing %d items...", count);
}
TPRINTF("done.\n");
TPRINTF("Freeing %d items...", count);
for (i = 0; i < count; i++)
slab_free(cache, data[i]);
if (!quiet) {
printf("done.\n");
printf("Allocating %d items...", count);
}
TPRINTF("done.\n");
TPRINTF("Allocating %d items...", count);
for (i = 0; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb(data[i], size, 0);
}
if (!quiet) {
printf("done.\n");
printf("Freeing %d items...", count / 2);
}
TPRINTF("done.\n");
TPRINTF("Freeing %d items...", count / 2);
for (i = count - 1; i >= count / 2; i--)
slab_free(cache, data[i]);
if (!quiet) {
printf("done.\n");
printf("Allocating %d items...", count / 2);
}
TPRINTF("done.\n");
TPRINTF("Allocating %d items...", count / 2);
for (i = count / 2; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb(data[i], size, 0);
}
if (!quiet) {
printf("done.\n");
printf("Freeing %d items...", count);
}
TPRINTF("done.\n");
TPRINTF("Freeing %d items...", count);
for (i = 0; i < count; i++)
slab_free(cache, data[i]);
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
slab_cache_destroy(cache);
if (!quiet)
printf("Test complete.\n");
TPRINTF("Test complete.\n");
}
 
static void testsimple(bool quiet)
static void testsimple(void)
{
testit(100, VAL_COUNT, quiet);
testit(200, VAL_COUNT, quiet);
testit(1024, VAL_COUNT, quiet);
testit(2048, 512, quiet);
testit(4000, 128, quiet);
testit(8192, 128, quiet);
testit(16384, 128, quiet);
testit(16385, 128, quiet);
testit(100, VAL_COUNT);
testit(200, VAL_COUNT);
testit(1024, VAL_COUNT);
testit(2048, 512);
testit(4000, 128);
testit(8192, 128);
testit(16384, 128);
testit(16385, 128);
}
 
#define THREADS 6
#define THR_MEM_COUNT 1024
#define THR_MEM_SIZE 128
#define THREADS 6
#define THR_MEM_COUNT 1024
#define THR_MEM_SIZE 128
 
static void * thr_data[THREADS][THR_MEM_COUNT];
static void *thr_data[THREADS][THR_MEM_COUNT];
static slab_cache_t *thr_cache;
static semaphore_t thr_sem;
static bool sh_quiet;
 
static void slabtest(void *data)
{
136,8 → 127,7
thread_detach(THREAD);
if (!sh_quiet)
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid);
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid);
for (j = 0; j < 10; j++) {
for (i = 0; i < THR_MEM_COUNT; i++)
150,24 → 140,23
slab_free(thr_cache, thr_data[offs][i]);
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " finished\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid);
semaphore_up(&thr_sem);
}
 
static void testthreads(bool quiet)
static void testthreads(void)
{
thread_t *t;
int i;
 
thr_cache = slab_cache_create("thread_cache", THR_MEM_SIZE, 0, NULL, NULL,
SLAB_CACHE_NOMAGAZINE);
SLAB_CACHE_NOMAGAZINE);
semaphore_initialize(&thr_sem, 0);
for (i = 0; i < THREADS; i++) {
if (!(t = thread_create(slabtest, (void *) (unative_t) i, TASK, 0, "slabtest", false))) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("Could not create thread %d\n", i);
} else
thread_ready(t);
}
177,16 → 166,13
slab_cache_destroy(thr_cache);
if (!quiet)
printf("Test complete.\n");
TPRINTF("Test complete.\n");
}
 
char * test_slab1(bool quiet)
char *test_slab1(void)
{
sh_quiet = quiet;
testsimple();
testthreads();
testsimple(quiet);
testthreads(quiet);
return NULL;
}
/branches/arm/kernel/test/mm/purge1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <test.h>
 
char *test_purge1(void)
{
return NULL;
}
/branches/arm/kernel/test/mm/mapping1.c
35,40 → 35,36
#include <arch/types.h>
#include <debug.h>
 
#define PAGE0 0x10000000
#define PAGE1 (PAGE0+PAGE_SIZE)
#define PAGE0 0x10000000
#define PAGE1 (PAGE0 + PAGE_SIZE)
 
#define VALUE0 0x01234567
#define VALUE1 0x89abcdef
#define VALUE0 0x01234567
#define VALUE1 0x89abcdef
 
char * test_mapping1(bool quiet)
char *test_mapping1(void)
{
uintptr_t frame0, frame1;
uint32_t v0, v1;
 
frame0 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
frame1 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
if (!quiet)
printf("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0));
TPRINTF("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0));
*((uint32_t *) frame0) = VALUE0;
if (!quiet)
printf("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1));
TPRINTF("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1));
*((uint32_t *) frame1) = VALUE1;
if (!quiet)
printf("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0));
TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0));
page_mapping_insert(AS_KERNEL, PAGE0, KA2PA(frame0), PAGE_PRESENT | PAGE_WRITE);
if (!quiet)
printf("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1));
TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1));
page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE);
v0 = *((uint32_t *) PAGE0);
v1 = *((uint32_t *) PAGE1);
if (!quiet) {
printf("Value at virtual address %p is %#x.\n", PAGE0, v0);
printf("Value at virtual address %p is %#x.\n", PAGE1, v1);
}
TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, v0);
TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, v1);
if (v0 != VALUE0)
return "Value at v0 not equal to VALUE0";
75,25 → 71,22
if (v1 != VALUE1)
return "Value at v1 not equal to VALUE1";
if (!quiet)
printf("Writing %#x to virtual address %p.\n", 0, PAGE0);
TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE0);
*((uint32_t *) PAGE0) = 0;
if (!quiet)
printf("Writing %#x to virtual address %p.\n", 0, PAGE1);
*((uint32_t *) PAGE1) = 0;
 
TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE1);
*((uint32_t *) PAGE1) = 0;
v0 = *((uint32_t *) PAGE0);
v1 = *((uint32_t *) PAGE1);
if (!quiet) {
printf("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0));
printf("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1));
}
 
TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0));
TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1));
if (v0 != 0)
return "Value at v0 not equal to 0";
if (v1 != 0)
return "Value at v1 not equal to 0";
return NULL;
return NULL;
}
/branches/arm/kernel/test/mm/purge1.def
1,4 → 1,3
#ifdef ia64
{
"purge1",
"Itanium TLB purge test",
5,4 → 4,3
&test_purge1,
true
},
#endif
/branches/arm/kernel/test/test.c
34,6 → 34,8
 
#include <test.h>
 
bool test_quiet;
 
test_t tests[] = {
#include <atomic/atomic1.def>
#include <avltree/avltree1.def>
56,11 → 58,14
#include <synch/semaphore1.def>
#include <synch/semaphore2.def>
#include <print/print1.def>
#include <print/print2.def>
#include <print/print3.def>
#include <print/print4.def>
#include <thread/thread1.def>
#include <sysinfo/sysinfo1.def>
{
.name = NULL,
.desc = NULL,
.desc = NULL,
.entry = NULL
}
};
/branches/arm/kernel/test/btree/btree1.c
33,15 → 33,14
 
static void *data = (void *) 0xdeadbeef;
 
char * test_btree1(bool quiet)
char *test_btree1(void)
{
btree_t t;
int i;
 
btree_create(&t);
if (!quiet)
printf("Inserting keys.\n");
TPRINTF("Inserting keys.\n");
btree_insert(&t, 19, data, NULL);
btree_insert(&t, 20, data, NULL);
btree_insert(&t, 21, data, NULL);
78,11 → 77,10
for (i = 100; i >= 50; i--)
btree_insert(&t, i, data, NULL);
if (!quiet)
if (!test_quiet)
btree_print(&t);
if (!quiet)
printf("Removing keys.\n");
TPRINTF("Removing keys.\n");
btree_remove(&t, 50, NULL);
btree_remove(&t, 49, NULL);
btree_remove(&t, 51, NULL);
158,7 → 156,7
btree_remove(&t, 35, NULL);
btree_remove(&t, 36, NULL);
if (!quiet)
if (!test_quiet)
btree_print(&t);
return NULL;
/branches/arm/kernel/test/test.h
38,8 → 38,17
#include <arch/types.h>
#include <typedefs.h>
 
typedef char *(*test_entry_t)(bool);
extern bool test_quiet;
 
#define TPRINTF(format, ...) \
{ \
if (!test_quiet) { \
printf(format, ##__VA_ARGS__); \
} \
}
 
typedef char *(*test_entry_t)(void);
 
typedef struct {
char *name;
char *desc;
47,30 → 56,33
bool safe;
} test_t;
 
extern char * test_atomic1(bool quiet);
extern char * test_avltree1(bool quiet);
extern char * test_btree1(bool quiet);
extern char * test_mips1(bool quiet);
extern char * test_fault1(bool quiet);
extern char * test_fpu1(bool quiet);
extern char * test_sse1(bool quiet);
extern char * test_mips2(bool quiet);
extern char * test_falloc1(bool quiet);
extern char * test_falloc2(bool quiet);
extern char * test_mapping1(bool quiet);
extern char * test_purge1(bool quiet);
extern char * test_slab1(bool quiet);
extern char * test_slab2(bool quiet);
extern char * test_rwlock1(bool quiet);
extern char * test_rwlock2(bool quiet);
extern char * test_rwlock3(bool quiet);
extern char * test_rwlock4(bool quiet);
extern char * test_rwlock5(bool quiet);
extern char * test_semaphore1(bool quiet);
extern char * test_semaphore2(bool quiet);
extern char * test_print1(bool quiet);
extern char * test_thread1(bool quiet);
extern char * test_sysinfo1(bool quiet);
extern char *test_atomic1(void);
extern char *test_avltree1(void);
extern char *test_btree1(void);
extern char *test_mips1(void);
extern char *test_fault1(void);
extern char *test_fpu1(void);
extern char *test_sse1(void);
extern char *test_mips2(void);
extern char *test_falloc1(void);
extern char *test_falloc2(void);
extern char *test_mapping1(void);
extern char *test_purge1(void);
extern char *test_slab1(void);
extern char *test_slab2(void);
extern char *test_rwlock1(void);
extern char *test_rwlock2(void);
extern char *test_rwlock3(void);
extern char *test_rwlock4(void);
extern char *test_rwlock5(void);
extern char *test_semaphore1(void);
extern char *test_semaphore2(void);
extern char *test_print1(void);
extern char *test_print2(void);
extern char *test_print3(void);
extern char *test_print4(void);
extern char *test_thread1(void);
extern char *test_sysinfo1(void);
 
extern test_t tests[];
 
/branches/arm/kernel/test/debug/mips1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <test.h>
 
char *test_mips1(void)
{
return NULL;
}
/branches/arm/kernel/test/debug/mips1.c
25,8 → 25,6
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef mips32
 
#include <print.h>
#include <debug.h>
38,10 → 36,9
 
#include <arch.h>
 
char * test_mips1(bool quiet)
char *test_mips1(void)
{
if (!quiet)
printf("You should enter kconsole debug mode now.\n");
TPRINTF("If kconsole is compiled in, you should enter debug mode now.\n");
asm volatile (
"break\n"
49,5 → 46,3
return "Back from debug mode";
}
 
#endif
/branches/arm/kernel/test/debug/mips1.def
1,4 → 1,3
#ifdef mips32
{
"mips1",
"MIPS debug test",
5,4 → 4,3
&test_mips1,
false
},
#endif
/branches/arm/kernel/test/thread/thread1.c
36,37 → 36,33
 
#include <arch.h>
 
#define THREADS 5
#define THREADS 5
 
static atomic_t finish;
static atomic_t threads_finished;
static bool sh_quiet;
 
static void threadtest(void *data)
{
thread_detach(THREAD);
 
thread_detach(THREAD);
while (atomic_get(&finish)) {
if (!sh_quiet)
printf("%" PRIu64 " ", THREAD->tid);
TPRINTF("%" PRIu64 " ", THREAD->tid);
thread_usleep(100000);
}
atomic_inc(&threads_finished);
}
 
char * test_thread1(bool quiet)
char *test_thread1(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
atomic_set(&finish, 1);
atomic_set(&threads_finished, 0);
 
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(threadtest, NULL, TASK, 0, "threadtest", false))) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("Could not create thread %d\n", i);
break;
}
thread_ready(t);
73,14 → 69,12
total++;
}
if (!quiet)
printf("Running threads for 10 seconds...\n");
TPRINTF("Running threads for 10 seconds...\n");
thread_sleep(10);
atomic_set(&finish, 0);
while (atomic_get(&threads_finished) < ((long) total)) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_finished));
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_finished));
thread_sleep(1);
}
/branches/arm/kernel/test/fpu/fpu1.c
File deleted
/branches/arm/kernel/test/fpu/fpu1_ia64.c
0,0 → 1,170
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <print.h>
#include <debug.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
#include <arch/arch.h>
 
 
#define THREADS 150
#define ATTEMPTS 100
 
#define E_10e8 271828182
#define PI_10e8 3141592
 
static inline long double sqrt(long double a)
{
long double x = 1;
long double lx = 0;
if (a < 0.00000000000000001)
return 0;
while (x != lx) {
lx = x;
x = (x + (a / x)) / 2;
}
return x;
}
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
 
static void e(void *data)
{
int i;
double e, d, le, f;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i<ATTEMPTS; i++) {
le = -1;
e = 0;
f = 1;
for (d = 1; e != le; d *= f, f += 1) {
le = e;
e = e + 1 / d;
}
if ((int) (100000000 * e) != E_10e8) {
TPRINTF("tid%" PRIu64 ": e*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
static void pi(void *data)
{
int i;
double lpi, pi;
double n, ab, ad;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i < ATTEMPTS; i++) {
lpi = -1;
pi = 0;
for (n = 2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) {
double sc, cd;
sc = sqrt(1 - (ab * ab / 4));
cd = 1 - sc;
ad = sqrt(ab * ab / 4 + cd * cd);
lpi = pi;
pi = 2 * n * ad;
}
if ((int) (1000000 * pi) != PI_10e8) {
TPRINTF("tid%" PRIu64 ": pi*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (1000000 * pi), (unative_t) (PI_10e8 / 100));
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
char *test_fpu1(void)
{
unsigned int i, total = 0;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) {
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
total++;
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) {
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
total++;
}
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
if (atomic_get(&threads_fault) == 0)
return NULL;
return "Test failed";
}
/branches/arm/kernel/test/fpu/fpu1_x86.c
0,0 → 1,167
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <print.h>
#include <debug.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
#include <arch/arch.h>
 
 
#define THREADS 150
#define ATTEMPTS 100
 
#define E_10e8 271828182
#define PI_10e8 314159265
 
static inline double sqrt(double x)
{
double v;
asm (
"fsqrt\n"
: "=t" (v)
: "0" (x)
);
return v;
}
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
 
static void e(void *data)
{
int i;
double e, d, le, f;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i<ATTEMPTS; i++) {
le = -1;
e = 0;
f = 1;
for (d = 1; e != le; d *= f, f += 1) {
le = e;
e = e + 1 / d;
}
if ((int) (100000000 * e) != E_10e8) {
TPRINTF("tid%" PRIu64 ": e*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
static void pi(void *data)
{
int i;
double lpi, pi;
double n, ab, ad;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i < ATTEMPTS; i++) {
lpi = -1;
pi = 0;
for (n = 2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) {
double sc, cd;
sc = sqrt(1 - (ab * ab / 4));
cd = 1 - sc;
ad = sqrt(ab * ab / 4 + cd * cd);
lpi = pi;
pi = 2 * n * ad;
}
if ((int) (100000000 * pi) != PI_10e8) {
TPRINTF("tid%" PRIu64 ": pi*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8);
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
char *test_fpu1(void)
{
unsigned int i, total = 0;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) {
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
total++;
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) {
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
total++;
}
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
if (atomic_get(&threads_fault) == 0)
return NULL;
return "Test failed";
}
/branches/arm/kernel/test/fpu/mips2_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <test.h>
 
char *test_mips2(void)
{
return NULL;
}
/branches/arm/kernel/test/fpu/fpu1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <test.h>
 
char *test_fpu1(void)
{
return NULL;
}
/branches/arm/kernel/test/fpu/sse1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <test.h>
 
char *test_sse1(void)
{
return NULL;
}
/branches/arm/kernel/test/fpu/mips2.c
26,8 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifdef mips32
 
#include <print.h>
#include <debug.h>
 
38,14 → 36,13
 
#include <arch.h>
 
#define THREADS 50
#define DELAY 10000L
#define ATTEMPTS 5
#define THREADS 50
#define DELAY 10000L
#define ATTEMPTS 5
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
static bool sh_quiet;
 
static void testit1(void *data)
{
56,7 → 53,7
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"mtc1 %0,$1"
71,8 → 68,7
);
if (arg != after_arg) {
if (!sh_quiet)
printf("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
89,13 → 85,13
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"mtc1 %0,$1"
: "=r" (arg)
);
 
scheduler();
asm volatile (
"mfc1 %0,$1"
103,8 → 99,7
);
if (arg != after_arg) {
if (!sh_quiet)
printf("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
113,24 → 108,21
}
 
 
char * test_mips2(bool quiet)
char *test_mips2(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
if (!quiet)
printf("Creating %u threads... ", 2 * THREADS);
 
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i);
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
137,8 → 129,7
total++;
if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i + 1);
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
145,15 → 136,13
total++;
}
if (!quiet)
printf("ok\n");
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_ok));
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
162,5 → 151,3
return "Test failed";
}
 
#endif
/branches/arm/kernel/test/fpu/sse1.c
26,8 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#if (defined(ia32) || defined(amd64) || defined(ia32xen))
 
#include <print.h>
#include <debug.h>
 
38,41 → 36,38
 
#include <arch.h>
 
#define THREADS 25
#define DELAY 10000L
#define ATTEMPTS 5
#define THREADS 25
#define DELAY 10000L
#define ATTEMPTS 5
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
static bool sh_quiet;
 
 
static void testit1(void *data)
{
int i;
int arg __attribute__((aligned(16))) = (int) ((unative_t) data);
int after_arg __attribute__((aligned(16)));
 
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"movlpd %0, %%xmm2\n"
: "=m" (arg)
"movlpd %[arg], %%xmm2\n"
: [arg] "=m" (arg)
);
 
delay(DELAY);
asm volatile (
"movlpd %%xmm2, %0\n"
: "=m" (after_arg)
"movlpd %%xmm2, %[after_arg]\n"
: [after_arg] "=m" (after_arg)
);
if (arg != after_arg) {
if (!sh_quiet)
printf("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
89,22 → 84,21
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"movlpd %0, %%xmm2\n"
: "=m" (arg)
"movlpd %[arg], %%xmm2\n"
: [arg] "=m" (arg)
);
 
scheduler();
asm volatile (
"movlpd %%xmm2, %0\n"
: "=m" (after_arg)
"movlpd %%xmm2, %[after_arg]\n"
: [after_arg] "=m" (after_arg)
);
if (arg != after_arg) {
if (!sh_quiet)
printf("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
112,25 → 106,21
atomic_inc(&threads_ok);
}
 
 
char * test_sse1(bool quiet)
char *test_sse1(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
if (!quiet)
printf("Creating %u threads... ", 2 * THREADS);
 
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i);
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
137,8 → 127,7
total++;
if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i + 1);
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
145,15 → 134,13
total++;
}
if (!quiet)
printf("ok\n");
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_ok));
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
162,5 → 149,3
return "Test failed";
}
 
#endif
/branches/arm/kernel/test/fpu/mips2.def
1,4 → 1,3
#ifdef mips32
{
"mips2",
"MIPS FPU test",
5,4 → 4,3
&test_mips2,
true
},
#endif
/branches/arm/kernel/test/fpu/fpu1.def
1,4 → 1,3
#if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen))
{
"fpu1",
"Intel FPU test",
5,4 → 4,3
&test_fpu1,
true
},
#endif
/branches/arm/kernel/test/fpu/sse1.def
1,4 → 1,3
#if (defined(ia32) || defined(amd64) || defined(ia32xen))
{
"sse1",
"Intel SEE test",
5,4 → 4,3
&test_sse1,
true
},
#endif
/branches/arm/kernel/test/sysinfo/sysinfo1.c
32,9 → 32,9
#include <test.h>
#include <sysinfo/sysinfo.h>
 
char * test_sysinfo1(bool quiet)
char *test_sysinfo1(void)
{
if (!quiet)
if (!test_quiet)
sysinfo_dump(NULL, 0);
return NULL;
}
/branches/arm/kernel/test/fault/fault1.c
36,8 → 36,7
 
#include <arch.h>
 
 
char * test_fault1(bool quiet)
char *test_fault1(void)
{
((int *)(0))[1] = 0;
/branches/arm/kernel/test/atomic/atomic1.c
31,7 → 31,7
#include <atomic.h>
#include <debug.h>
 
char * test_atomic1(bool quiet)
char *test_atomic1(void)
{
atomic_t a;
/branches/arm/kernel/test/print/print2.c
0,0 → 1,57
/*
* Copyright (c) 2005 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <print.h>
#include <test.h>
 
char *test_print2(void)
{
TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
TPRINTF("Expected output: [a] [ b] [c ] [ d] [e ]\n");
TPRINTF("Real output: [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n");
TPRINTF("Expected output: [1] [ 02] [03 ] [004] [005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", 1, 2, 3, 4, 5);
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", -1, -2, -3, -4, -5):\n");
TPRINTF("Expected output: [-1] [-02] [-03] [-004] [-005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", -1, -2, -3, -4, -5);
TPRINTF("Testing printf(\"%%#x %%5.3#x %%-5.3#x %%3.5#x %%-3.5#x\", 17, 18, 19, 20, 21):\n");
TPRINTF("Expected output: [0x11] [0x012] [0x013] [0x00014] [0x00015]\n");
TPRINTF("Real output: [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21);
unative_t nat = 0x12345678u;
TPRINTF("Testing printf(\"%%#" PRIx64 " %%#" PRIx32 " %%#" PRIx16 " %%#" PRIx8 " %%#" PRIxn " %%#" PRIx64 " %%s\", 0x1234567887654321ll, 0x12345678, 0x1234, 0x12, nat, 0x1234567887654321ull, \"Lovely string\"):\n");
TPRINTF("Expected output: [0x1234567887654321] [0x12345678] [0x1234] [0x12] [0x12345678] [0x1234567887654321] \"Lovely string\"\n");
TPRINTF("Real output: [%#" PRIx64 "] [%#" PRIx32 "] [%#" PRIx16 "] [%#" PRIx8 "] [%#" PRIxn "] [%#" PRIx64 "] \"%s\"\n\n", 0x1234567887654321ll, 0x12345678, 0x1234, 0x12, nat, 0x1234567887654321ull, "Lovely string");
return NULL;
}
/branches/arm/kernel/test/print/print3.c
0,0 → 1,61
/*
* Copyright (c) 2005 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <print.h>
#include <macros.h>
#include <test.h>
 
#define BUFFER_SIZE 32
 
char *test_print3(void)
{
char buffer[BUFFER_SIZE];
int retval;
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short text without parameters.\"):\n");
TPRINTF("Expected result: retval=30 buffer=\"Short text without parameters.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very very very long text without parameters.\"):\n");
TPRINTF("Expected result: retval=44 buffer=\"Very very very long text withou\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short %%s.\", \"text\"):\n");
TPRINTF("Expected result: retval=11 buffer=\"Short text.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short %s.", "text");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very long %%s. This text's length is more than %%d. We are interested in the result.\", \"text\", " STRING(BUFFER_SIZE) "):\n");
TPRINTF("Expected result: retval=84 buffer=\"Very long text. This text's len\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text's length is more than %d. We are interested in the result.", "text", BUFFER_SIZE);
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
return NULL;
}
/branches/arm/kernel/test/print/print4.c
0,0 → 1,82
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <print.h>
#include <test.h>
 
char *test_print4(void)
{
TPRINTF("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n");
uint8_t group;
for (group = 1; group < 4; group++) {
TPRINTF("%#" PRIx8 ": ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%c", (char) ((group << 5) + index));
TPRINTF(" ");
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
TPRINTF("\n");
}
TPRINTF("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n");
for (group = 4; group < 8; group++) {
TPRINTF("%#" PRIx8 ": ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
TPRINTF("\n");
}
TPRINTF("\nUTF-8 strings using printf(\"%%s\"):\n");
TPRINTF("English: %s\n", "Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %s\n", "Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %s\n", "Սկսեց հրատարակվել Երուսաղեմի հայկական");
TPRINTF("\nUTF-32 strings using printf(\"%%ls\"):\n");
TPRINTF("English: %ls\n", L"Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %ls\n", L"Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %ls\n", L"Սկսեց հրատարակվել Երուսաղեմի հայկական");
return NULL;
}
/branches/arm/kernel/test/print/print1.c
29,44 → 29,27
#include <print.h>
#include <test.h>
 
#define BUFFER_SIZE 32
 
char * test_print1(bool quiet)
char *test_print1(void)
{
if (!quiet) {
int retval;
unative_t nat = 0x12345678u;
char buffer[BUFFER_SIZE];
printf(" text 10.8s %*.*s \n", 5, 3, "text");
printf(" very long text 10.8s %10.8s \n", "very long text");
printf(" text 8.10s %8.10s \n", "text");
printf(" very long text 8.10s %8.10s \n", "very long text");
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n", 'a', 'b', 'c', 'd', 'e');
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n", 1, 1, 1, 1, 1);
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n", -1, -1, -1, -1, -1);
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n", 17, 17, 17, 17, 17);
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#" PRIxn "'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
printf(" Print to NULL '%s'\n", NULL);
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
printf("Result is: '%s', retval = %d\n", buffer, retval);
}
TPRINTF("Testing printf(\"%%*.*s\", 5, 3, \"text\"):\n");
TPRINTF("Expected output: \" tex\"\n");
TPRINTF("Real output: \"%*.*s\"\n\n", 5, 3, "text");
TPRINTF("Testing printf(\"%%10.8s\", \"very long text\"):\n");
TPRINTF("Expected output: \" very lon\"\n");
TPRINTF("Real output: \"%10.8s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%8.10s\", \"text\"):\n");
TPRINTF("Expected output: \"text\"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "text");
TPRINTF("Testing printf(\"%%8.10s\", \"very long text\"):\n");
TPRINTF("Expected output: \"very long \"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%s\", NULL):\n");
TPRINTF("Expected output: \"(NULL)\"\n");
TPRINTF("Real output: \"%s\"\n\n", NULL);
return NULL;
}
/branches/arm/kernel/test/print/print1.def
1,6 → 1,6
{
"print1",
"Printf test",
"String printf test",
&test_print1,
true
},
/branches/arm/kernel/test/print/print2.def
0,0 → 1,6
{
"print2",
"Numeric printf test",
&test_print2,
true
},
/branches/arm/kernel/test/print/print3.def
0,0 → 1,6
{
"print3",
"Buffered printf test",
&test_print3,
true
},
/branches/arm/kernel/test/print/print4.def
0,0 → 1,6
{
"print4",
"Unicode test",
&test_print4,
true
},
/branches/arm/HelenOS.config
1,5 → 1,6
#
# Copyright (c) 2006 Ondrej Palkovsky
# Copyright (c) 2006 Ondrej Palkovsky
# Copyright (c) 2009 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
26,60 → 27,435
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
## General configuration directives
## General platform options
 
# Platform
% Platform
@ "amd64" AMD64/Intel EM64T (PC)
@ "arm32" ARM 32-bit
@ "ia32" Intel IA-32 (PC)
@ "ia32xen" Intel IA-32 on Xen hypervisor
@ "ia64" Intel IA-64
@ "mips32" MIPS 32-bit
@ "ppc32" PowerPC 32-bit (iMac G4)
@ "ppc64" PowerPC 64-bit (iMac G5)
@ "sparc64" Sun UltraSPARC 64-bit
! PLATFORM (choice)
 
# Machine
% Machine type
@ "msim" MSIM
@ "simics" Simics
@ "bgxemul" GXEmul big endian
@ "lgxemul" GXEmul little endian
! [PLATFORM=mips32] MACHINE (choice)
 
# Machine type
% Machine type
@ "i460GX" i460GX chipset machine
@ "ski" Ski ia64 simulator
@ "i460GX" i460GX chipset machine
! [PLATFORM=ia64] MACHINE (choice)
 
# Machine Type
@ "gxemul_testarm" testarm - GXEmul
@ "qemu_icp" Integrator CP - QEMU
! [PLATFORM=arm32] MACHINE (choice)
% Machine type
@ "generic" Generic Sun workstation or server
@ "serengeti" Serengeti system
! [PLATFORM=sparc64] MACHINE (choice)
 
# Compiler
% CPU type
@ "pentium4" Pentium 4
@ "pentium3" Pentium 3
@ "core" Core Solo/Duo
@ "athlon_xp" Athlon XP
@ "athlon_mp" Athlon MP
! [PLATFORM=ia32] PROCESSOR (choice)
 
% CPU type
@ "opteron" Opteron
! [PLATFORM=amd64] PROCESSOR (choice)
 
% CPU type
@ "us" UltraSPARC I-II subarchitecture
@ "us3" UltraSPARC III-IV subarchitecture
! [PLATFORM=sparc64&MACHINE=generic] PROCESSOR (choice)
 
% CPU type
@ "us3"
! [PLATFORM=sparc64&MACHINE=serengeti] PROCESSOR (choice)
 
% Ramdisk format
@ "tmpfs" TMPFS image
@ "fat" FAT16 image
! RDFMT (choice)
 
 
## Mapping between platform and kernel architecture
 
% Kernel architecture
@ "amd64"
! [PLATFORM=amd64] KARCH (choice)
 
% Kernel architecture
@ "arm32"
! [PLATFORM=arm32] KARCH (choice)
 
% Kernel architecture
@ "ia32"
! [PLATFORM=ia32] KARCH (choice)
 
% Kernel architecture
@ "ia32xen"
! [PLATFORM=ia32xen] KARCH (choice)
 
% Kernel architecture
@ "ia64"
! [PLATFORM=ia64] KARCH (choice)
 
% Kernel architecture
@ "mips32"
! [PLATFORM=mips32] KARCH (choice)
 
% Kernel architecture
@ "ppc32"
! [PLATFORM=ppc32] KARCH (choice)
 
% Kernel architecture
@ "ppc64"
! [PLATFORM=ppc64] KARCH (choice)
 
% Kernel architecture
@ "sparc64"
! [PLATFORM=sparc64] KARCH (choice)
 
 
## Mapping between platform and user space architecture
 
% User space architecture
@ "amd64"
! [PLATFORM=amd64] UARCH (choice)
 
% User space architecture
@ "arm32"
! [PLATFORM=arm32] UARCH (choice)
 
% User space architecture
@ "ia32"
! [PLATFORM=ia32|PLATFORM=ia32xen] UARCH (choice)
 
% User space architecture
@ "ia64"
! [PLATFORM=ia64] UARCH (choice)
 
% User space architecture
@ "mips32"
! [PLATFORM=mips32&(MACHINE=msim|MACHINE=lgxemul)] UARCH (choice)
 
% User space architecture
@ "mips32eb"
! [PLATFORM=mips32&MACHINE=bgxemul] UARCH (choice)
 
% User space architecture
@ "ppc32"
! [PLATFORM=ppc32] UARCH (choice)
 
% User space architecture
@ "ppc64"
! [PLATFORM=ppc64] UARCH (choice)
 
% User space architecture
@ "sparc64"
! [PLATFORM=sparc64] UARCH (choice)
 
 
## Mapping between platform and boot architecture
 
% Boot architecture
@ "amd64"
! [PLATFORM=amd64] BARCH (choice)
 
% Boot architecture
@ "arm32"
! [PLATFORM=arm32] BARCH (choice)
 
% Boot architecture
@ "ia32"
! [PLATFORM=ia32] BARCH (choice)
 
% Boot architecture
@ "ia32xen"
! [PLATFORM=ia32xen] BARCH (choice)
 
% Boot architecture
@ "ia64"
! [PLATFORM=ia64] BARCH (choice)
 
% Boot architecture
@ "mips32"
! [PLATFORM=mips32] BARCH (choice)
 
% Boot architecture
@ "ppc32"
! [PLATFORM=ppc32] BARCH (choice)
 
% Boot architecture
@ "ppc64"
! [PLATFORM=ppc64] BARCH (choice)
 
% Boot architecture
@ "sparc64"
! [PLATFORM=sparc64] BARCH (choice)
 
 
## Mapping between platform and image format
 
% Image format
@ "binary"
! [PLATFORM=mips32&MACHINE=msim] IMAGE (choice)
 
% Image format
@ "ecoff"
! [PLATFORM=mips32&(MACHINE=bgxemul|MACHINE=lgxemul)] IMAGE (choice)
 
 
## Compiler options
 
% Compiler
@ "gcc_cross" GCC Cross-compiler
@ "gcc_native" GCC Native
@ "icc_native" ICC Native
@ "suncc_native" Sun Studio C Compiler
! [PLATFORM=amd64|PLATFORM=ia32|PLATFORM=ia32xen] COMPILER (choice)
! [PLATFORM=amd64|PLATFORM=ia32] COMPILER (choice)
 
# Compiler
% Compiler
@ "gcc_cross" GCC Cross-compiler
@ "gcc_native" GCC Native
@ "icc_native" ICC Native
! [PLATFORM=ia64] COMPILER (choice)
 
# Compiler
% Compiler
@ "gcc_cross" GCC Cross-compiler
@ "gcc_native" GCC Native
@ "suncc_native" Sun Studio C Compiler
! [PLATFORM=sparc64] COMPILER (choice)
 
# Compiler
% Compiler
@ "gcc_cross" GCC Cross-compiler
@ "gcc_native" GCC Native
! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=ppc64] COMPILER (choice)
! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice)
 
# Debug build
 
## Kernel configuration
 
% Fences
! [PLATFORM=ia32&(PROCESSOR=athlon_xp|PROCESSOR=athlon_mp|PROCESSOR=pentium3)] CONFIG_FENCES_P3 (y)
 
% Fences
! [PLATFORM=ia32&(PROCESSOR=pentium4|PROCESSOR=core)] CONFIG_FENCES_P4 (y)
 
% Fences
! [PLATFORM=amd64] CONFIG_FENCES_P4 (y)
 
% ACPI support
! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_ACPI (y)
 
% Hierarchical page tables support
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y)
 
% Page hash table support
! [PLATFORM=ia64|PLATFORM=sparc64] CONFIG_PAGE_HT (y)
 
% Software integer division support
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_SOFTINT (y)
 
% ASID support
! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y)
 
% ASID FIFO support
! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
 
% OpenFirmware tree support
! [PLATFORM=sparc64] CONFIG_OFW_TREE (y)
 
% Multiboot standard support
! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_MULTIBOOT (y)
 
% FPU support
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ia64|PLATFORM=sparc64] CONFIG_FPU (y)
 
% FPU support
! [PLATFORM=mips32&(MACHINE=lgxemul|MACHINE=bgxemul)] CONFIG_FPU (y)
 
 
## Kernel features options
 
% Support for SMP
! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)] CONFIG_SMP (y/n)
 
% Debug build
! CONFIG_DEBUG (y/n)
 
% Deadlock detection support for spinlocks
! [CONFIG_DEBUG=y&CONFIG_SMP=y] CONFIG_DEBUG_SPINLOCK (y/n)
 
% Lazy FPU context switching
! [CONFIG_FPU=y] CONFIG_FPU_LAZY (y/n)
 
% Use VHPT
! [PLATFORM=ia64] CONFIG_VHPT (n/y)
 
% Use TSB
! [PLATFORM=sparc64] CONFIG_TSB (y/n)
 
% IO SAPIC on default address support
! [PLATFORM=ia64&MACHINE!=ski] CONFIG_IOSAPIC (y/n)
 
% Virtually indexed D-cache support
! [PLATFORM=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
 
% Support for userspace debuggers
! CONFIG_UDEBUG (y/n)
 
% Kernel console support
! CONFIG_KCONSOLE (y/n)
 
% Kernel symbol information
! CONFIG_SYMTAB (y/n)
 
% Detailed kernel logging
! CONFIG_LOG (n/y)
 
% Compile kernel tests
! CONFIG_TEST (y/n)
 
 
## Hardware support
 
% Input device class
@ "generic" Keyboard or serial line
@ "none" No input device
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
 
% Input device class
@ "generic" Keyboard or serial line
@ "keyboard" Keyboard
@ "serial" Serial line
@ "none" No input device
! [PLATFORM=ia64&MACHINE=i460GX] CONFIG_HID_IN (choice)
 
% Output device class
@ "generic" Monitor or serial line
@ "none" No output device
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ppc32|(PLATFORM=ia64&MACHINE=i460GX)|(PLATFORM=mips32&MACHINE=msim)] CONFIG_HID_OUT (choice)
 
% Output device class
@ "generic" Monitor or serial line
@ "monitor" Monitor
@ "serial" Serial line
@ "none" No output device
! [PLATFORM=mips32&(MACHINE=bgxemul|MACHINE=lgxemul)] CONFIG_HID_OUT (choice)
 
% Output device class
@ "generic" Monitor or serial line
@ "monitor" Monitor
@ "serial" Serial line
@ "none" No output device
! [PLATFORM=arm32] CONFIG_HID_OUT (choice)
 
% PC keyboard support
! [CONFIG_HID_IN=generic&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_PC_KBD (y/n)
 
% PC keyboard support
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_PC_KBD (y/n)
 
% Support for msim/GXemul keyboard
! [CONFIG_HID_IN=generic&PLATFORM=mips32] CONFIG_MIPS_KBD (y/n)
 
% Support for msim/GXemul printer
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=mips32] CONFIG_MIPS_PRN (y/n)
 
% Support for GXemul keyboard
! [CONFIG_HID_IN=generic&PLATFORM=arm32] CONFIG_ARM_KBD (y/n)
 
% Support for GXemul printer
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32] CONFIG_ARM_PRN (y/n)
 
% Support for VIA CUDA controller
! [CONFIG_HID_IN=generic&PLATFORM=ppc32] CONFIG_VIA_CUDA (y/n)
 
% Support for NS16550 controller
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic] CONFIG_NS16550 (y/n)
 
% Support for NS16550 controller
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_NS16550 (y/n)
 
% Support for Z8530 controller
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic] CONFIG_Z8530 (y/n)
 
% Support for Serengeti console
! [CONFIG_HID_OUT=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_PRN (y/n)
 
% Support for Serengeti keyboard
! [CONFIG_HID_IN=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_KBD (y/n)
 
% i8042 controller support
! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
 
% Sun keyboard support
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&(CONFIG_NS16550=y|CONFIG_Z8530=y)] CONFIG_SUN_KBD (y)
 
% Macintosh ADB keyboard support
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=ppc32&(CONFIG_VIA_CUDA=y)] CONFIG_MAC_KBD (y)
 
% Dummy serial line input
! [CONFIG_MIPS_KBD=y|CONFIG_ARM_KBD=y] CONFIG_DSRLNIN (y)
 
% Dummy serial line output
! [CONFIG_MIPS_PRN=y|CONFIG_ARM_PRN=y] CONFIG_DSRLNOUT (y)
 
% Serial line input module
! [CONFIG_DSRLNIN=y|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&MACHINE=serengeti&CONFIG_SGCN_KBD=y)] CONFIG_SRLN (y)
 
% EGA support
! [CONFIG_HID_OUT=generic&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_EGA (y/n)
 
% EGA support
! [CONFIG_HID_OUT=generic&PLATFORM=ia64&MACHINE=i460GX] CONFIG_EGA (y/n)
 
% Framebuffer support
! [CONFIG_HID_OUT=generic&(PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ppc32)] CONFIG_FB (y/n)
 
% Framebuffer support
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&PLATFORM=mips32&(MACHINE=lgxemul|MACHINE=bgxemul)] CONFIG_FB (y/n)
 
% Framebuffer support
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&PLATFORM=arm32] CONFIG_FB (y/n)
 
% Framebuffer support
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&PLATFORM=sparc64&MACHINE=generic] CONFIG_FB (y/n)
 
% Default framebuffer mode
@ "640x480"
@ "800x600"
@ "1024x768"
@ "1152x720"
@ "1152x864"
@ "1280x960"
@ "1280x1024"
@ "1400x1050"
@ "1440x900"
@ "1440x1050"
@ "1600x1200"
@ "1920x1080"
@ "1920x1200"
! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_HID_OUT!=none&CONFIG_FB=y] CONFIG_VESA_MODE (choice)
 
% Default framebuffer depth
@ "8"
@ "16"
@ "24"
! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_HID_OUT!=none&CONFIG_FB=y] CONFIG_VESA_BPP (choice)
 
% Start AP processors by the loader
! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
 
% Use Block Address Translation by the loader
! [PLATFORM=ppc32] CONFIG_BAT (y/n)
 
% Preserve A.OUT header in isofs.b
! [PLATFORM=sparc64&MACHINE=generic] CONFIG_AOUT_ISOFS_B (y)
 
% External ramdisk
! [PLATFORM=sparc64] CONFIG_RD_EXTERNAL (y/n)
/branches/arm/boot/boot.config
File deleted
/branches/arm/boot/arch/ppc64/Makefile.inc
File deleted
/branches/arm/boot/arch/ppc64/loader/regname.h
File deleted
/branches/arm/boot/arch/ppc64/loader/boot.S
File deleted
/branches/arm/boot/arch/ppc64/loader/main.c
File deleted
/branches/arm/boot/arch/ppc64/loader/asm.h
File deleted
/branches/arm/boot/arch/ppc64/loader/ofwarch.c
File deleted
/branches/arm/boot/arch/ppc64/loader/types.h
File deleted
/branches/arm/boot/arch/ppc64/loader/main.h
File deleted
/branches/arm/boot/arch/ppc64/loader/Makefile
File deleted
/branches/arm/boot/arch/ppc64/loader/debug.inc
File deleted
/branches/arm/boot/arch/ppc64/loader/ofwarch.h
File deleted
/branches/arm/boot/arch/ppc64/loader/_link.ld.in
File deleted
/branches/arm/boot/arch/ppc64/loader/asm.S
File deleted
/branches/arm/boot/arch/ia32xen/grub/menu.lst
File deleted
/branches/arm/boot/arch/ia32xen/grub/stage2_eltorito
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/boot/arch/ia32xen/grub/COPYING
File deleted
/branches/arm/boot/arch/ia32xen/grub/xen.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/boot/arch/ia32xen/grub/menu.debug.lst
File deleted
/branches/arm/boot/arch/ia32xen/grub/README
File deleted
/branches/arm/boot/arch/ia32xen/grub/xen.debug.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/boot/arch/ia32xen/Makefile.inc
File deleted
/branches/arm/boot/arch/sparc64/loader/Makefile
27,7 → 27,7
#
 
include ../../../../version
include ../../../Makefile.config
-include ../../../../Makefile.config
 
## Toolchain configuration
#
57,16 → 57,8
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
endif
 
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 -mno-fpu
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 -mno-fpu -pipe
 
ifdef REVISION
CFLAGS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
SOURCES = \
main.c \
_components.c \
79,6 → 71,9
asm.S \
boot.S
 
#
# All components that go to image.boot without the ramdisk.
#
COMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
85,7 → 80,7
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
94,22 → 89,43
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
endif
 
#
# Final list of all components that go to image.boot.
#
ALL_COMPONENTS = $(COMPONENTS)
ifeq ($(CONFIG_RD_EXTERNAL),n)
ALL_COMPONENTS += ./initrd.img
endif
 
RD_SRVS = \
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat
$(USPACEDIR)/srv/bd/file_bd/file_bd
 
ifeq ($(MACHINE),generic)
RD_SRVS += \
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/cir/fhc/fhc \
$(USPACEDIR)/srv/cir/obio/obio
endif
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
$(USPACEDIR)/app/bdsh/bdsh \
$(USPACEDIR)/app/klog/klog
 
ifeq ($(MACHINE),generic)
RD_APPS += \
$(USPACEDIR)/app/tester/tester
endif
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
ALL_COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(ALL_COMPONENTS))))
 
.PHONY: all clean depend
 
117,11 → 133,11
 
-include Makefile.depend
 
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS)
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
image.boot: depend _components.h _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS)
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) -o $@
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
clean:
-for file in $(RD_SRVS) ; do \
130,9 → 146,9
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend
-rm -f _components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend
 
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
_components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS): $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
for file in $(RD_SRVS) ; do \
cp $$file $(USPACEDIR)/dist/srv/ ; \
done
143,11 → 159,11
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
endif
ifeq ($(RDFMT),fat)
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
endif
../../../../tools/mkhord.py 16384 initrd.fs initrd.img
rm initrd.fs
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(COMPONENTS)
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(ALL_COMPONENTS)
 
%.o: %.S
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/boot/arch/sparc64/loader/asm.S
40,7 → 40,7
.global jump_to_kernel
 
halt:
b halt
ba %xcc, halt
nop
memcpy:
105,9 → 105,28
* 1. Make sure that the code we have moved has drained to main memory.
* 2. Invalidate I-cache.
* 3. Flush instruction pipeline.
*/
call icache_flush
membar #StoreStore
*/
 
/*
* US3 processors have a write-invalidate cache, so explicitly
* invalidating it is not required. Whether to invalidate I-cache
* or not is decided according to the value of the global
* "subarchitecture" variable (set in the bootstrap).
*/
set subarchitecture, %g2
ldub [%g2], %g2
cmp %g2, 3
be %xcc, 1f
nop
0:
call icache_flush
nop
1:
membar #StoreStore
/*
* Flush the instruction pipeline.
*/
flush %i7
 
mov %o0, %l1
134,7 → 153,6
retl
! SF Erratum #51
nop
 
.global ofw
ofw:
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
/branches/arm/boot/arch/sparc64/loader/boot.S
43,7 → 43,7
 
.global start
start:
b 1f
ba %xcc, 1f
nop
 
/*
83,7 → 83,7
call ofw_init ! initialize OpenFirmware
stx %o4, [%l0]
b bootstrap
ba %xcc, bootstrap
nop
 
.align STACK_ALIGNMENT
/branches/arm/boot/arch/sparc64/loader/main.c
36,25 → 36,36
#include <ofw_tree.h>
#include "ofwarch.h"
#include <align.h>
#include <macros.h>
#include <string.h>
 
bootinfo_t bootinfo;
 
component_t components[COMPONENTS];
 
char *release = RELEASE;
char *release = STRING(RELEASE);
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = "\nBuilt on " TIMESTAMP;
char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
 
/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
uint8_t subarchitecture;
 
/**
* mask of the MID field inside the ICBUS_CONFIG register shifted by
* MID_SHIFT bits to the right
*/
uint16_t mid_mask;
 
/** Print version information. */
static void version_print(void)
{
63,6 → 74,39
release, revision, timestamp);
}
 
/* the lowest ID (read from the VER register) of some US3 CPU model */
#define FIRST_US3_CPU 0x14
 
/* the greatest ID (read from the VER register) of some US3 CPU model */
#define LAST_US3_CPU 0x19
 
/* UltraSPARC IIIi processor implementation code */
#define US_IIIi_CODE 0x15
 
/**
* Sets the global variables "subarchitecture" and "mid_mask" to
* correct values.
*/
static void detect_subarchitecture(void)
{
uint64_t v;
asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
v = (v << 16) >> 48;
if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) {
subarchitecture = SUBARCH_US3;
if (v == US_IIIi_CODE)
mid_mask = (1 << 5) - 1;
else
mid_mask = (1 << 10) - 1;
} else if (v < FIRST_US3_CPU) {
subarchitecture = SUBARCH_US;
mid_mask = (1 << 5) - 1;
} else {
printf("\nThis CPU is not supported by HelenOS.");
}
}
 
void bootstrap(void)
{
void *base = (void *) KERNEL_VIRTUAL_ADDRESS;
72,6 → 116,7
 
version_print();
detect_subarchitecture();
init_components(components);
 
if (!ofw_get_physmem_start(&bootinfo.physmem_start)) {
83,7 → 128,7
printf("Error: unable to get memory map, halting.\n");
halt();
}
 
if (bootinfo.memmap.total == 0) {
printf("Error: no memory detected, halting.\n");
halt();
98,8 → 143,8
silo_ramdisk_image += bootinfo.physmem_start;
silo_ramdisk_image -= 0x400000;
/* Install 1:1 mapping for the ramdisk. */
if (ofw_map((void *)((uintptr_t)silo_ramdisk_image),
(void *)((uintptr_t)silo_ramdisk_image),
if (ofw_map((void *)((uintptr_t) silo_ramdisk_image),
(void *)((uintptr_t) silo_ramdisk_image),
silo_ramdisk_size, -1) != 0) {
printf("Failed to map ramdisk.\n");
halt();
134,6 → 179,9
base + top;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size =
components[i].size;
strncpy(bootinfo.taskmap.tasks[
bootinfo.taskmap.count].name, components[i].name,
BOOTINFO_TASK_NAME_BUFLEN);
bootinfo.taskmap.count++;
}
top += components[i].size;
159,7 → 207,8
* given to us by SILO.
*/
(void) ofw_claim_phys(base + top, silo_ramdisk_size);
(void) ofw_map(base + top, base + top, silo_ramdisk_size, -1);
(void) ofw_map(bootinfo.physmem_start + base + top, base + top,
silo_ramdisk_size, -1);
memmove(base + top, (void *)((uintptr_t)silo_ramdisk_image),
silo_ramdisk_size);
printf("done.\n");
209,7 → 258,8
balloc_base = base + ALIGN_UP(top, PAGE_SIZE);
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base,
BALLOC_MAX_SIZE);
(void) ofw_map(balloc_base, balloc_base, BALLOC_MAX_SIZE, -1);
(void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base,
BALLOC_MAX_SIZE, -1);
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base);
 
printf("\nCanonizing OpenFirmware device tree...");
216,7 → 266,7
bootinfo.ofw_root = ofw_tree_build();
printf("done.\n");
 
#ifdef CONFIG_SMP
#ifdef CONFIG_AP
printf("\nChecking for secondary processors...");
if (!ofw_cpu())
printf("Error: unable to get CPU properties\n");
223,9 → 273,10
printf("done.\n");
#endif
 
ofw_setup_palette();
 
printf("\nBooting the kernel...\n");
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS,
bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo,
sizeof(bootinfo));
}
 
/branches/arm/boot/arch/sparc64/loader/main.h
38,12 → 38,19
 
#define TASKMAP_MAX_RECORDS 32
 
/** Size of buffer for storing task name in task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#define BSP_PROCESSOR 1
#define AP_PROCESSOR 0
 
#define SUBARCH_US 1
#define SUBARCH_US3 3
 
typedef struct {
void *addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} task_t;
 
typedef struct {
/branches/arm/boot/arch/sparc64/loader/ofwarch.c
32,7 → 32,7
* @brief Architecture dependent parts of OpenFirmware interface.
*/
 
#include <ofwarch.h>
#include <ofwarch.h>
#include <ofw.h>
#include <printf.h>
#include <string.h>
40,6 → 40,10
#include "main.h"
#include "asm.h"
 
/* these tho variables will be set by the detect_subarchitecture function */
extern uint8_t subarchitecture;
extern uint16_t mid_mask;
 
void write(const char *str, const int len)
{
int i;
56,36 → 60,40
return flag != -1;
}
 
int ofw_cpu(void)
/**
* Starts all CPUs represented by following siblings of the given node,
* except for the current CPU.
*
* @param child The first child of the OFW tree node whose children
* represent CPUs to be woken up.
* @param current_mid MID of the current CPU, the current CPU will
* (of course) not be woken up.
* @return Number of CPUs which have the same parent node as
* "child".
*/
static int wake_cpus_in_node(phandle child, uint64_t current_mid)
{
int cpus;
char type_name[BUF_SIZE];
 
phandle node;
node = ofw_get_child_node(ofw_root);
if (node == 0 || node == -1) {
printf("Could not find any child nodes of the root node.\n");
return 0;
}
uint64_t current_mid;
asm volatile ("ldxa [%1] %2, %0\n"
: "=r" (current_mid)
: "r" (0), "i" (ASI_UPA_CONFIG));
current_mid >>= UPA_CONFIG_MID_SHIFT;
current_mid &= UPA_CONFIG_MID_MASK;
 
int cpus;
for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node),
cpus++) {
if (ofw_get_property(node, "device_type", type_name,
for (cpus = 0; child != 0 && child != -1;
child = ofw_get_peer_node(child), cpus++) {
if (ofw_get_property(child, "device_type", type_name,
sizeof(type_name)) > 0) {
if (strcmp(type_name, "cpu") == 0) {
uint32_t mid;
if (ofw_get_property(node, "upa-portid", &mid,
sizeof(mid)) <= 0)
/*
* "upa-portid" for US, "portid" for US-III,
* "cpuid" for US-IV
*/
if (ofw_get_property(
child, "upa-portid",
&mid, sizeof(mid)) <= 0
&& ofw_get_property(child, "portid",
&mid, sizeof(mid)) <= 0
&& ofw_get_property(child, "cpuid",
&mid, sizeof(mid)) <= 0)
continue;
if (current_mid != mid) {
93,7 → 101,7
* Start secondary processor.
*/
(void) ofw_call("SUNW,start-cpu", 3, 1,
NULL, node, KERNEL_VIRTUAL_ADDRESS,
NULL, child, KERNEL_VIRTUAL_ADDRESS,
bootinfo.physmem_start |
AP_PROCESSOR);
}
104,12 → 112,59
return cpus;
}
 
/**
* Finds out the current CPU's MID and wakes up all AP processors.
*/
int ofw_cpu(void)
{
int cpus;
phandle node;
phandle subnode;
phandle cpus_parent;
phandle cmp;
char name[BUF_SIZE];
 
/* get the current CPU MID */
uint64_t current_mid;
asm volatile ("ldxa [%1] %2, %0\n"
: "=r" (current_mid)
: "r" (0), "i" (ASI_ICBUS_CONFIG));
current_mid >>= ICBUS_CONFIG_MID_SHIFT;
 
current_mid &= mid_mask;
 
/* wake up CPUs */
cpus_parent = ofw_find_device("/ssm@0,0");
if (cpus_parent == 0 || cpus_parent == -1) {
cpus_parent = ofw_find_device("/");
}
 
node = ofw_get_child_node(cpus_parent);
cpus = wake_cpus_in_node(node, current_mid);
while (node != 0 && node != -1) {
if (ofw_get_property(node, "name", name,
sizeof(name)) > 0) {
if (strcmp(name, "cmp") == 0) {
subnode = ofw_get_child_node(node);
cpus += wake_cpus_in_node(subnode,
current_mid);
}
}
node = ofw_get_peer_node(node);
}
return cpus;
}
 
/** Get physical memory starting address.
*
* @param start Pointer to variable where the physical memory starting
* address will be stored.
* @param start Pointer to variable where the physical memory starting
* address will be stored.
*
* @return Non-zero on succes, zero on failure.
* @return Non-zero on succes, zero on failure.
*/
int ofw_get_physmem_start(uintptr_t *start)
{
/branches/arm/boot/arch/sparc64/loader/register.h
33,8 → 33,7
#define PSTATE_PRIV_BIT 4
#define PSTATE_AM_BIT 8
 
#define ASI_UPA_CONFIG 0x4a
#define UPA_CONFIG_MID_SHIFT 17
#define UPA_CONFIG_MID_MASK 0x1f
#define ASI_ICBUS_CONFIG 0x4a
#define ICBUS_CONFIG_MID_SHIFT 17
 
#endif
/branches/arm/boot/arch/sparc64/Makefile.inc
26,27 → 26,40
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
TMP=distroot
TMP = distroot
 
ifeq ($(CONFIG_AOUT_ISOFS_B),y)
SILO_PACKAGE = silo.tar.gz
else
SILO_PACKAGE = silo.patched.tar.gz
endif
 
build: $(BASE)/image.iso
 
$(BASE)/image.iso: depend arch/$(ARCH)/loader/image.boot
$(BASE)/image.iso: depend arch/$(BARCH)/loader/image.boot
mkdir -p $(TMP)/boot
mkdir -p $(TMP)/HelenOS
cat arch/$(ARCH)/silo/silo.tar.gz | (cd $(TMP)/boot; tar xvfz -)
cp arch/$(ARCH)/silo/README arch/$(ARCH)/silo/COPYING arch/$(ARCH)/silo/silo.conf $(TMP)/boot
cp arch/$(ARCH)/loader/image.boot $(TMP)/HelenOS/image.boot
cat arch/$(BARCH)/silo/$(SILO_PACKAGE) | (cd $(TMP)/boot; tar xvfz -)
cp arch/$(BARCH)/silo/README arch/$(BARCH)/silo/COPYING $(TMP)/boot
ifeq ($(CONFIG_RD_EXTERNAL),y)
cp arch/$(BARCH)/silo/silo.conf $(TMP)/boot/silo.conf
else
cat arch/$(BARCH)/silo/silo.conf | grep -v initrd > $(TMP)/boot/silo.conf
endif
cp arch/$(BARCH)/loader/image.boot $(TMP)/HelenOS/image.boot
gzip -f $(TMP)/HelenOS/image.boot
cp arch/$(ARCH)/loader/initrd.img $(TMP)/HelenOS/initrd.img
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $(BASE)/image.iso $(TMP)/
ifeq ($(CONFIG_RD_EXTERNAL),y)
cp arch/$(BARCH)/loader/initrd.img $(TMP)/HelenOS/initrd.img
endif
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $@ $(TMP)/
 
depend:
-rm arch/$(ARCH)/loader/image.boot
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(ARCH)/loader/image.boot:
$(MAKE) -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
arch/$(BARCH)/loader/image.boot:
$(MAKE) -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 
clean: generic_clean
$(MAKE) -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
$(MAKE) -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/arm/boot/arch/sparc64/silo/silo.patched.tar.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/boot/arch/ia64/loader/Makefile
27,7 → 27,7
#
 
include ../../../../version
include ../../../Makefile.config
-include ../../../../Makefile.config
 
## Toolchain configuration
#
47,7 → 47,7
LD = ld
OBJCOPY = objcopy
OBJDUMP = objdump
GEFI_PREXIX =
GEFI_PREFIX =
endif
 
ifeq ($(COMPILER),icc_native)
68,16 → 68,8
endif
 
#-mno-pic means do not use gp + imm22 to address data
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic -pipe
 
ifdef REVISION
CFLAGS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
SOURCES = \
main.c \
../../../generic/printf.c \
87,22 → 79,39
asm.S \
boot.S
 
NOCOMPONENTS = \
$(KERNELDIR)/kernel.bin
COMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
endif
ifeq ($(RDFMT),fat)
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat
endif
 
RD_SRVS = \
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/vfs/vfs \
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/bd/file_bd/file_bd
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
$(USPACEDIR)/app/klog/klog
$(USPACEDIR)/app/klog/klog \
$(USPACEDIR)/app/bdsh/bdsh
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
116,22 → 125,41
hello.efi: image.boot
make -C gefi/HelenOS PREFIX=$(GEFI_PREFIX)
cp gefi/HelenOS/hello.efi ../../../../
# cp gefi/HelenOS/hello.efi /boot/efi/
cp gefi/HelenOS/image.bin ../../../../
 
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS)
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
clean:
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot image.map image.disasm Makefile.depend ../../../../image.bin ../../../../hello.efi
-for file in $(RD_SRVS) ; do \
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
done
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) image.boot image.map image.disasm initrd.img image.boot Makefile.depend ../../../../image.bin ../../../../hello.efi
make -C gefi clean
make -C gefi/HelenOS clean
 
_components.h _components.c _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) _link.ld.in
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned long" $(COMPONENTS)
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
for file in $(RD_SRVS) ; do \
cp $$file $(USPACEDIR)/dist/srv/ ; \
done
for file in $(RD_APPS) ; do \
cp $$file $(USPACEDIR)/dist/app/ ; \
done
ifeq ($(RDFMT),tmpfs)
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
endif
ifeq ($(RDFMT),fat)
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
endif
../../../../tools/mkhord.py 16384 initrd.fs initrd.img
rm initrd.fs
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned long" $(COMPONENTS) ./initrd.img
 
%.o: %.S
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
/branches/arm/boot/arch/ia64/loader/types.h
41,7 → 41,4
typedef uint64_t uintptr_t;
typedef uint64_t unative_t;
 
typedef unsigned long count_t;
 
 
#endif
/branches/arm/boot/arch/ia64/loader/gefi/HelenOS/Makefile
20,6 → 20,7
# Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#
 
prefix=$(PREFIX)
include ../Make.defaults
CDIR=$(TOPDIR)/..
31,10 → 32,8
LOADLIBES = -lefi -lgnuefi
FORMAT = efi-app-$(ARCH)
 
 
all: gefi hello.efi
 
 
clean:
rm -f *.efi *~ *.o *.so *.map *.disass *.bin
 
43,18 → 42,30
hello.efi: hello.so
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
-j .rela -j .reloc --target=$(FORMAT) hello.so hello.efi
$(OBJDUMP) -d hello.efi > hello.disass
 
hello.so: hello.o image.o
$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES)
#When selected first lines or second lines, select if image is linked into hello or not - usefull for network boot
#hello.so: hello.o image.o division.o
hello.so: hello.o image.bin division.o
# $(LD) $(LDFLAGS) -Map hello.map hello.o division.o image.o -o hello.so $(LOADLIBES) #link image inside hello
$(LD) $(LDFLAGS) -Map hello.map hello.o division.o -o hello.so $(LOADLIBES) #dont link image inside hello
 
hello.o: hello.c
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c hello.c -o hello.o
 
image.o: ../../image.boot
division.o: division.c
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c division.c -o division.o
 
image.bin: ../../image.boot
$(OBJCOPY) -O binary ../../image.boot image.bin
$(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o
 
image.o: ../../image.boot mkimage
$(OBJCOPY) -O binary ../../image.boot image.bin
./mkimage
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c image.c -o image.o
# $(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o
 
mkimage: mkimage.c
gcc -o mkimage mkimage.c
 
gefi:
make -C .. prefix=$(PREFIX)
/branches/arm/boot/arch/ia64/loader/gefi/HelenOS/hello.c
1,9 → 1,29
#include <efi.h>
#include <efilib.h>
 
#include <../../../../../../kernel/arch/ia64/include/bootinfo.h>
 
#define KERNEL_LOAD_ADDRESS 0x4400000
 
#define MEM_MAP_DESCRIPTOR_OFFSET_TYPE 0
#define MEM_MAP_DESCRIPTOR_OFFSET_BASE 8
#define MEM_MAP_DESCRIPTOR_OFFSET_PAGES 24
 
 
 
//Link image as a data array into hello - usefull with network boot
//#define IMAGE_LINKED
 
bootinfo_t *bootinfo=(bootinfo_t *)BOOTINFO_ADDRESS;
 
 
#ifdef IMAGE_LINKED
extern char HOSimage[];
extern int HOSimagesize;
#endif
 
 
 
static CHAR16 *
a2u (char *str)
{
15,24 → 35,7
mem[i] = 0;
return mem;
}
char HEX[256];
 
char hexs[]="0123456789ABCDEF";
/*
void to_hex(unsigned long long num)
{
int a;
for(a=15;a>=0;a--)
{
char c=num - (num & 0xfffffffffffffff0LL);
num/=16;
c=hexs[c];
HEX[a]=c;
}
 
}
*/
 
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
72,16 → 75,18
EFI_FILE *FileHandle;
 
BS->HandleProtocol(LoadedImage->DeviceHandle, &FileSystemProtocol, &Vol);
Vol->OpenVolume (Vol, &CurDir);
 
char FileName[1024];
char *OsKernelBuffer;
int i;
int defaultLoad;
int imageLoad;
UINTN Size;
 
StrCpy(FileName,DevicePathToStr(LoadedImage->FilePath));
for(i=StrLen(FileName);i>=0 && FileName[i]!='\\';i--);
FileName[i] = 0;
FileName[0] = 0;
Print(L"%s\n",LoadedImage->LoadOptions);
97,11 → 102,13
}
while(LoadOptions[i]==L' ') if(LoadOptions[i++]==0) break;
if(LoadOptions[i++]==0)
if(LoadOptions[i++]==0){
StrCat(FileName,L"\\image.bin");
else{
defaultLoad=1;
}
/* else{
CHAR16 buf[1024];
buf[0]='\\';
//buf[0]='\\';
i--;
int j;
for(j=0;LoadOptions[i+j]!=L' '&&LoadOptions[i+j]!=0;j++)
108,38 → 115,101
buf[j+1]=LoadOptions[i+j];
buf[j+1]=0;
StrCat(FileName,buf);
defaultLoad=0;
}*/
else{
CHAR16 buf[1024];
//buf[0]='\\';
i--;
int j;
for(j=0;LoadOptions[i+j]!=L' '&&LoadOptions[i+j]!=0;j++)
buf[j]=LoadOptions[i+j];
buf[j+1]=0;
StrCat(FileName,buf);
defaultLoad=0;
}
//Print(L"%s\n",FileName);
 
EFI_STATUS stat;
stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
if(EFI_ERROR(stat)){
Print(L"Error Opening Image %s\n",FileName);
return 0;
imageLoad=1;
#ifdef IMAGE_LINKED
if(defaultLoad) {
Print(L"Using Linked Image\n");
imageLoad=0;
}
Size = 0x00400000;
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
FileHandle->Close(FileHandle);
#endif
 
if(Size<1) return 0;
char * HOS;
if(imageLoad)
{
Size = 0x00400000;
 
Vol->OpenVolume (Vol, &CurDir);
 
char * HOS = OsKernelBuffer;
EFI_STATUS stat;
stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
if(EFI_ERROR(stat)){
Print(L"Error Opening Image %s\n",FileName);
return 0;
}
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
FileHandle->Close(FileHandle);
HOS = OsKernelBuffer;
if(Size<1) return 0;
 
}
#ifdef IMAGE_LINKED
else {
HOS = HOSimage;
Size = HOSimagesize;
Print(L"Image start %llX\n",(long long)HOS);
Print(L"Image size %llX\n",(long long)Size);
Print(L"Image &size %llX\n",(long long)&Size);
}
#endif
int HOSSize = Size;
 
 
{
rArg rSAL;
rArg rPAL;
 
//Setup AP's wake up address
LibSalProc(0x01000000,2,0x4400200,0,0,0,0,0,&rSAL);
 
 
//Get System Frequency
UINT64 sys_freq;
LibSalProc(0x01000012,0,0,0,0,0,0,0,&rSAL);
sys_freq=rSAL.p1;
 
UINT64 freq_scale;
//Get CPU Frequency to System Frequency ratio
LibPalProc(14,0,0,0,&rPAL);
freq_scale=rPAL.p1;
 
 
UINT64 sapic;
LibGetSalIpiBlock(&sapic);
Print (L"SAPIC:%X\n", sapic);
//bootinfo->sapic=sapic;
 
 
UINT64 wakeup_intno;
LibGetSalWakeupVector(&wakeup_intno);
Print (L"WAKEUP INTNO:%X\n", wakeup_intno);
 
 
 
 
 
UINTN cookie;
void *p=(void *)KERNEL_LOAD_ADDRESS;
UINTN mapsize,descsize;
UINT32 desver;
EFI_STATUS status;
EFI_MEMORY_DESCRIPTOR emd[1024];
mapsize=1024*sizeof(emd);
status=BS->AllocatePages(AllocateAnyPages,EfiLoaderData,/*(HOSSize>>12)+1*/ 1,p);
if(EFI_ERROR(status)){
150,10 → 220,18
return EFI_SUCCESS;
}
status=BS->GetMemoryMap(&mapsize,emd,&cookie,&descsize,&desver);
if(EFI_ERROR(status)){
Print(L"Error 1\n");
return EFI_SUCCESS;
UINTN no_entryes;
void * mds;
mds=LibMemoryMap(&no_entryes,&cookie,&descsize,&desver);
for(i=0;i<no_entryes;i++)
{
unsigned int type=*((unsigned int *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_TYPE));
unsigned long long base=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_BASE));
unsigned long long pages=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_PAGES));
Print(L"T:%02d %016llX %016llX\n",type,base,pages*EFI_PAGE_SIZE);
}
status=BS->ExitBootServices(image,cookie);
if(EFI_ERROR(status)){
161,12 → 239,62
return EFI_SUCCESS;
}
}
int a;
for(a=0;a<HOSSize;a++){
((char *)(0x4400000))[a]=HOS[a];
}
bootinfo->sapic=(unsigned long *)sapic;
bootinfo->wakeup_intno=wakeup_intno;
bootinfo->sys_freq=sys_freq;
bootinfo->freq_scale=freq_scale;
bootinfo->hello_configured=1;
 
 
bootinfo->memmap_items=0;
for(i=0;i<no_entryes;i++)
{
unsigned int type=*((unsigned int *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_TYPE));
unsigned long long base=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_BASE));
unsigned long long pages=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_PAGES));
switch (type)
{
case EfiConventionalMemory:
bootinfo->memmap[bootinfo->memmap_items].type=EFI_MEMMAP_FREE_MEM;
bootinfo->memmap[bootinfo->memmap_items].base=base;
bootinfo->memmap[bootinfo->memmap_items].size=pages*EFI_PAGE_SIZE;
bootinfo->memmap_items++;
break;
case EfiMemoryMappedIO:
bootinfo->memmap[bootinfo->memmap_items].type=EFI_MEMMAP_IO;
bootinfo->memmap[bootinfo->memmap_items].base=base;
bootinfo->memmap[bootinfo->memmap_items].size=pages*EFI_PAGE_SIZE;
bootinfo->memmap_items++;
break;
case EfiMemoryMappedIOPortSpace:
bootinfo->memmap[bootinfo->memmap_items].type=EFI_MEMMAP_IO_PORTS;
bootinfo->memmap[bootinfo->memmap_items].base=base;
bootinfo->memmap[bootinfo->memmap_items].size=pages*EFI_PAGE_SIZE;
bootinfo->memmap_items++;
break;
default :
break;
}
 
}
 
 
//Run Kernel
asm volatile(
177,8 → 305,6
);
while(1){
((volatile int *)(0x80000000000b8000))[0]++;
}
//Not reached
return EFI_SUCCESS;
}
/branches/arm/boot/arch/ia64/loader/gefi/HelenOS/division.c
0,0 → 1,0
link ../../../../../../uspace/lib/softint/generic/division.c
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/boot/arch/ia64/loader/gefi/HelenOS/division.h
0,0 → 1,0
link ../../../../../../uspace/lib/softint/include/division.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/boot/arch/ia64/loader/gefi/HelenOS/mkimage.c
0,0 → 1,17
#include<stdio.h>
#include<stdlib.h>
 
int main(int argc,char** argv)
{
FILE *fi,*fo;
int count=0;
int ch;
fi=fopen("image.bin","rb");
fo=fopen("image.c","wb");
fprintf(fo,"char HOSimage[]={\n");
if((ch=getc(fi))!=EOF) {fprintf(fo,"0x%02X",ch);count++;}
while((ch=getc(fi))!=EOF) {fprintf(fo,",0x%02X",ch);count++;}
fprintf(fo,"};\nint HOSimagesize=%d;\n",count);
return EXIT_SUCCESS;
}
 
/branches/arm/boot/arch/ia64/loader/gefi/Make.defaults
27,30 → 27,19
#
INSTALLROOT=/usr/local
 
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
TOPDIR := $(shell pwd)
 
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
INCDIR = -I. -I$(CDIR)/inc -I$(CDIR)/inc/$(ARCH) -I$(CDIR)/inc/protocol
ARCH = ia64
INCDIR = -I. -I$(CDIR)/inc -I$(CDIR)/inc/$(ARCH) -I$(CDIR)/inc/protocol
CPPFLAGS = -DCONFIG_$(ARCH)
CFLAGS = -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants
LDFLAGS = -nostdlib
INSTALL = install
CFLAGS = -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -frename-registers -mfixed-range=f32-f127
LDFLAGS = -nostdlib
INSTALL = install
 
GCC_VERSION=$(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
 
# prefix =
CC = $(prefix)gcc
AS = $(prefix)as
LD = $(prefix)ld
AR = $(prefix)ar
RANLIB = $(prefix)ranlib
OBJCOPY = $(prefix)objcopy
OBJDUMP = $(prefix)objdump
 
 
ifneq ($(GCC_VERSION),2)
CFLAGS += -frename-registers
endif
 
CFLAGS += -mfixed-range=f32-f127
 
CC = $(prefix)gcc
AS = $(prefix)as
LD = $(prefix)ld
AR = $(prefix)ar
RANLIB = $(prefix)ranlib
OBJCOPY = $(prefix)objcopy
OBJDUMP = $(prefix)objdump
/branches/arm/boot/arch/ia64/loader/gefi/Makefile
23,9 → 23,9
 
include Make.defaults
 
SUBDIRS = lib gnuefi inc apps
SUBDIRS = lib gnuefi inc
 
all: check_gcc $(SUBDIRS)
all: $(SUBDIRS)
 
$(SUBDIRS):
$(MAKE) -C $@
39,13 → 39,4
 
.PHONY: $(SUBDIRS) clean depend
 
#
# on both platforms you must use gcc 3.0 or higher
#
check_gcc:
ifeq ($(GCC_VERSION),2)
@echo "you need to use a version of gcc >= 3.0, you are using `$(CC) --version`"
@exit 1
endif
 
include Make.rules
/branches/arm/boot/arch/ia64/loader/gefi/apps/Makefile
28,7 → 28,7
CRTOBJS = ../gnuefi/crt0-efi-$(ARCH).o
LDSCRIPT = ../gnuefi/elf_$(ARCH)_efi.lds
LDFLAGS += -T $(LDSCRIPT) -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS)
LOADLIBES = -lefi -lgnuefi
LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
FORMAT = efi-app-$(ARCH)
 
TARGETS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi printenv.efi t7.efi
/branches/arm/boot/arch/ia64/loader/main.c
1,6 → 1,6
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2006 Jakub Jermar
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
33,11 → 33,13
#include "_components.h"
#include <align.h>
#include <balloc.h>
#include <macros.h>
#include <string.h>
 
bootinfo_t bootinfo;
extern bootinfo_t binfo;
component_t components[COMPONENTS];
 
char *release = RELEASE;
char *release = STRING(RELEASE);
 
void write(const char *str, const int len)
{
44,15 → 46,22
return;
}
 
#define DEFAULT_MEMORY_BASE 0x4000000
#define DEFAULT_MEMORY_SIZE 0x4000000
#define DEFAULT_LEGACY_IO_BASE 0x00000FFFFC000000
#define DEFAULT_LEGACY_IO_SIZE 0x4000000
 
#define DEFAULT_FREQ_SCALE 0x0000000100000001 /* 1/1 */
#define DEFAULT_SYS_FREQ 100000000 /* 100MHz */
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = "\nBuilt on " TIMESTAMP;
char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
60,26 → 69,18
/** Print version information. */
static void version_print(void)
{
printf("HelenOS IA64 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp);
printf("HelenOS IA64 Bootloader\nRelease %s%s%s\n"
"Copyright (c) 2006 HelenOS project\n", release, revision,
timestamp);
}
 
void bootstrap(void)
{
 
int ii;
//for(ii=0;ii<KERNEL_SIZE;ii++) ((char *)(0x100000))[ii] = ((char *)KERNEL_START)[ii+1];
//((int *)(0x100000))[0]++;
bootinfo_t *bootinfo = &binfo;
 
 
 
version_print();
 
init_components(components);
 
printf("\nSystem info\n");
91,20 → 92,46
printf(" %P: %s image (size %d bytes)\n", components[i].start,
components[i].name, components[i].size);
 
if (!bootinfo->hello_configured) {
/*
* Load configuration defaults for simulators.
*/
bootinfo->memmap_items = 0;
bootinfo->memmap[bootinfo->memmap_items].base =
DEFAULT_MEMORY_BASE;
bootinfo->memmap[bootinfo->memmap_items].size =
DEFAULT_MEMORY_SIZE;
bootinfo->memmap[bootinfo->memmap_items].type =
EFI_MEMMAP_FREE_MEM;
bootinfo->memmap_items++;
 
bootinfo.taskmap.count = 0;
bootinfo->memmap[bootinfo->memmap_items].base =
DEFAULT_LEGACY_IO_BASE;
bootinfo->memmap[bootinfo->memmap_items].size =
DEFAULT_LEGACY_IO_SIZE;
bootinfo->memmap[bootinfo->memmap_items].type =
EFI_MEMMAP_IO_PORTS;
bootinfo->memmap_items++;
bootinfo->freq_scale = DEFAULT_FREQ_SCALE;
bootinfo->sys_freq = DEFAULT_SYS_FREQ;
}
 
bootinfo->taskmap.count = 0;
for (i = 0; i < COMPONENTS; i++) {
 
if (i > 0) {
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = components[i].start;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
bootinfo.taskmap.count++;
bootinfo->taskmap.tasks[bootinfo->taskmap.count].addr =
components[i].start;
bootinfo->taskmap.tasks[bootinfo->taskmap.count].size =
components[i].size;
strncpy(bootinfo->taskmap.tasks[
bootinfo->taskmap.count].name,
components[i].name, BOOTINFO_TASK_NAME_BUFLEN);
bootinfo->taskmap.count++;
}
}
 
 
jump_to_kernel(&bootinfo);
 
 
jump_to_kernel(bootinfo);
}
 
/branches/arm/boot/arch/ia64/loader/_link.ld.in
12,11 → 12,14
*(.data); /* initialized data */
_got = . ;
*(.got .got.*);
*(.bss); /* uninitialized static variables */
*(COMMON);
}
 
.sboot : {
*(.sdata);
*(.sdata2);
*(.sbss);
*(.bss); /* uninitialized static variables */
*(COMMON);
}
/DISCARD/ : {
/branches/arm/boot/arch/ia64/loader/asm.S
37,7 → 37,5
alloc loc0 = ar.pfs, 1, 1, 0, 0
movl r8 = 0x4404000;;
mov b1 = r8 ;;
mov r1 = in0;
mov r1 = in0; #Save bootinfo prt
br.call.sptk.many b0 = b1;;
.global ofw
ofw:
/branches/arm/boot/arch/ia64/loader/boot.S
34,6 → 34,7
.global start
start:
 
 
mov ar.rsc = r0
# movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
movl r1 = 0x4400000
57,6 → 58,22
mov b1 = r18 ;;
br.call.sptk.many b0 = b1
 
.align 512
ap_start:
 
 
ap_loop:
movl r18=0x4405000;;
mov b1 = r18 ;;
br.call.sptk.many b0 = b1;;
 
.align 1024
 
.align 4096
.global binfo
binfo:
 
 
.bss #on this line is ".bss", it cannot be seen in my mcedit :-(
 
 
/branches/arm/boot/arch/ia64/loader/main.h
29,29 → 29,14
#ifndef BOOT_ia64_MAIN_H_
#define BOOT_ia64_MAIN_H_
 
#include <ofw.h>
#include <ofw_tree.h>
#include <types.h>
#include <../../../../kernel/arch/ia64/include/bootinfo.h>
 
 
#define CONFIG_INIT_TASKS 32
 
typedef struct {
void *addr;
size_t size;
} init_task_t;
typedef struct {
count_t count;
init_task_t tasks[CONFIG_INIT_TASKS];
} init_t;
 
typedef struct {
init_t taskmap;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
extern void start(void);
extern void bootstrap(void);
 
/branches/arm/boot/arch/ia64/Makefile.inc
26,22 → 26,17
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#ifeq ($(MACHINE),ski)
 
build: $(BASE)/image.boot
 
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
 
depend:
-rm arch/$(ARCH)/loader/image.boot
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(ARCH)/loader/image.boot:
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
arch/$(BARCH)/loader/image.boot:
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 
clean: generic_clean
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -f $(BASE)/image.boot
 
#endif
 
/branches/arm/boot/arch/arm32/loader/Makefile
27,7 → 27,7
#
 
include ../../../../version
include ../../../Makefile.config
-include ../../../../Makefile.config
 
## Toolchain configuration
#
41,14 → 41,6
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin
 
ifeq ($(MACHINE), gxemul_testarm)
DMACHINE = MACHINE_GXEMUL_TESTARM
endif
 
ifeq ($(MACHINE), qemu_icp)
DMACHINE = MACHINE_QEMU_ICP
endif
 
ifeq ($(COMPILER),gcc_native)
CC = gcc
AS = as
65,28 → 57,17
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
endif
 
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../.. -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../.. -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -pipe
 
ifdef REVISION
CFLAGS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
ifdef MACHINE
CFLAGS += "-DMACHINE=$(MACHINE)"
endif
 
SOURCES = \
main.c \
boot.S \
asm.S \
mm.c \
print/write.c \
print/gxemul.c \
_components.c \
../../../generic/printf.c \
../../../generic/string.c \
../../../genarch/division.c
 
COMPONENTS = \
95,7 → 76,7
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
108,10 → 89,14
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/file_bd/file_bd \
$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
131,7 → 116,7
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
clean:
-for file in $(RD_SRVS) ; do \
153,7 → 138,7
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
endif
ifeq ($(RDFMT),fat)
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
endif
../../../../tools/mkhord.py 4096 initrd.fs initrd.img
rm initrd.fs
163,4 → 148,4
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.c
$(CC) -D$(DMACHINE) $(DEFS) $(CFLAGS) -c $< -o $@
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
/branches/arm/boot/arch/arm32/loader/main.c
32,13 → 32,16
*/
/** @file
* @brief Bootstrap.
*/
*/
 
 
#include "main.h"
#include "main.h"
#include "asm.h"
#include "_components.h"
#include <printf.h>
#include <align.h>
#include <macros.h>
#include <string.h>
 
#include "mm.h"
 
46,16 → 49,16
#define KERNEL_VIRTUAL_ADDRESS 0x80200000
 
 
char *release = RELEASE;
char *release = STRING(RELEASE);
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = "\nBuilt on " TIMESTAMP;
char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
64,7 → 67,7
/** Prints bootloader version information. */
static void version_print(void)
{
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2009 HelenOS project\n",
printf("HelenOS ARM32 Bootloader\nRelease %s%s%s\nCopyright (c) 2007 HelenOS project\n",
release, revision, timestamp);
}
 
84,31 → 87,40
printf(" kernel entry point at %L\n", KERNEL_VIRTUAL_ADDRESS);
printf(" %L: boot info structure\n", &bootinfo);
 
unsigned int top = 0;
bootinfo.cnt = 0;
unsigned int i, j;
for (i = 0; i < COMPONENTS; i++) {
printf(" %L: %s image (size %d bytes)\n",
components[i].start, components[i].name, components[i].size);
}
 
printf("\nCopying components\n");
 
unsigned int top = 0;
bootinfo.cnt = 0;
for (i = 0; i < COMPONENTS; i++) {
printf(" %s...", components[i].name);
components[i].start, components[i].name, components[i].size);
top = ALIGN_UP(top, KERNEL_PAGE_SIZE);
memcpy(((void *) KERNEL_VIRTUAL_ADDRESS) + top, components[i].start, components[i].size);
if (i > 0) {
bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top;
bootinfo.tasks[bootinfo.cnt].size = components[i].size;
strncpy(bootinfo.tasks[bootinfo.cnt].name,
components[i].name, BOOTINFO_TASK_NAME_BUFLEN);
bootinfo.cnt++;
}
top += components[i].size;
}
j = bootinfo.cnt - 1;
 
printf("\nCopying components\n");
 
for (i = COMPONENTS - 1; i > 0; i--, j--) {
printf(" %s...", components[i].name);
memcpy((void *)bootinfo.tasks[j].addr, components[i].start,
components[i].size);
printf("done.\n");
}
printf("\nCopying kernel...");
memcpy((void *)KERNEL_VIRTUAL_ADDRESS, components[0].start,
components[0].size);
printf("done.\n");
 
printf("\nBooting the kernel...\n");
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo));
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo);
}
 
/** @}
/branches/arm/boot/arch/arm32/loader/main.h
32,7 → 32,7
*/
/** @file
* @brief Boot related declarations.
*/
*/
 
 
#ifndef BOOT_arm32_MAIN_H
39,17 → 39,13
#define BOOT_arm32_MAIN_H
 
 
/** Aligns to the nearest higher address.
*
* @param addr Address or number to be aligned.
* @param align Size of alignment, must be power of 2.
*/
#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1))
 
/** Maximum number of tasks in the #bootinfo_t struct. */
#define TASKMAP_MAX_RECORDS 32
 
/** Size of buffer for storing task name in task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
 
/** Struct holding information about single loaded task. */
typedef struct {
/** Address where the task was placed. */
56,6 → 52,8
void *addr;
/** Size of the task's binary. */
unsigned int size;
/** Task name. */
char name[BOOTINFO_TASK_NAME_BUFLEN];
} task_t;
 
 
74,4 → 72,3
 
/** @}
*/
 
/branches/arm/boot/arch/arm32/loader/boot.S
34,10 → 34,8
.global start
.global jump_to_kernel
.global page_table
.global boot_stack
 
start:
ldr sp, =boot_stack
b bootstrap
 
jump_to_kernel:
48,10 → 46,6
#
bx r0
 
#bootloader stack
.section ST
.space 4096
boot_stack:
 
# place page_table to PT section
.section PT
59,5 → 53,3
# make place for PTL0 page table
page_table:
.skip PTL0_ENTRIES * PTL0_ENTRY_SIZE
 
 
/branches/arm/boot/arch/arm32/loader/asm.h
32,7 → 32,7
*/
/** @file
* @brief Functions implemented in assembly.
*/
*/
 
 
#ifndef BOOT_arm32_ASM_H
40,10 → 40,10
 
 
/** Copies cnt bytes from dst to src.
*
*
* @param dst Destination address.
* @param src Source address.
* @param cnt Count of bytes to be copied.
* @param cnt Count of bytes to be copied.
*/
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
58,12 → 58,11
 
/** Jumps to the kernel entry point.
*
* @param entry Kernel entry point address.
* @param bootinfo Structure holding information about loaded tasks.
* @param bootinfo_size Size of the bootinfo structure.
* @param entry Kernel entry point address.
* @param bootinfo Structure holding information about loaded tasks.
*
*/
extern void jump_to_kernel(void *entry, void *bootinfo,
unsigned int bootinfo_size) __attribute__((noreturn));
extern void jump_to_kernel(void *entry, void *bootinfo) __attribute__((noreturn));
 
 
#endif
/branches/arm/boot/arch/arm32/loader/_link.ld.in
17,9 → 17,6
*(COMMON); /* global variables */
*(.reginfo);
 
. = 0x2000;
*(ST); /* bootloader stack section */
 
. = 0x4000;
*(PT); /* page table placed at 0x4000 */
[[COMPONENTS]]
/branches/arm/boot/arch/arm32/loader/print/write.c
File deleted
/branches/arm/boot/arch/arm32/loader/print/gxemul.c
0,0 → 1,70
/*
* Copyright (c) 2007 Michal Kebrt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
 
/** @addtogroup arm32boot
* @{
*/
/** @file
* @brief GXemul specific code.
*/
 
 
#include <printf.h>
 
 
/** Address where characters to be printed are expected. */
#define PUTC_ADDRESS 0x10000000
 
 
/** Prints a character to the console.
*
* @param ch Character to be printed.
*/
static void putc(char ch)
{
*((volatile char *) PUTC_ADDRESS) = ch;
}
 
 
/** Prints a string to the console.
*
* @param str String to be printed.
* @param len Number of characters to be printed.
*/
void write(const char *str, const int len)
{
int i;
for (i = 0; i < len; ++i) {
putc(str[i]);
}
}
 
/** @}
*/
 
/branches/arm/boot/arch/arm32/Makefile.inc
28,15 → 28,15
 
build: $(BASE)/image.boot
 
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
 
depend:
-rm arch/$(ARCH)/loader/image.boot
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(ARCH)/loader/image.boot:
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE) MACHINE=$(MACHINE)
arch/$(BARCH)/loader/image.boot:
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 
clean:
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE)
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -f $(BASE)/image.boot
/branches/arm/boot/arch/ppc32/loader/debug.inc
File deleted
/branches/arm/boot/arch/ppc32/loader/Makefile
27,7 → 27,7
#
 
include ../../../../version
include ../../../Makefile.config
-include ../../../../Makefile.config
 
## Toolchain configuration
#
57,16 → 57,8
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
endif
 
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32 -pipe
 
ifdef REVISION
CFLAGS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
SOURCES = \
main.c \
ofwarch.c \
73,6 → 65,7
_components.c \
../../../genarch/ofw.c \
../../../generic/printf.c \
../../../generic/string.c \
asm.S \
boot.S
 
82,8 → 75,8
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
endif
95,10 → 88,13
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/file_bd/file_bd
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
118,7 → 114,7
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
clean:
-for file in $(RD_SRVS) ; do \
140,7 → 136,7
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
endif
ifeq ($(RDFMT),fat)
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
endif
../../../../tools/mkhord.py 4096 initrd.fs initrd.img
rm initrd.fs
/branches/arm/boot/arch/ppc32/loader/ofwarch.c
48,22 → 48,24
}
}
 
int ofw_keyboard(keyboard_t *keyboard)
int ofw_macio(macio_t *macio)
{
char device_name[BUF_SIZE];
if (ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0)
if ((ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0)
&& (ofw_get_property(ofw_aliases, "mac-io", device_name, sizeof(device_name)) <= 0))
return false;
phandle device = ofw_find_device(device_name);
if (device == -1)
return false;
pci_reg_t macio;
if (ofw_get_property(device, "assigned-addresses", &macio, sizeof(macio)) <= 0)
pci_reg_t pci_reg;
if (ofw_get_property(device, "assigned-addresses", &pci_reg, sizeof(pci_reg)) <= 0)
return false;
keyboard->addr = (void *) macio.addr.addr_lo;
keyboard->size = macio.size_lo;
macio->addr = (void *) pci_reg.addr.addr_lo;
macio->size = pci_reg.size_lo;
 
return true;
}
/branches/arm/boot/arch/ppc32/loader/main.c
32,6 → 32,8
#include "_components.h"
#include <ofw.h>
#include <align.h>
#include <macros.h>
#include <string.h>
 
#define HEAP_GAP 1024000
 
72,16 → 74,16
}
}
 
char *release = RELEASE;
char *release = STRING(RELEASE);
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = "\nBuilt on " TIMESTAMP;
char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
89,7 → 91,7
/** Print version information. */
static void version_print(void)
{
printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp);
printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n\n", release, revision, timestamp);
}
 
void bootstrap(void)
107,25 → 109,29
check_align(&trans, "translation table");
if (!ofw_memmap(&bootinfo.memmap)) {
printf("Error: unable to get memory map, halting.\n");
printf("Error: Unable to get memory map, halting.\n");
halt();
}
if (bootinfo.memmap.total == 0) {
printf("Error: no memory detected, halting.\n");
printf("Error: No memory detected, halting.\n");
halt();
}
if (!ofw_screen(&bootinfo.screen))
printf("Warning: unable to get screen properties.\n");
printf("Warning: Unable to get screen properties.\n");
if (!ofw_keyboard(&bootinfo.keyboard))
printf("Warning: unable to get keyboard properties.\n");
if (!ofw_macio(&bootinfo.macio))
printf("Warning: Unable to get macio properties.\n");
printf("\nDevice statistics\n");
printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
printf(" keyboard at %L (size %d bytes)\n", bootinfo.keyboard.addr, bootinfo.keyboard.size);
printf("Device statistics\n");
if (bootinfo.screen.addr)
printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline);
if (bootinfo.macio.addr)
printf(" macio at %L (size %d bytes)\n", bootinfo.macio.addr, bootinfo.macio.size);
void *real_mode_pa = ofw_translate(&real_mode);
void *trans_pa = ofw_translate(&trans);
void *bootinfo_pa = ofw_translate(&bootinfo);
161,6 → 167,9
if (j == 0) {
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) (pages << PAGE_WIDTH);
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
strncpy(bootinfo.taskmap.tasks[bootinfo.taskmap.count].name,
components[i].name, BOOTINFO_TASK_NAME_BUFLEN);
 
bootinfo.taskmap.count++;
}
}
172,6 → 181,8
fix_overlap(&trans, &trans_pa, "translation table", &top);
fix_overlap(&bootinfo, &bootinfo_pa, "boot info", &top);
ofw_setup_palette();
printf("\nBooting the kernel...\n");
jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa, (void *) bootinfo.screen.addr, bootinfo.screen.scanline);
}
/branches/arm/boot/arch/ppc32/loader/main.h
33,9 → 33,17
 
#define TASKMAP_MAX_RECORDS 32
 
/** Size of buffer for storing task name in task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
/** Struct holding information about single loaded task. */
typedef struct {
/** Address where the task was placed. */
void *addr;
/** Size of the task's binary. */
unsigned int size;
/** Task name. */
char name[BOOTINFO_TASK_NAME_BUFLEN];
} task_t;
 
typedef struct {
47,7 → 55,7
memmap_t memmap;
taskmap_t taskmap;
screen_t screen;
keyboard_t keyboard;
macio_t macio;
} bootinfo_t;
 
extern void start(void);
/branches/arm/boot/arch/ppc32/loader/_link.ld.in
1,9 → 1,9
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(start)
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(start)
 
SECTIONS {
.boot 0x10000000: AT (0) {
.boot 0x01000000: AT (0) {
*(BOOTSTRAP);
*(REALMODE);
*(.text);
10,12 → 10,12
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
[[COMPONENTS]]
}
}
/branches/arm/boot/arch/ppc32/loader/regname.h
208,11 → 208,13
#define hid0 1008
 
/* MSR bits */
#define msr_ir (1 << 4)
#define msr_dr (1 << 5)
#define msr_dr (1 << 4)
#define msr_ir (1 << 5)
#define msr_pr (1 << 14)
#define msr_ee (1 << 15)
 
/* HID0 bits */
#define hid0_sten (1 << 24)
#define hid0_ice (1 << 15)
#define hid0_dce (1 << 14)
#define hid0_icfi (1 << 11)
/branches/arm/boot/arch/ppc32/loader/asm.S
28,8 → 28,26
 
#include "asm.h"
#include "regname.h"
#include "debug.inc"
 
.macro SMC_COHERENCY addr
dcbst 0, \addr
sync
icbi 0, \addr
sync
isync
.endm
 
.macro FLUSH_DCACHE addr
dcbst 0, \addr
sync
isync
.endm
 
.macro TLB_FLUSH reg
tlbie \reg
addi \reg, \reg, 0x1000
.endm
 
.text
 
.global halt
140,9 → 158,6
 
real_mode:
DEBUG_INIT
DEBUG_real_mode
# copy kernel to proper location
#
# r5 = trans (pa)
163,14 → 178,13
mtctr r31
lwz r29, 0(r5)
DEBUG_INIT
DEBUG_copy_loop
copy_loop:
lwz r28, 0(r29)
stw r28, 0(r30)
SMC_COHERENCY r30
addi r29, r29, 4
addi r30, r30, 4
subi r6, r6, 4
180,15 → 194,11
bdnz copy_loop
DEBUG_end_copy_loop
addi r5, r5, 4
b page_copy
copy_end:
DEBUG_segments
# initially fill segment registers
li r31, 0
196,7 → 206,7
li r29, 8
mtctr r29
li r30, 0 # ASID 0 (VSIDs 0 .. 7)
 
seg_fill_uspace:
mtsrin r30, r31
220,8 → 230,6
# invalidate block address translation registers
DEBUG_bat
li r30, 0
mtspr ibat0u, r30
251,8 → 259,6
# create empty Page Hash Table
# on top of memory, size 64 KB
DEBUG_pht
lwz r31, 0(r3) # r31 = memory size
lis r30, 65536@h
274,6 → 280,7
# write zeroes
stw r29, 0(r31)
FLUSH_DCACHE r31
addi r31, r31, 4
subi r30, r30, 4
282,8 → 289,6
beq clear_end
bdnz pht_clear
 
DEBUG_end_pht_clear
clear_end:
291,8 → 296,6
# create BAT identity mapping
DEBUG_mapping
lwz r31, 0(r3) # r31 = memory size
lis r29, 0x0002
315,8 → 318,6
bdnz bat_mask
DEBUG_bat_mask
andi. r31, r31, 0x07ff # mask = mask & 0x07ff (BAT can map up to 256 MB)
li r29, 2
336,16 → 337,90
mtspr dbat0l, r30
no_bat:
 
#endif
DEBUG_tlb
# flush TLB
tlbia
li r31, 0
sync
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
TLB_FLUSH r31
eieio
tlbsync
sync
DEBUG_prepare
# start the kernel
#
# pc = KERNEL_START_ADDR
373,8 → 448,6
sync
isync
DEBUG_rfi
rfi
 
.align PAGE_WIDTH
/branches/arm/boot/arch/ppc32/Makefile.inc
26,17 → 26,27
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
build: $(BASE)/image.boot
TMP = distroot
 
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot
build: $(BASE)/image.iso
 
$(BASE)/image.iso: depend arch/$(BARCH)/loader/image.boot
mkdir -p $(TMP)/boot
mkdir -p $(TMP)/ppc
cp arch/$(BARCH)/loader/image.boot $(TMP)/boot/image.boot
cp arch/$(BARCH)/yaboot/ofboot.b $(TMP)/boot/ofboot.b
cp arch/$(BARCH)/yaboot/bootinfo.txt $(TMP)/ppc/bootinfo.txt
cp arch/$(BARCH)/yaboot/yaboot $(TMP)/boot/yaboot
cp arch/$(BARCH)/yaboot/yaboot.conf $(TMP)/boot/yaboot.conf
mkisofs -hfs -part -map arch/$(BARCH)/yaboot/maps -no-desktop -hfs-volid "HelenOS" -hfs-bless $(TMP)/boot -r -o $@ $(TMP)/
 
depend:
-rm arch/$(ARCH)/loader/image.boot
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(ARCH)/loader/image.boot:
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
arch/$(BARCH)/loader/image.boot:
$(MAKE) -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 
clean: generic_clean
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
-rm -f $(BASE)/image.boot
$(MAKE) -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/arm/boot/arch/ppc32/yaboot/yaboot.conf
0,0 → 1,5
device=cd:
timeout=0
 
image=/boot/image.boot
label=HelenOS
/branches/arm/boot/arch/ppc32/yaboot/ofboot.b
0,0 → 1,13
<CHRP-BOOT>
<COMPATIBLE>
MacRISC
</COMPATIBLE>
<DESCRIPTION>
HelenOS
</DESCRIPTION>
<BOOT-SCRIPT>
" screen" output
load-base release-load-area
boot cd:,\boot\yaboot
</BOOT-SCRIPT>
</CHRP-BOOT>
/branches/arm/boot/arch/ppc32/yaboot/bootinfo.txt
0,0 → 1,5
<chrp-boot>
<description>HelenOS</description>
<os-name>HelenOS</os-name>
<boot-script>boot cd:,\boot\yaboot</boot-script>
</chrp-boot>
/branches/arm/boot/arch/ppc32/yaboot/COPYING
0,0 → 1,340
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
 
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
 
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
 
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 
Also add information on how to contact you by electronic and paper mail.
 
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
 
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
 
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
 
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
 
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
 
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
/branches/arm/boot/arch/ppc32/yaboot/README
0,0 → 1,5
For licensing terms of Yaboot boot loader see the file COPYING contained
in this directory. Full version of Yaboot, including its source code,
can be downloaded from Yaboot's project page:
 
http://yaboot.ozlabs.org/
/branches/arm/boot/arch/ppc32/yaboot/maps
0,0 → 1,6
# EXTN XLate CREATOR TYPE Comment
.b Raw 'UNIX' 'tbxi' "bootstrap"
yaboot Raw 'UNIX' 'boot' "bootstrap"
image.boot Raw 'UNIX' 'boot' "kernel"
.conf Raw 'UNIX' 'conf' "bootstrap"
* Raw 'UNIX 'UNIX' "unix"
/branches/arm/boot/arch/ppc32/yaboot/yaboot
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/branches/arm/boot/arch/amd64/Makefile.inc
26,12 → 26,14
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
TMP = distroot
 
INIT_TASKS = \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
45,10 → 47,14
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/ata_bd/ata_bd \
$(USPACEDIR)/srv/bd/file_bd/file_bd
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
57,18 → 63,18
 
build: $(BASE)/image.iso
 
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
mkdir -p arch/$(ARCH)/iso/boot/grub
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/
$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
mkdir -p $(TMP)/boot/grub
cp arch/$(BARCH)/grub/stage2_eltorito $(TMP)/boot/grub/
ifneq ($(RDFMT),tmpfs)
cat arch/$(ARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(ARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" > $(TMP)/boot/grub/menu.lst
endif
ifneq ($(RDFMT),fat)
cat arch/$(ARCH)/grub/menu.lst | grep -v "fat" >arch/$(ARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" > $(TMP)/boot/grub/menu.lst
endif
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/
cp $(KERNELDIR)/kernel.bin $(TMP)/boot/
for task in $(INIT_TASKS) ; do \
cp $$task arch/$(ARCH)/iso/boot/ ; \
cp $$task $(TMP)/boot/ ; \
done
for file in $(RD_SRVS) ; do \
cp $$file $(USPACEDIR)/dist/srv/ ; \
77,14 → 83,14
cp $$file $(USPACEDIR)/dist/app/ ; \
done
ifeq ($(RDFMT),tmpfs)
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
ifeq ($(RDFMT),fat)
$(BASE)/tools/mkfat.sh $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
$(BASE)/tools/mkhord.py 4096 arch/$(ARCH)/iso/boot/initrd.fs arch/$(ARCH)/iso/boot/initrd.img
rm arch/$(ARCH)/iso/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/
$(BASE)/tools/mkhord.py 4096 $(TMP)/boot/initrd.fs $(TMP)/boot/initrd.img
rm $(TMP)/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $@ $(TMP)/
 
clean:
-for file in $(RD_SRVS) ; do \
93,5 → 99,5
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -fr arch/$(ARCH)/iso
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/arm/boot/arch/mips32/loader/_link.ld.in.ecoff
File deleted
/branches/arm/boot/arch/mips32/loader/_link.ld.in.binary
File deleted
/branches/arm/boot/arch/mips32/loader/Makefile
27,7 → 27,7
#
 
include ../../../../version
include ../../../Makefile.config
-include ../../../../Makefile.config
 
## Toolchain configuration
#
36,17 → 36,25
CROSS_PREFIX = /usr/local
endif
 
ifeq ($(IMAGE),binary)
LD_IN = binary
endif
ifeq ($(IMAGE),ecoff)
LD_IN = ecoff
endif
BFD_NAME = elf32-tradlittlemips
BFD_ARCH = mips
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin
 
ifeq ($(MACHINE),lgxemul)
BFD_NAME = elf32-tradlittlemips
BFD = ecoff-littlemips
endif
ifeq ($(MACHINE),bgxemul)
BFD_NAME = elf32-tradbigmips
BFD = ecoff-bigmips
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
TARGET = mips-linux-gnu
endif
ifeq ($(MACHINE),msim)
BFD_NAME = elf32-tradlittlemips
BFD = binary
endif
 
ifeq ($(COMPILER),gcc_native)
CC = gcc
AS = as
63,21 → 71,14
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
endif
 
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3 -pipe
 
ifdef REVISION
CFLAGS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
SOURCES = \
main.c \
msim.c \
_components.c \
../../../generic/printf.c \
../../../generic/string.c \
asm.S \
boot.S
 
87,8 → 88,8
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
endif
100,10 → 101,14
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/file_bd/file_bd \
$(USPACEDIR)/srv/bd/gxe_bd/gxe_bd
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
119,11 → 124,14
 
-include Makefile.depend
 
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@
image.boot: image.raw
$(OBJCOPY) -O $(BFD) $< $@
 
image.raw: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
$(LD) -no-check-sections -N -T _link.ld -o $@ $(COMPONENT_OBJECTS) initrd.o $(OBJECTS)
 
depend:
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null
 
clean:
-for file in $(RD_SRVS) ; do \
132,7 → 140,7
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -f _components.h _components.c _link.ld _link.ld.in $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot Makefile.depend
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.raw image.boot Makefile.depend
 
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in
for file in $(RD_SRVS) ; do \
145,15 → 153,12
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs
endif
ifeq ($(RDFMT),fat)
../../../../tools/mkfat.sh $(USPACEDIR)/dist/ initrd.fs
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs
endif
../../../../tools/mkhord.py 16384 initrd.fs initrd.img
rm initrd.fs
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned int" $(COMPONENTS) ./initrd.img
 
_link.ld.in: _link.ld.in.$(LD_IN)
cp $< $@
 
%.o: %.S
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
/branches/arm/boot/arch/mips32/loader/_link.ld.in
0,0 → 1,20
ENTRY(start)
 
SECTIONS {
.boot 0xbfc00000: AT (0) {
*(BOOTSTRAP);
*(.text);
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
*(.scommon);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
*(.reginfo);
[[COMPONENTS]]
}
}
/branches/arm/boot/arch/mips32/loader/main.c
28,6 → 28,9
 
#include "main.h"
#include <printf.h>
#include <align.h>
#include <macros.h>
#include <string.h>
#include "msim.h"
#include "asm.h"
#include "_components.h"
34,16 → 37,16
 
#define KERNEL_VIRTUAL_ADDRESS 0x80100000
 
char *release = RELEASE;
char *release = STRING(RELEASE);
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = "\nBuilt on " TIMESTAMP;
char *timestamp = "\nBuilt on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
72,9 → 75,10
printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size);
printf("\nCopying components\n");
unsigned int top = 0;
bootinfo.cnt = 0;
for (i = 0; i < COMPONENTS; i++) {
for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
printf(" %s...", components[i].name);
top = ALIGN_UP(top, PAGE_SIZE);
memcpy(((void *) KERNEL_VIRTUAL_ADDRESS) + top, components[i].start, components[i].size);
81,6 → 85,8
if (i > 0) {
bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top;
bootinfo.tasks[bootinfo.cnt].size = components[i].size;
strncpy(bootinfo.tasks[bootinfo.cnt].name,
components[i].name, BOOTINFO_TASK_NAME_BUFLEN);
bootinfo.cnt++;
}
top += components[i].size;
87,6 → 93,13
printf("done.\n");
}
unsigned int *cpumap = (unsigned int *) CPUMAP;
bootinfo.cpumap = 0;
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
if (cpumap[i] != 0)
bootinfo.cpumap |= (1 << i);
}
printf("\nBooting the kernel...\n");
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo));
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo);
}
/branches/arm/boot/arch/mips32/loader/main.h
29,21 → 29,30
#ifndef BOOT_mips32_MAIN_H_
#define BOOT_mips32_MAIN_H_
 
/** Align to the nearest higher address.
*
* @param addr Address or size to be aligned.
* @param align Size of alignment, must be power of 2.
*/
#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1))
#define CPUMAP 0x80001000
#define INITIAL_STACK 0x80002000
#define MSIM_DORDER_ADDRESS 0xb0000004
 
#define TASKMAP_MAX_RECORDS 32
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#ifndef __ASM__
 
/** Size of buffer for storing task name in task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
/** Struct holding information about single loaded task. */
typedef struct {
/** Address where the task was placed. */
void *addr;
/** Size of the task's binary. */
unsigned int size;
/** Task name. */
char name[BOOTINFO_TASK_NAME_BUFLEN];
} task_t;
 
typedef struct {
unsigned int cpumap;
unsigned int cnt;
task_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
52,3 → 61,5
extern void bootstrap(void);
 
#endif
 
#endif
/branches/arm/boot/arch/mips32/loader/boot.S
27,9 → 27,8
#
 
#include "regname.h"
#include "main.h"
 
#define INITIAL_STACK 0x80040000
 
.set noat
.set noreorder
.set nomacro
38,8 → 37,82
 
.global start
start:
lui $sp, INITIAL_STACK >> 16
ori $sp, $sp, INITIAL_STACK & 0xffff
j bootstrap
/* Setup CPU map (on msim this code
is executed in parallel on all CPUs,
but it not an issue) */
la $a0, CPUMAP
sw $zero, 0($a0)
sw $zero, 4($a0)
sw $zero, 8($a0)
sw $zero, 12($a0)
sw $zero, 16($a0)
sw $zero, 20($a0)
sw $zero, 24($a0)
sw $zero, 28($a0)
sw $zero, 32($a0)
sw $zero, 36($a0)
sw $zero, 40($a0)
sw $zero, 44($a0)
sw $zero, 48($a0)
sw $zero, 52($a0)
sw $zero, 56($a0)
sw $zero, 60($a0)
sw $zero, 64($a0)
sw $zero, 68($a0)
sw $zero, 72($a0)
sw $zero, 76($a0)
sw $zero, 80($a0)
sw $zero, 84($a0)
sw $zero, 88($a0)
sw $zero, 92($a0)
sw $zero, 96($a0)
sw $zero, 100($a0)
sw $zero, 104($a0)
sw $zero, 108($a0)
sw $zero, 112($a0)
sw $zero, 116($a0)
sw $zero, 120($a0)
sw $zero, 124($a0)
lui $a1, 1
#ifdef MACHINE_msim
/* Read dorder value */
la $k0, MSIM_DORDER_ADDRESS
lw $k1, ($k0)
/* If we are not running on BSP
then end in an infinite loop */
beq $k1, $zero, bsp
nop
/* Record CPU presence */
sll $a2, $k1, 2
addu $a2, $a2, $a0
sw $a1, ($a2)
loop:
j loop
nop
#endif
bsp:
/* Record CPU presence */
sw $a1, ($a0)
/* Setup initial stack */
la $sp, INITIAL_STACK
j bootstrap
nop
/branches/arm/boot/arch/mips32/loader/asm.h
29,11 → 29,11
#ifndef BOOT_mips32_ASM_H_
#define BOOT_mips32_ASM_H_
 
#define PAGE_SIZE 16384
#define PAGE_WIDTH 14
#define PAGE_SIZE 16384
#define PAGE_WIDTH 14
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
void jump_to_kernel(void *entry, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
void jump_to_kernel(void *entry, void *bootinfo) __attribute__((noreturn));
 
#endif
/branches/arm/boot/arch/mips32/Makefile.inc
28,15 → 28,15
 
build: $(BASE)/image.boot
 
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot
 
depend:
-rm arch/$(ARCH)/loader/image.boot
-rm arch/$(BARCH)/loader/image.boot
 
arch/$(ARCH)/loader/image.boot:
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE)
arch/$(BARCH)/loader/image.boot:
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 
clean:
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE)
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
-rm -f $(BASE)/image.boot
/branches/arm/boot/arch/ia32/Makefile.inc
26,13 → 26,15
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
TMP = distroot
 
INIT_TASKS = \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
$(USPACEDIR)/app/init/init \
$(USPACEDIR)/srv/devmap/devmap \
$(USPACEDIR)/srv/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
$(USPACEDIR)/srv/bd/rd/rd \
$(USPACEDIR)/srv/vfs/vfs
ifeq ($(RDFMT),tmpfs)
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs
endif
45,9 → 47,14
$(USPACEDIR)/srv/fb/fb \
$(USPACEDIR)/srv/kbd/kbd \
$(USPACEDIR)/srv/console/console \
$(USPACEDIR)/srv/fs/fat/fat
$(USPACEDIR)/srv/fs/devfs/devfs \
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \
$(USPACEDIR)/srv/fs/fat/fat \
$(USPACEDIR)/srv/bd/ata_bd/ata_bd \
$(USPACEDIR)/srv/bd/file_bd/file_bd
 
RD_APPS = \
$(USPACEDIR)/app/getvc/getvc \
$(USPACEDIR)/app/tetris/tetris \
$(USPACEDIR)/app/tester/tester \
$(USPACEDIR)/app/trace/trace \
56,18 → 63,18
 
build: $(BASE)/image.iso
 
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
mkdir -p arch/$(ARCH)/iso/boot/grub
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/
$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS)
mkdir -p $(TMP)/boot/grub
cp arch/$(BARCH)/grub/stage2_eltorito $(TMP)/boot/grub/
ifneq ($(RDFMT),tmpfs)
cat arch/$(ARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(ARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" > $(TMP)/boot/grub/menu.lst
endif
ifneq ($(RDFMT),fat)
cat arch/$(ARCH)/grub/menu.lst | grep -v "fat" >arch/$(ARCH)/iso/boot/grub/menu.lst
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" > $(TMP)/boot/grub/menu.lst
endif
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/
cp $(KERNELDIR)/kernel.bin $(TMP)/boot/
for task in $(INIT_TASKS) ; do \
cp $$task arch/$(ARCH)/iso/boot/ ; \
cp $$task $(TMP)/boot/ ; \
done
for file in $(RD_SRVS) ; do \
cp $$file $(USPACEDIR)/dist/srv/ ; \
76,14 → 83,14
cp $$file $(USPACEDIR)/dist/app/ ; \
done
ifeq ($(RDFMT),tmpfs)
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
ifeq ($(RDFMT),fat)
$(BASE)/tools/mkfat.sh $(USPACEDIR)/dist/ arch/$(ARCH)/iso/boot/initrd.fs
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ $(TMP)/boot/initrd.fs
endif
$(BASE)/tools/mkhord.py 4096 arch/$(ARCH)/iso/boot/initrd.fs arch/$(ARCH)/iso/boot/initrd.img
rm arch/$(ARCH)/iso/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/
$(BASE)/tools/mkhord.py 4096 $(TMP)/boot/initrd.fs $(TMP)/boot/initrd.img
rm $(TMP)/boot/initrd.fs
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $@ $(TMP)/
 
clean:
-for file in $(RD_SRVS) ; do \
92,5 → 99,5
-for file in $(RD_APPS) ; do \
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
done
-rm -fr arch/$(ARCH)/iso
-rm -fr $(TMP)
-rm -f $(BASE)/image.iso
/branches/arm/boot/arch/ia32/grub/README
File deleted
/branches/arm/boot/arch/ia32/grub/menu.lst
File deleted
/branches/arm/boot/arch/ia32/grub/stage2_eltorito
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Deleted: svn:mime-type
-application/octet-stream
\ No newline at end of property
/branches/arm/boot/arch/ia32/grub/COPYING
File deleted
/branches/arm/boot/arch/ia32/grub
0,0 → 1,0
link ../amd64/grub
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/boot/generic/printf.c
83,14 → 83,16
*/
static void print_number(const unative_t num, const unsigned int base)
{
int val = num;
char d[sizeof(unative_t) * 8 + 1]; /* this is good enough even for base == 2 */
int val = num;
 
/* This is enough even for base 2. */
char d[sizeof(unative_t) * 8 + 1];
int i = sizeof(unative_t) * 8 - 1;
 
do {
d[i--] = digits[val % base];
} while (val /= base);
 
d[sizeof(unative_t) * 8] = 0;
puts(&d[i + 1]);
}
156,89 → 158,89
int i = 0;
va_list ap;
char c;
 
va_start(ap, fmt);
 
while ((c = fmt[i++])) {
switch (c) {
/* control character */
 
/* control character */
case '%':
 
switch (c = fmt[i++]) {
 
/* percentile itself */
case '%':
break;
 
/*
* String and character conversions.
*/
case 's':
puts(va_arg(ap, char_ptr));
goto loop;
 
case 'c':
c = (char) va_arg(ap, int);
break;
 
/*
* Hexadecimal conversions with fixed width.
*/
case 'P':
puts("0x");
case 'p':
print_fixed_hex(va_arg(ap, unative_t),
sizeof(unative_t));
goto loop;
 
case 'Q':
puts("0x");
case 'q':
print_fixed_hex(va_arg(ap, uint64_t), INT64);
goto loop;
 
case 'L':
puts("0x");
case 'l':
print_fixed_hex(va_arg(ap, unative_t), INT32);
goto loop;
 
case 'W':
puts("0x");
case 'w':
print_fixed_hex(va_arg(ap, unative_t), INT16);
goto loop;
 
case 'B':
puts("0x");
case 'b':
print_fixed_hex(va_arg(ap, unative_t), INT8);
goto loop;
 
/*
* Decimal and hexadecimal conversions.
*/
case 'd':
print_number(va_arg(ap, unative_t), 10);
goto loop;
switch (c = fmt[i++]) {
/* percentile itself */
case '%':
break;
/*
* String and character conversions.
*/
case 's':
puts(va_arg(ap, char_ptr));
goto loop;
case 'c':
c = (char) va_arg(ap, int);
break;
/*
* Hexadecimal conversions with fixed width.
*/
case 'P':
puts("0x");
case 'p':
print_fixed_hex(va_arg(ap, unative_t), sizeof(unative_t));
goto loop;
case 'Q':
puts("0x");
case 'q':
print_fixed_hex(va_arg(ap, uint64_t), INT64);
goto loop;
case 'L':
puts("0x");
case 'l':
print_fixed_hex(va_arg(ap, unative_t), INT32);
goto loop;
case 'W':
puts("0x");
case 'w':
print_fixed_hex(va_arg(ap, unative_t), INT16);
goto loop;
case 'B':
puts("0x");
case 'b':
print_fixed_hex(va_arg(ap, unative_t), INT8);
goto loop;
/*
* Decimal and hexadecimal conversions.
*/
case 'd':
print_number(va_arg(ap, unative_t), 10);
goto loop;
case 'X':
puts("0x");
case 'x':
print_number(va_arg(ap, unative_t), 16);
goto loop;
/*
* Bad formatting.
*/
default:
goto out;
case 'X':
puts("0x");
case 'x':
print_number(va_arg(ap, unative_t), 16);
goto loop;
/*
* Bad formatting.
*/
default:
goto out;
}
default:
write(&c, 1);
 
default:
write(&c, 1);
}
loop:
;
}
/branches/arm/boot/generic/align.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
/branches/arm/boot/generic/macros.h
0,0 → 1,53
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef BOOT_MACROS_H_
#define BOOT_MACROS_H_
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
 
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
 
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
 
#endif
 
/** @}
*/
/branches/arm/boot/Makefile
29,7 → 29,8
## Include configuration
#
 
-include Makefile.config
-include ../Makefile.config
-include ../config.defs
 
## Paths
#
38,31 → 39,11
KERNELDIR = $(BASE)/kernel
USPACEDIR = $(BASE)/uspace
 
ifeq ($(CONFIG_DEBUG),y)
DEFS += -DCONFIG_DEBUG
endif
.PHONY: all build clean generic_clean
 
ifeq ($(CONFIG_BAT),y)
DEFS += -DCONFIG_BAT
endif
all: ../Makefile.config ../config.h ../config.defs build
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
-include arch/$(BARCH)/Makefile.inc
 
.PHONY: all build config distclean clean generic_clean
 
all:
../tools/config.py boot.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(IMAGE)
$(MAKE) -C . build
 
-include arch/$(ARCH)/Makefile.inc
 
config:
../tools/config.py boot.config
 
distclean: clean
-rm Makefile.config
 
generic_clean:
-rm generic/*.o genarch/*.o
/branches/arm/boot/tools/ppc32/font-8x16.c
File deleted
/branches/arm/boot/tools/ppc32/Makefile
File deleted
/branches/arm/boot/tools/ppc32/font-8x16.h
File deleted
/branches/arm/boot/tools/ppc32/debug.c
File deleted
/branches/arm/boot/tools/ia32/gen_vga323.c
1,8 → 1,36
/*
* Copyright (c) 2008 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
 
#include <stdio.h>
 
#define RED(i) ((i >> 5) & ((1 << 3) - 1))
#define GREEN(i) ((i >> 3) & ((1 << 2) - 1))
#define BLUE(i) (i & ((1 << 3) - 1))
#define RED(i) (((i) >> 5) & ((1 << 3) - 1))
#define GREEN(i) (((i) >> 3) & ((1 << 2) - 1))
#define BLUE(i) ((i) & ((1 << 3) - 1))
 
int main(int argc, char *argv[]) {
unsigned int i;
/branches/arm/boot/genarch/ofw.h
74,7 → 74,7
typedef struct {
void *addr;
uint32_t size;
} keyboard_t;
} macio_t;
 
typedef struct {
uint32_t info;
122,7 → 122,8
extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
extern int ofw_memmap(memmap_t *map);
extern int ofw_screen(screen_t *screen);
extern int ofw_keyboard(keyboard_t *keyboard);
extern int ofw_macio(macio_t *macio);
extern int ofw_setup_palette(void);
extern void ofw_quiesce(void);
 
#endif
/branches/arm/boot/genarch/ofw.c
25,7 → 25,7
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <ofw.h>
#include <ofwarch.h>
#include <printf.h>
48,7 → 48,8
if (ofw_chosen == -1)
halt();
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0)
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout,
sizeof(ofw_stdout)) <= 0)
ofw_stdout = 0;
ofw_root = ofw_find_device("/");
57,11 → 58,13
halt();
}
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu,
sizeof(ofw_mmu)) <= 0) {
puts("\r\nError: Unable to get mmu property, halted.\r\n");
halt();
}
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) {
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop,
sizeof(ofw_memory_prop)) <= 0) {
puts("\r\nError: Unable to get memory property, halted.\r\n");
halt();
}
81,14 → 84,18
 
/** Perform a call to OpenFirmware client interface.
*
* @param service String identifying the service requested.
* @param nargs Number of input arguments.
* @param nret Number of output arguments. This includes the return value.
* @param rets Buffer for output arguments or NULL. The buffer must accommodate nret - 1 items.
* @param service String identifying the service requested.
* @param nargs Number of input arguments.
* @param nret Number of output arguments. This includes the return
* value.
* @param rets Buffer for output arguments or NULL. The buffer must
* accommodate nret - 1 items.
*
* @return Return value returned by the client interface.
* @return Return value returned by the client interface.
*/
unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...)
unsigned long
ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets,
...)
{
va_list list;
ofw_args_t args;
119,7 → 126,9
return ofw_call("finddevice", 1, 1, NULL, name);
}
 
int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen)
int
ofw_get_property(const phandle device, const char *name, void *buf,
const int buflen)
{
return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen);
}
144,7 → 153,8
unsigned int ret = 1;
if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0)
if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0)
if (ofw_get_property(ofw_root, "#address-cells", &ret,
sizeof(ret)) <= 0)
ret = OFW_ADDRESS_CELLS;
return ret;
156,7 → 166,8
unsigned int ret;
if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0)
if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0)
if (ofw_get_property(ofw_root, "#size-cells", &ret,
sizeof(ret)) <= 0)
ret = OFW_SIZE_CELLS;
return ret;
192,7 → 203,8
ofw_arg_t result[4];
int shift;
 
if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, virt) != 0) {
if (ofw_call("call-method", 4, 5, result, "translate", ofw_mmu,
virt, 0) != 0) {
puts("Error: MMU method translate() failed, halting.\n");
halt();
}
212,7 → 224,8
{
ofw_arg_t retaddr;
 
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) {
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len,
virt) != 0) {
puts("Error: MMU method claim() failed, halting.\n");
halt();
}
269,8 → 282,8
phys_lo = (uintptr_t) phys;
}
 
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt,
phys_hi, phys_lo);
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size,
virt, phys_hi, phys_lo);
}
 
/** Save OpenFirmware physical memory map.
281,10 → 294,12
*/
int ofw_memmap(memmap_t *map)
{
unsigned int ac = ofw_get_address_cells(ofw_memory);
unsigned int sc = ofw_get_size_cells(ofw_memory);
unsigned int ac = ofw_get_address_cells(ofw_memory) /
(sizeof(uintptr_t) / sizeof(uint32_t));
unsigned int sc = ofw_get_size_cells(ofw_memory) /
(sizeof(uintptr_t) / sizeof(uint32_t));
 
uint32_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)];
uintptr_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)];
int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf));
if (ret <= 0) /* ret is the number of written bytes */
return false;
292,11 → 307,22
int pos;
map->total = 0;
map->count = 0;
for (pos = 0; (pos < ret / sizeof(uint32_t)) &&
for (pos = 0; (pos < ret / sizeof(uintptr_t)) &&
(map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) {
void * start = (void *) ((uintptr_t) buf[pos + ac - 1]);
void *start = (void *) (buf[pos + ac - 1]);
unsigned int size = buf[pos + ac + sc - 1];
 
/*
* This is a hot fix of the issue which occurs on machines
* where there are holes in the physical memory (such as
* SunBlade 1500). Should we detect a hole in the physical
* memory, we will ignore any memory detected behind
* the hole and pretend the hole does not exist.
*/
if ((map->count > 0) && (map->zones[map->count - 1].start +
map->zones[map->count - 1].size < start))
break;
 
if (size > 0) {
map->zones[map->count].start = start;
map->zones[map->count].size = size;
308,13 → 334,13
return true;
}
 
 
int ofw_screen(screen_t *screen)
{
char device_name[BUF_SIZE];
uint32_t virtaddr;
if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0)
if (ofw_get_property(ofw_aliases, "screen", device_name,
sizeof(device_name)) <= 0)
return false;
phandle device = ofw_find_device(device_name);
321,27 → 347,78
if (device == -1)
return false;
if (ofw_get_property(device, "address", &virtaddr, sizeof(virtaddr)) <= 0)
if (ofw_get_property(device, "address", &virtaddr,
sizeof(virtaddr)) <= 0)
return false;
 
screen->addr = (void *) ((uintptr_t) virtaddr);
 
if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0)
if (ofw_get_property(device, "width", &screen->width,
sizeof(screen->width)) <= 0)
return false;
if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0)
if (ofw_get_property(device, "height", &screen->height,
sizeof(screen->height)) <= 0)
return false;
if (ofw_get_property(device, "depth", &screen->bpp, sizeof(screen->bpp)) <= 0)
if (ofw_get_property(device, "depth", &screen->bpp,
sizeof(screen->bpp)) <= 0)
return false;
if (ofw_get_property(device, "linebytes", &screen->scanline, sizeof(screen->scanline)) <= 0)
if (ofw_get_property(device, "linebytes", &screen->scanline,
sizeof(screen->scanline)) <= 0)
return false;
return true;
}
 
#define RED(i) (((i) >> 5) & ((1 << 3) - 1))
#define GREEN(i) (((i) >> 3) & ((1 << 2) - 1))
#define BLUE(i) ((i) & ((1 << 3) - 1))
#define CLIP(i) ((i) <= 255 ? (i) : 255)
 
 
/**
* Sets up the palette for the 8-bit color depth configuration so that the
* 3:2:3 color scheme can be used. Checks that setting the palette makes sense
* (appropriate nodes exist in the OBP tree and the color depth is not greater
* than 8).
*
* @return true if the palette has been set, false otherwise
*
*/
int ofw_setup_palette(void)
{
char device_name[BUF_SIZE];
/* resolve alias */
if (ofw_get_property(ofw_aliases, "screen", device_name,
sizeof(device_name)) <= 0)
return false;
/* for depth greater than 8 it makes no sense to set up the palette */
uint32_t depth;
phandle device = ofw_find_device(device_name);
if (device == -1)
return false;
if (ofw_get_property(device, "depth", &depth, sizeof(uint32_t)) <= 0)
return false;
if (depth != 8)
return false;
/* required in order to be able to make a method call */
ihandle screen = ofw_open(device_name);
if (screen == -1)
return false;
/* setup the palette so that the (inverted) 3:2:3 scheme is usable */
unsigned int i;
for (i = 0; i < 256; i++)
ofw_call("call-method", 6, 1, NULL, "color!", screen,
255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37));
return true;
}
 
void ofw_quiesce(void)
{
ofw_call("quiesce", 0, 0, NULL);
/branches/arm/boot/genarch/ofw_tree.c
42,10 → 42,11
 
static ofw_tree_property_t *ofw_tree_properties_alloc(unsigned count)
{
return balloc(count * sizeof(ofw_tree_property_t), sizeof(ofw_tree_property_t));
return balloc(count * sizeof(ofw_tree_property_t),
sizeof(ofw_tree_property_t));
}
 
static void * ofw_tree_space_alloc(size_t size)
static void *ofw_tree_space_alloc(size_t size)
{
char *addr;
 
65,23 → 66,26
return addr;
}
 
/** Transfer information from one OpenFirmware node into its memory representation.
/** Transfer information from one OpenFirmware node into its memory
* representation.
*
* Transfer entire information from the OpenFirmware device tree 'current' node to
* its memory representation in 'current_node'. This function recursively processes
* all node's children. Node's peers are processed iteratively in order to prevent
* stack from overflowing.
* Transfer entire information from the OpenFirmware device tree 'current' node
* to its memory representation in 'current_node'. This function recursively
* processes all node's children. Node's peers are processed iteratively in
* order to prevent stack from overflowing.
*
* @param current_node Pointer to uninitialized ofw_tree_node structure that will
* become the memory represenation of 'current'.
* @param parent_node Parent ofw_tree_node structure or NULL in case of root node.
* @param current_node Pointer to uninitialized ofw_tree_node structure that
* will become the memory represenation of 'current'.
* @param parent_node Parent ofw_tree_node structure or NULL in case of root
* node.
* @param current OpenFirmware phandle to the current device tree node.
*/
static void ofw_tree_node_process(ofw_tree_node_t *current_node,
ofw_tree_node_t *parent_node, phandle current)
ofw_tree_node_t *parent_node, phandle current)
{
static char path[MAX_PATH_LEN+1];
static char path[MAX_PATH_LEN + 1];
static char name[OFW_TREE_PROPERTY_MAX_NAMELEN];
static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN];
phandle peer;
phandle child;
size_t len;
121,7 → 125,6
memcpy(current_node->da_name, &path[i], len);
current_node->da_name[len] = '\0';
/*
* Recursively process the potential child node.
*/
131,7 → 134,8
child_node = ofw_tree_node_alloc();
if (child_node) {
ofw_tree_node_process(child_node, current_node, child);
ofw_tree_node_process(child_node, current_node,
child);
current_node->child = child_node;
}
}
140,9 → 144,11
* Count properties.
*/
name[0] = '\0';
while (ofw_next_property(current, name, name) == 1)
while (ofw_next_property(current, name, name2) == 1) {
current_node->properties++;
memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
}
 
if (!current_node->properties)
return;
149,20 → 155,23
/*
* Copy properties.
*/
current_node->property = ofw_tree_properties_alloc(current_node->properties);
current_node->property =
ofw_tree_properties_alloc(current_node->properties);
if (!current_node->property)
return;
name[0] = '\0';
for (i = 0; ofw_next_property(current, name, name) == 1; i++) {
for (i = 0; ofw_next_property(current, name, name2) == 1; i++) {
size_t size;
if (i == current_node->properties)
break;
memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN);
memcpy(current_node->property[i].name, name,
OFW_TREE_PROPERTY_MAX_NAMELEN);
current_node->property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
OFW_TREE_PROPERTY_MAX_NAMELEN);
current_node->property[i].name[
OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0';
 
size = ofw_get_proplen(current, name);
current_node->property[i].size = size;
174,7 → 183,8
/*
* Copy property value to memory node.
*/
(void) ofw_get_property(current, name, buf, size);
(void) ofw_get_property(current, name,
buf, size);
}
} else {
current_node->property[i].value = NULL;
181,7 → 191,8
}
}
 
current_node->properties = i; /* Just in case we ran out of memory. */
/* Just in case we ran out of memory. */
current_node->properties = i;
 
/*
* Iteratively process the next peer node.
214,15 → 225,33
 
/** Construct memory representation of OpenFirmware device tree.
*
* @return NULL on failure or pointer to the root node.
* @return NULL on failure or pointer to the root node.
*/
ofw_tree_node_t *ofw_tree_build(void)
{
ofw_tree_node_t *root;
phandle ssm_node;
ofw_tree_node_t *ssm;
root = ofw_tree_node_alloc();
if (root)
ofw_tree_node_process(root, NULL, ofw_root);
 
/*
* The firmware client interface does not automatically include the
* "ssm" node in the list of children of "/". A nasty yet working
* solution is to explicitly stick "ssm" to the OFW tree.
*/
ssm_node = ofw_find_device("/ssm@0,0");
if (ssm_node != -1) {
ssm = ofw_tree_node_alloc();
if (ssm) {
ofw_tree_node_process(ssm, root,
ofw_find_device("/ssm@0,0"));
ssm->peer = root->child;
root->child = ssm;
}
}
return root;
}
/branches/arm/boot/genarch/balloc.h
31,7 → 31,7
 
#include <types.h>
 
#define BALLOC_MAX_SIZE (1024 * 1024)
#define BALLOC_MAX_SIZE (128 * 1024)
 
typedef struct {
uintptr_t base;
/branches/arm/defaults/amd64/Makefile.config
0,0 → 1,56
# Platform
PLATFORM = amd64
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Debug build
CONFIG_DEBUG = y
 
# Deadlock detection support for spinlocks
CONFIG_DEBUG_SPINLOCK = y
 
# Support for SMP
CONFIG_SMP = y
 
# Lazy FPU context switching
CONFIG_FPU_LAZY = y
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic
 
# PC keyboard support
CONFIG_PC_KBD = y
 
# EGA support
CONFIG_EGA = y
 
# Framebuffer support
CONFIG_FB = y
 
# Default framebuffer mode
CONFIG_VESA_MODE = 800x600
 
# Default framebuffer depth
CONFIG_VESA_BPP = 16
/branches/arm/defaults/amd64/output
0,0 → 1,0
image.iso
/branches/arm/defaults/ia32/Makefile.config
0,0 → 1,62
# Platform
PLATFORM = ia32
 
# CPU type
PROCESSOR = pentium4
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Debug build
CONFIG_DEBUG = y
 
# Deadlock detection support for spinlocks
CONFIG_DEBUG_SPINLOCK = y
 
# ACPI support
CONFIG_ACPI = y
 
# Support for SMP
CONFIG_SMP = y
 
# Lazy FPU context switching
CONFIG_FPU_LAZY = y
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic
 
# PC keyboard support
CONFIG_PC_KBD = y
 
# EGA support
CONFIG_EGA = y
 
# Framebuffer support
CONFIG_FB = y
 
# Default framebuffer mode
CONFIG_VESA_MODE = 800x600
 
# Default framebuffer depth
CONFIG_VESA_BPP = 16
/branches/arm/defaults/ia32/output
0,0 → 1,0
image.iso
/branches/arm/defaults/ppc32/Makefile.config
0,0 → 1,38
# Platform
PLATFORM = ppc32
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Debug build
CONFIG_DEBUG = y
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic
 
# Framebuffer support
CONFIG_FB = y
 
# Use Block Address Translation by the loader
CONFIG_BAT = y
/branches/arm/defaults/ppc32/output
0,0 → 1,0
image.iso
/branches/arm/defaults/sparc64/Makefile.config
0,0 → 1,56
# Platform
PLATFORM = sparc64
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Support for SMP
CONFIG_SMP = y
 
# Debug build
CONFIG_DEBUG = y
 
# Deadlock detection support for spinlocks
CONFIG_DEBUG_SPINLOCK = y
 
# Lazy FPU context switching
CONFIG_FPU_LAZY = y
 
# Use TSB
CONFIG_TSB = y
 
# Virtually indexed D-cache support
CONFIG_VIRT_IDX_DCACHE = y
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic
 
# Start AP processors by the loader
CONFIG_AP = y
 
# Preserve A.OUT header in isofs.b
CONFIG_AOUT_ISOFS_B = y
 
# External ramdisk
CONFIG_RD_EXTERNAL = y
/branches/arm/defaults/sparc64/serengeti/Makefile.config
0,0 → 1,2
# Machine type
MACHINE = serengeti
/branches/arm/defaults/sparc64/us3/Makefile.config
0,0 → 1,5
# Machine type
MACHINE = generic
 
# CPU type
PROCESSOR = us3
/branches/arm/defaults/sparc64/us/Makefile.config
0,0 → 1,5
# Machine type
MACHINE = generic
 
# CPU type
PROCESSOR = us
/branches/arm/defaults/sparc64/output
0,0 → 1,0
image.iso
/branches/arm/defaults/ia64/Makefile.config
0,0 → 1,44
# Platform
PLATFORM = ia64
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Debug build
CONFIG_DEBUG = y
 
# Deadlock detection support for spinlocks
CONFIG_DEBUG_SPINLOCK = y
 
# Support for SMP
CONFIG_SMP = y
 
# Lazy FPU context switching
CONFIG_FPU_LAZY = y
 
# Use VHPT
CONFIG_VHPT = n
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic
/branches/arm/defaults/ia64/i460GX/Makefile.config
0,0 → 1,3
# Machine type
MACHINE = i460GX
 
/branches/arm/defaults/ia64/output
0,0 → 1,0
image.boot
/branches/arm/defaults/ia64/ski/Makefile.config
0,0 → 1,2
# Machine type
MACHINE = ski
/branches/arm/defaults/arm32/Makefile.config
0,0 → 1,32
# Platform
PLATFORM = arm32
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Debug build
CONFIG_DEBUG = y
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# What is your input device?
CONFIG_HID_IN = generic
 
# What is your output device?
CONFIG_HID_OUT = generic
/branches/arm/defaults/arm32/output
0,0 → 1,0
image.boot
/branches/arm/defaults/mips32/Makefile.config
0,0 → 1,38
# Platform
PLATFORM = mips32
 
# Ramdisk format
RDFMT = fat
 
# Compiler
COMPILER = gcc_cross
 
# Debug build
CONFIG_DEBUG = y
 
# Deadlock detection support for spinlocks
CONFIG_DEBUG_SPINLOCK = y
 
# Support for SMP
CONFIG_SMP = y
 
# Support for userspace debuggers
CONFIG_UDEBUG = y
 
# Kernel console support
CONFIG_KCONSOLE = y
 
# Kernel symbol information
CONFIG_SYMTAB = y
 
# Detailed kernel logging
CONFIG_LOG = n
 
# Compile kernel tests
CONFIG_TEST = y
 
# Input device class
CONFIG_HID_IN = generic
 
# Output device class
CONFIG_HID_OUT = generic
/branches/arm/defaults/mips32/GXemul/Makefile.config
0,0 → 1,2
# Machine type
MACHINE = lgxemul
/branches/arm/defaults/mips32/output
0,0 → 1,0
image.boot
/branches/arm/defaults/mips32/msim/Makefile.config
0,0 → 1,2
# Machine type
MACHINE = msim
/branches/arm/tools/mkfat.sh
File deleted
Property changes:
Deleted: svn:executable
-*
\ No newline at end of property
/branches/arm/tools/mkfat.py
34,7 → 34,276
import os
import random
import xstruct
import array
 
exclude_names = set(['.svn'])
 
def align_up(size, alignment):
"Return size aligned up to alignment"
if (size % alignment == 0):
return size
return (((size / alignment) + 1) * alignment)
 
def subtree_size(root, cluster_size, dirent_size):
"Recursive directory walk and calculate size"
size = 0
files = 2
for name in os.listdir(root):
canon = os.path.join(root, name)
if (os.path.isfile(canon) and (not name in exclude_names)):
size += align_up(os.path.getsize(canon), cluster_size)
files += 1
if (os.path.isdir(canon) and (not name in exclude_names)):
size += subtree_size(canon, cluster_size, dirent_size)
files += 1
return size + align_up(files * dirent_size, cluster_size)
 
def root_entries(root):
"Return number of root directory entries"
return len(os.listdir(root))
 
def write_file(path, outf, cluster_size, data_start, fat, reserved_clusters):
"Store the contents of a file"
size = os.path.getsize(path)
prev = -1
first = 0
inf = file(path, "r")
rd = 0;
while (rd < size):
empty_cluster = fat.index(0)
fat[empty_cluster] = 0xffff
if (prev != -1):
fat[prev] = empty_cluster
else:
first = empty_cluster
prev = empty_cluster
data = inf.read(cluster_size);
outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size)
outf.write(data)
rd += len(data)
inf.close()
return first, size
 
def write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster):
"Store the contents of a directory"
length = len(directory)
size = length * dirent_size
prev = -1
first = 0
i = 0
rd = 0;
while (rd < size):
if (prev != -1):
empty_cluster = fat.index(0)
fat[empty_cluster] = 0xffff
fat[prev] = empty_cluster
else:
first = empty_cluster
prev = empty_cluster
data = ''
data_len = 0
while ((i < length) and (data_len < cluster_size)):
if (i == 0):
directory[i].cluster = empty_cluster
data += directory[i].pack()
data_len += dirent_size
i += 1
outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size)
outf.write(data)
rd += len(data)
return first, size
 
DIR_ENTRY = """little:
char name[8] /* file name */
char ext[3] /* file extension */
uint8_t attr /* file attributes */
uint8_t lcase /* file name case (NT extension) */
uint8_t ctime_fine /* create time (fine resolution) */
uint16_t ctime /* create time */
uint16_t cdate /* create date */
uint16_t adate /* access date */
padding[2] /* EA-index */
uint16_t mtime /* modification time */
uint16_t mdate /* modification date */
uint16_t cluster /* first cluster */
uint32_t size /* file size */
"""
 
DOT_DIR_ENTRY = """little:
uint8_t signature /* 0x2e signature */
char name[7] /* empty */
char ext[3] /* empty */
uint8_t attr /* file attributes */
padding[1] /* reserved for NT */
uint8_t ctime_fine /* create time (fine resolution) */
uint16_t ctime /* create time */
uint16_t cdate /* create date */
uint16_t adate /* access date */
padding[2] /* EA-index */
uint16_t mtime /* modification time */
uint16_t mdate /* modification date */
uint16_t cluster /* first cluster */
uint32_t size /* file size */
"""
 
DOTDOT_DIR_ENTRY = """little:
uint8_t signature[2] /* 0x2e signature */
char name[6] /* empty */
char ext[3] /* empty */
uint8_t attr /* file attributes */
padding[1] /* reserved for NT */
uint8_t ctime_fine /* create time (fine resolution) */
uint16_t ctime /* create time */
uint16_t cdate /* create date */
uint16_t adate /* access date */
padding[2] /* EA-index */
uint16_t mtime /* modification time */
uint16_t mdate /* modification date */
uint16_t cluster /* first cluster */
uint32_t size /* file size */
"""
 
def mangle_fname(name):
# FIXME: filter illegal characters
parts = name.split('.')
if (len(parts) > 0):
fname = parts[0]
else:
fname = ''
return (fname + ' ').upper()[0:8]
 
def mangle_ext(name):
# FIXME: filter illegal characters
parts = name.split('.')
if (len(parts) > 1):
ext = parts[1]
else:
ext = ''
return (ext + ' ').upper()[0:3]
 
def create_dirent(name, directory, cluster, size):
dir_entry = xstruct.create(DIR_ENTRY)
dir_entry.name = mangle_fname(name)
dir_entry.ext = mangle_ext(name)
if (directory):
dir_entry.attr = 0x30
else:
dir_entry.attr = 0x20
dir_entry.lcase = 0x18
dir_entry.ctime_fine = 0 # FIXME
dir_entry.ctime = 0 # FIXME
dir_entry.cdate = 0 # FIXME
dir_entry.adate = 0 # FIXME
dir_entry.mtime = 0 # FIXME
dir_entry.mdate = 0 # FIXME
dir_entry.cluster = cluster
if (directory):
dir_entry.size = 0
else:
dir_entry.size = size
return dir_entry
 
def create_dot_dirent(empty_cluster):
dir_entry = xstruct.create(DOT_DIR_ENTRY)
dir_entry.signature = 0x2e
dir_entry.name = ' '
dir_entry.ext = ' '
dir_entry.attr = 0x10
dir_entry.ctime_fine = 0 # FIXME
dir_entry.ctime = 0 # FIXME
dir_entry.cdate = 0 # FIXME
dir_entry.adate = 0 # FIXME
dir_entry.mtime = 0 # FIXME
dir_entry.mdate = 0 # FIXME
dir_entry.cluster = empty_cluster
dir_entry.size = 0
return dir_entry
 
def create_dotdot_dirent(parent_cluster):
dir_entry = xstruct.create(DOTDOT_DIR_ENTRY)
dir_entry.signature = [0x2e, 0x2e]
dir_entry.name = ' '
dir_entry.ext = ' '
dir_entry.attr = 0x10
dir_entry.ctime_fine = 0 # FIXME
dir_entry.ctime = 0 # FIXME
dir_entry.cdate = 0 # FIXME
dir_entry.adate = 0 # FIXME
dir_entry.mtime = 0 # FIXME
dir_entry.mdate = 0 # FIXME
dir_entry.cluster = parent_cluster
dir_entry.size = 0
return dir_entry
 
def recursion(head, root, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, parent_cluster):
"Recursive directory walk"
directory = []
if (not head):
# Directory cluster preallocation
empty_cluster = fat.index(0)
fat[empty_cluster] = 0xffff
directory.append(create_dot_dirent(empty_cluster))
directory.append(create_dotdot_dirent(parent_cluster))
else:
empty_cluster = 0
for name in os.listdir(root):
canon = os.path.join(root, name)
if (os.path.isfile(canon) and (not name in exclude_names)):
rv = write_file(canon, outf, cluster_size, data_start, fat, reserved_clusters)
directory.append(create_dirent(name, False, rv[0], rv[1]))
if (os.path.isdir(canon) and (not name in exclude_names)):
rv = recursion(False, canon, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
directory.append(create_dirent(name, True, rv[0], rv[1]))
if (head):
outf.seek(root_start)
for dir_entry in directory:
outf.write(dir_entry.pack())
else:
return write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
 
BOOT_SECTOR = """little:
uint8_t jmp[3] /* jump instruction */
char oem[8] /* OEM string */
62,6 → 331,14
uint8_t boot_signature[2] /* boot signature */
"""
 
EMPTY_SECTOR = """little:
padding[512] /* empty sector data */
"""
 
FAT_ENTRY = """little:
uint16_t next /* FAT16 entry */
"""
 
def usage(prname):
"Print usage syntax"
print prname + " <PATH> <IMAGE>"
76,27 → 353,59
print "<PATH> must be a directory"
return
fat16_clusters = 4096
sector_size = 512
cluster_size = 4096
dirent_size = 32
fatent_size = 2
fat_count = 2
reserved_clusters = 2
# Make sure the filesystem is large enought for FAT16
size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
while (size / cluster_size < fat16_clusters):
if (cluster_size > sector_size):
cluster_size /= 2
size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
else:
size = fat16_clusters * cluster_size + reserved_clusters * cluster_size
root_size = align_up(root_entries(path) * dirent_size, cluster_size)
fat_size = align_up(align_up(size, cluster_size) / cluster_size * fatent_size, sector_size)
sectors = (cluster_size + fat_count * fat_size + root_size + size) / sector_size
root_start = cluster_size + fat_count * fat_size
data_start = root_start + root_size
outf = file(sys.argv[2], "w")
boot_sector = xstruct.create(BOOT_SECTOR)
boot_sector.jmp = [0xEB, 0x3C, 0x90]
boot_sector.oem = "MSDOS5.0"
boot_sector.sector = 512
boot_sector.cluster = 8 # 4096 bytes per cluster
boot_sector.reserved = 1
boot_sector.fats = 2
boot_sector.rootdir = 224 # FIXME: root directory should be sector aligned
boot_sector.sectors = 0 # FIXME
boot_sector.sector = sector_size
boot_sector.cluster = cluster_size / sector_size
boot_sector.reserved = cluster_size / sector_size
boot_sector.fats = fat_count
boot_sector.rootdir = root_size / dirent_size
if (sectors <= 65535):
boot_sector.sectors = sectors
else:
boot_sector.sectors = 0
boot_sector.descriptor = 0xF8
boot_sector.fat_sectors = 0 # FIXME
boot_sector.track_sectors = 0 # FIXME
boot_sector.heads = 0 # FIXME
boot_sector.fat_sectors = fat_size / sector_size
boot_sector.track_sectors = 63
boot_sector.heads = 6
boot_sector.hidden = 0
boot_sector.sectors_big = 0 # FIXME
if (sectors > 65535):
boot_sector.sectors_big = sectors
else:
boot_sector.sectors_big = 0
boot_sector.drive = 0
boot_sector.drive = 0x80
boot_sector.extboot_signature = 0x29
boot_sector.serial = random.randint(0, 0xFFFFFFFF)
boot_sector.serial = random.randint(0, 0x7fffffff)
boot_sector.label = "HELENOS"
boot_sector.fstype = "FAT16 "
boot_sector.boot_signature = [0x55, 0xAA]
103,6 → 412,39
outf.write(boot_sector.pack())
empty_sector = xstruct.create(EMPTY_SECTOR)
# Reserved sectors
for i in range(1, cluster_size / sector_size):
outf.write(empty_sector.pack())
# FAT tables
for i in range(0, fat_count):
for j in range(0, fat_size / sector_size):
outf.write(empty_sector.pack())
# Root directory
for i in range(0, root_size / sector_size):
outf.write(empty_sector.pack())
# Data
for i in range(0, size / sector_size):
outf.write(empty_sector.pack())
fat = array.array('L', [0] * (fat_size / fatent_size))
fat[0] = 0xfff8
fat[1] = 0xffff
recursion(True, path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, 0)
# Store FAT
fat_entry = xstruct.create(FAT_ENTRY)
for i in range(0, fat_count):
outf.seek(cluster_size + i * fat_size)
for j in range(0, fat_size / fatent_size):
fat_entry.next = fat[j]
outf.write(fat_entry.pack())
outf.close()
if __name__ == '__main__':
/branches/arm/tools/config.py
1,6 → 1,7
#!/usr/bin/env python
#
# Copyright (c) 2006 Ondrej Palkovsky
# Copyright (c) 2009 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
27,512 → 28,432
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""
HelenOS configuration script
HelenOS configuration system
"""
import sys
import os
import re
import commands
import xtui
 
INPUT = sys.argv[1]
OUTPUT = 'Makefile.config'
TMPOUTPUT = 'Makefile.config.tmp'
MAKEFILE = 'Makefile.config'
MACROS = 'config.h'
DEFS = 'config.defs'
PRECONF = 'defaults'
 
class DefaultDialog:
"Wrapper dialog that tries to return default values"
def __init__(self, dlg):
self.dlg = dlg
def read_defaults(fname, defaults):
"Read saved values from last configuration run"
inf = file(fname, 'r')
for line in inf:
res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
if (res):
defaults[res.group(1)] = res.group(2)
inf.close()
 
def set_title(self,text):
self.dlg.set_title(text)
def yesno(self, text, default=None):
if default is not None:
return default
return self.dlg.yesno(text, default)
def noyes(self, text, default=None):
if default is not None:
return default
return self.dlg.noyes(text, default)
def choice(self, text, choices, defopt=None):
if defopt is not None:
return choices[defopt][0]
return self.dlg.choice(text, choices, defopt)
def check_condition(text, defaults, ask_names):
"Check that the condition specified on input line is True (only CNF and DNF is supported)"
ctype = 'cnf'
if ((')|' in text) or ('|(' in text)):
ctype = 'dnf'
if (ctype == 'cnf'):
conds = text.split('&')
else:
conds = text.split('|')
for cond in conds:
if (cond.startswith('(')) and (cond.endswith(')')):
cond = cond[1:-1]
inside = check_inside(cond, defaults, ctype)
if (ctype == 'cnf') and (not inside):
return False
if (ctype == 'dnf') and (inside):
return True
if (ctype == 'cnf'):
return True
return False
 
class NoDialog:
def __init__(self):
self.printed = None
self.title = 'HelenOS Configuration'
def check_inside(text, defaults, ctype):
"Check for condition"
if (ctype == 'cnf'):
conds = text.split('|')
else:
conds = text.split('&')
for cond in conds:
res = re.match(r'^(.*?)(!?=)(.*)$', cond)
if (not res):
raise RuntimeError("Invalid condition: %s" % cond)
condname = res.group(1)
oper = res.group(2)
condval = res.group(3)
if (not defaults.has_key(condname)):
varval = ''
else:
varval = defaults[condname]
if (varval == '*'):
varval = 'y'
if (ctype == 'cnf'):
if (oper == '=') and (condval == varval):
return True
if (oper == '!=') and (condval != varval):
return True
else:
if (oper == '=') and (condval != varval):
return False
if (oper == '!=') and (condval == varval):
return False
if (ctype == 'cnf'):
return False
return True
 
def print_title(self):
if not self.printed:
sys.stdout.write("\n*** %s ***\n" % self.title)
self.printed = True
def parse_config(fname, ask_names):
"Parse configuration file"
inf = file(fname, 'r')
name = ''
choices = []
for line in inf:
if (line.startswith('!')):
# Ask a question
res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
if (not res):
raise RuntimeError("Weird line: %s" % line)
cond = res.group(1)
varname = res.group(2)
vartype = res.group(3)
ask_names.append((varname, vartype, name, choices, cond))
name = ''
choices = []
continue
if (line.startswith('@')):
# Add new line into the 'choices' array
res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
if not res:
raise RuntimeError("Bad line: %s" % line)
choices.append((res.group(2), res.group(3)))
continue
if (line.startswith('%')):
# Name of the option
name = line[1:].strip()
continue
if ((line.startswith('#')) or (line == '\n')):
# Comment or empty line
continue
raise RuntimeError("Unknown syntax: %s" % line)
inf.close()
 
def set_title(self, text):
self.title = text
self.printed = False
def noyes(self, text, default=None):
if not default:
default = 'n'
return self.yesno(text, default)
def yesno(self, text, default=None):
self.print_title()
if default != 'n':
default = 'y'
while 1:
sys.stdout.write("%s (y/n)[%s]: " % (text,default))
inp = sys.stdin.readline()
if not inp:
raise EOFError
inp = inp.strip().lower()
if not inp:
return default
if inp == 'y':
return 'y'
elif inp == 'n':
return 'n'
def yes_no(default):
"Return '*' if yes, ' ' if no"
if (default == 'y'):
return '*'
return ' '
 
def _print_choice(self, text, choices, defopt):
sys.stdout.write('%s:\n' % text)
for i,(text,descr) in enumerate(choices):
if descr is '':
sys.stdout.write('\t%2d. %s\n' % (i, text))
else:
sys.stdout.write('\t%2d. %s\n' % (i, descr))
if defopt is not None:
sys.stdout.write('Enter choice number[%d]: ' % defopt)
else:
sys.stdout.write('Enter choice number: ')
def subchoice(screen, name, choices, default):
"Return choice of choices"
maxkey = 0
for key, val in choices:
length = len(key)
if (length > maxkey):
maxkey = length
options = []
position = None
cnt = 0
for key, val in choices:
if ((default) and (key == default)):
position = cnt
options.append(" %-*s %s " % (maxkey, key, val))
cnt += 1
(button, value) = xtui.choice_window(screen, name, 'Choose value', options, position)
if (button == 'cancel'):
return None
return choices[value][0]
 
def menu(self, text, choices, button, defopt=None):
self.title = 'Main menu'
menu = []
for key, descr in choices:
txt = key + (45-len(key))*' ' + ': ' + descr
menu.append((key, txt))
return self.choice(text, [button] + menu)
def choice(self, text, choices, defopt=None):
self.print_title()
while 1:
self._print_choice(text, choices, defopt)
inp = sys.stdin.readline()
if not inp:
raise EOFError
if not inp.strip():
if defopt is not None:
return choices[defopt][0]
continue
try:
number = int(inp.strip())
except ValueError:
continue
if number < 0 or number >= len(choices):
continue
return choices[number][0]
def check_choices(defaults, ask_names):
"Check whether all accessible variables have a default"
for varname, vartype, name, choices, cond in ask_names:
if ((cond) and (not check_condition(cond, defaults, ask_names))):
continue
if (not defaults.has_key(varname)):
return False
return True
 
def create_output(mkname, mcname, dfname, defaults, ask_names):
"Create output configuration"
revision = commands.getoutput('svnversion . 2> /dev/null')
timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
outmk = file(mkname, 'w')
outmc = file(mcname, 'w')
outdf = file(dfname, 'w')
outmk.write('#########################################\n')
outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
outmk.write('#########################################\n\n')
outmc.write('/***************************************\n')
outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n')
outmc.write(' ***************************************/\n\n')
outdf.write('#########################################\n')
outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
outdf.write('#########################################\n\n')
outdf.write('CONFIG_DEFS =')
for varname, vartype, name, choices, cond in ask_names:
if ((cond) and (not check_condition(cond, defaults, ask_names))):
continue
if (not defaults.has_key(varname)):
default = ''
else:
default = defaults[varname]
if (default == '*'):
default = 'y'
outmk.write('# %s\n%s = %s\n\n' % (name, varname, default))
if ((vartype == "y") or (vartype == "n") or (vartype == "y/n") or (vartype == "n/y")):
if (default == "y"):
outmc.write('/* %s */\n#define %s\n\n' % (name, varname))
outdf.write(' -D%s' % varname)
else:
outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default))
outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default))
outmk.write('REVISION = %s\n' % revision)
outmk.write('TIMESTAMP = %s\n' % timestamp)
outmc.write('#define REVISION %s\n' % revision)
outmc.write('#define TIMESTAMP %s\n' % timestamp)
outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp))
outmk.close()
outmc.close()
outdf.close()
 
def eof_checker(fnc):
def wrapper(self, *args, **kw):
try:
return fnc(self, *args, **kw)
except EOFError:
return getattr(self.bckdialog,fnc.func_name)(*args, **kw)
return wrapper
def sorted_dir(root):
list = os.listdir(root)
list.sort()
return list
 
class Dialog(NoDialog):
def __init__(self):
NoDialog.__init__(self)
self.dlgcmd = os.environ.get('DIALOG','dialog')
self.title = ''
self.backtitle = 'HelenOS Configuration'
if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0:
raise NotImplementedError
self.bckdialog = NoDialog()
def read_preconfigured(root, fname, screen, defaults):
options = []
opt2path = {}
cnt = 0
# Look for profiles
for name in sorted_dir(root):
path = os.path.join(root, name)
canon = os.path.join(path, fname)
if ((os.path.isdir(path)) and (os.path.exists(canon)) and (os.path.isfile(canon))):
subprofile = False
# Look for subprofiles
for subname in sorted_dir(path):
subpath = os.path.join(path, subname)
subcanon = os.path.join(subpath, fname)
if ((os.path.isdir(subpath)) and (os.path.exists(subcanon)) and (os.path.isfile(subcanon))):
subprofile = True
options.append("%s (%s)" % (name, subname))
opt2path[cnt] = (canon, subcanon)
cnt += 1
if (not subprofile):
options.append(name)
opt2path[cnt] = (canon, None)
cnt += 1
(button, value) = xtui.choice_window(screen, 'Load preconfigured defaults', 'Choose configuration profile', options, None)
if (button == 'cancel'):
return None
read_defaults(opt2path[value][0], defaults)
if (opt2path[value][1] != None):
read_defaults(opt2path[value][1], defaults)
 
def set_title(self,text):
self.title = text
self.bckdialog.set_title(text)
def calldlg(self,*args,**kw):
"Wrapper for calling 'dialog' program"
indesc, outdesc = os.pipe()
pid = os.fork()
if not pid:
os.close(2)
os.dup(outdesc)
os.close(indesc)
dlgargs = [self.dlgcmd,'--title',self.title,
'--backtitle', self.backtitle]
for key,val in kw.items():
dlgargs.append('--'+key)
dlgargs.append(val)
dlgargs += args
os.execlp(self.dlgcmd,*dlgargs)
 
os.close(outdesc)
try:
errout = os.fdopen(indesc,'r')
data = errout.read()
errout.close()
pid,status = os.wait()
except:
os.system('reset') # Reset terminal
raise
if not os.WIFEXITED(status):
os.system('reset') # Reset terminal
raise EOFError
status = os.WEXITSTATUS(status)
if status == 255:
raise EOFError
return status,data
def yesno(self, text, default=None):
if text[-1] not in ('?',':'):
text = text + ':'
width = '50'
height = '5'
if len(text) < 48:
text = ' '*int(((48-len(text))/2)) + text
else:
width = '0'
height = '0'
if default == 'n':
res,data = self.calldlg('--defaultno','--yesno',text,height,width)
else:
res,data = self.calldlg('--yesno',text,height,width)
 
if res == 0:
return 'y'
return 'n'
yesno = eof_checker(yesno)
 
def menu(self, text, choices, button, defopt=None):
self.title = 'Main menu'
text = text + ':'
width = '70'
height = str(8 + len(choices))
args = []
for key,val in choices:
args.append(key)
args.append(val)
 
kw = {}
if defopt:
kw['default-item'] = choices[defopt][0]
res,data = self.calldlg('--ok-label','Change',
'--extra-label',button[1],
'--extra-button',
'--menu',text,height,width,
str(len(choices)),*args,**kw)
if res == 3:
return button[0]
if res == 1: # Cancel
sys.exit(1)
elif res:
print data
raise EOFError
return data
menu = eof_checker(menu)
def choice(self, text, choices, defopt=None):
text = text + ':'
width = '50'
height = str(8 + len(choices))
args = []
for key,val in choices:
args.append(key)
args.append(val)
 
kw = {}
if defopt:
kw['default-item'] = choices[defopt][0]
res,data = self.calldlg('--nocancel','--menu',text,height,width,
str(len(choices)),*args, **kw)
if res:
print data
raise EOFError
return data
choice = eof_checker(choice)
def read_defaults(fname,defaults):
"Read saved values from last configuration run"
f = file(fname,'r')
for line in f:
res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
if res:
defaults[res.group(1)] = res.group(2)
f.close()
 
def check_condition(text, defaults, asked_names):
seen_vars = [ x[0] for x in asked_names ]
ctype = 'cnf'
if ')|' in text or '|(' in text:
ctype = 'dnf'
if ctype == 'cnf':
conds = text.split('&')
else:
conds = text.split('|')
 
for cond in conds:
if cond.startswith('(') and cond.endswith(')'):
cond = cond[1:-1]
inside = check_inside(cond, defaults, ctype, seen_vars)
if ctype == 'cnf' and not inside:
return False
if ctype == 'dnf' and inside:
return True
 
if ctype == 'cnf':
return True
return False
 
def check_inside(text, defaults, ctype, seen_vars):
"""
Check that the condition specified on input line is True
 
only CNF is supported
"""
if ctype == 'cnf':
conds = text.split('|')
else:
conds = text.split('&')
for cond in conds:
res = re.match(r'^(.*?)(!?=)(.*)$', cond)
if not res:
raise RuntimeError("Invalid condition: %s" % cond)
condname = res.group(1)
oper = res.group(2)
condval = res.group(3)
if condname not in seen_vars:
varval = ''
## raise RuntimeError("Variable %s not defined before being asked." %\
## condname)
elif not defaults.has_key(condname):
raise RuntimeError("Condition var %s does not exist: %s" % \
(condname,text))
else:
varval = defaults[condname]
if ctype == 'cnf':
if oper == '=' and condval == varval:
return True
if oper == '!=' and condval != varval:
return True
else:
if oper== '=' and condval != varval:
return False
if oper== '!=' and condval == varval:
return False
if ctype=='cnf':
return False
return True
 
def parse_config(input, output, dlg, defaults={}, askonly=None):
"Parse configuration file and create Makefile.config on the fly"
def ask_the_question(dialog):
"Ask question based on the type of variables to ask"
# This is quite a hack, this thingy is written just to
# have access to local variables..
if vartype == 'y/n':
return dialog.yesno(comment, default)
elif vartype == 'n/y':
return dialog.noyes(comment, default)
elif vartype == 'choice':
defopt = None
if default is not None:
for i,(key,val) in enumerate(choices):
if key == default:
defopt = i
break
return dialog.choice(comment, choices, defopt)
else:
raise RuntimeError("Bad method: %s" % vartype)
 
f = file(input, 'r')
outf = file(output, 'w')
 
outf.write('#########################################\n')
outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
outf.write('#########################################\n\n')
 
asked_names = []
 
comment = ''
default = None
choices = []
for line in f:
if line.startswith('%'):
res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line)
if not res:
raise RuntimeError('Invalid command: %s' % line)
if res.group(1):
if not check_condition(res.group(1), defaults,
asked_names):
continue
args = res.group(2).strip().split(' ')
cmd = args[0].lower()
args = args[1:]
if cmd == 'saveas':
outf.write('%s = %s\n' % (args[1],defaults[args[0]]))
elif cmd == 'shellcmd':
varname = args[0]
args = args[1:]
for i,arg in enumerate(args):
if arg.startswith('$'):
args[i] = defaults[arg[1:]]
data,status = commands.getstatusoutput(' '.join(args))
if status:
raise RuntimeError('Error running: %s' % ' '.join(args))
outf.write('%s = %s\n' % (varname,data.strip()))
continue
if line.startswith('!'):
# Ask a question
res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
if not res:
raise RuntimeError("Weird line: %s" % line)
varname = res.group(2)
vartype = res.group(3)
 
default = defaults.get(varname,None)
if res.group(1):
if not check_condition(res.group(1), defaults,
asked_names):
if default is not None:
outf.write('#!# %s = %s\n' % (varname, default))
# Clear cumulated values
comment = ''
default = None
choices = []
continue
asked_names.append((varname,comment))
 
if default is None or not askonly or askonly == varname:
default = ask_the_question(dlg)
else:
default = ask_the_question(DefaultDialog(dlg))
 
outf.write('%s = %s\n' % (varname, default))
# Remeber the selected value
defaults[varname] = default
# Clear cumulated values
comment = ''
default = None
choices = []
continue
if line.startswith('@'):
# Add new line into the 'choice array'
res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
if not res:
raise RuntimeError("Bad line: %s" % line)
if res.group(1):
if not check_condition(res.group(1),defaults,
asked_names):
continue
choices.append((res.group(2), res.group(3)))
continue
 
# All other things print to output file
outf.write(line)
if re.match(r'^#[^#]', line):
# Last comment before question will be displayed to the user
comment = line[1:].strip()
elif line.startswith('## '):
# Set title of the dialog window
dlg.set_title(line[2:].strip())
 
outf.write('\n')
outf.write('REVISION = %s\n' % commands.getoutput('svnversion . 2> /dev/null'))
outf.write('TIMESTAMP = %s\n' % commands.getoutput('date "+%Y-%m-%d %H:%M:%S"'))
outf.close()
f.close()
return asked_names
 
def main():
defaults = {}
try:
dlg = Dialog()
except NotImplementedError:
dlg = NoDialog()
 
if len(sys.argv) >= 3 and sys.argv[2]=='default':
defmode = True
else:
defmode = False
 
# Default run will update the configuration file
# with newest options
if os.path.exists(OUTPUT):
read_defaults(OUTPUT, defaults)
 
# Get ARCH from command line if specified
if len(sys.argv) >= 4:
defaults['ARCH'] = sys.argv[3]
defaults['PLATFORM'] = sys.argv[3]
defaults = {}
ask_names = []
# Get COMPILER from command line if specified
if len(sys.argv) >= 5:
defaults['COMPILER'] = sys.argv[4]
# Parse configuration file
parse_config(INPUT, ask_names)
# Get CONFIG_DEBUG from command line if specified
if len(sys.argv) >= 6:
defaults['CONFIG_DEBUG'] = sys.argv[5]
# Read defaults from previous run
if os.path.exists(MAKEFILE):
read_defaults(MAKEFILE, defaults)
# Get MACHINE/IMAGE from command line if specified
if len(sys.argv) >= 7:
defaults['MACHINE'] = sys.argv[6]
defaults['IMAGE'] = sys.argv[6]
# Default mode: only check defaults and regenerate configuration
if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
if (check_choices(defaults, ask_names)):
create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
return 0
# Check mode: only check defaults
if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')):
if (check_choices(defaults, ask_names)):
return 0
return 1
screen = xtui.screen_init()
try:
selname = None
position = None
while True:
# Cancel out all defaults which have to be deduced
for varname, vartype, name, choices, cond in ask_names:
if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')):
defaults[varname] = None
options = []
opt2row = {}
cnt = 1
options.append(" --- Load preconfigured defaults ... ")
for varname, vartype, name, choices, cond in ask_names:
if ((cond) and (not check_condition(cond, defaults, ask_names))):
continue
if (varname == selname):
position = cnt
if (not defaults.has_key(varname)):
default = None
else:
default = defaults[varname]
if (vartype == 'choice'):
# Check if the default is an acceptable value
if ((default) and (not default in [choice[0] for choice in choices])):
default = None
defaults.pop(varname)
# If there is just one option, use it
if (len(choices) == 1):
defaults[varname] = choices[0][0]
continue
if (default == None):
options.append("? %s --> " % name)
else:
options.append(" %s [%s] --> " % (name, default))
elif (vartype == 'y'):
defaults[varname] = '*'
continue
elif (vartype == 'n'):
defaults[varname] = 'n'
continue
elif (vartype == 'y/n'):
if (default == None):
default = 'y'
defaults[varname] = default
options.append(" <%s> %s " % (yes_no(default), name))
elif (vartype == 'n/y'):
if (default == None):
default = 'n'
defaults[varname] = default
options.append(" <%s> %s " % (yes_no(default), name))
else:
raise RuntimeError("Unknown variable type: %s" % vartype)
opt2row[cnt] = (varname, vartype, name, choices)
cnt += 1
if (position >= options):
position = None
(button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position)
if (button == 'cancel'):
return 'Configuration canceled'
if (button == 'done'):
if (check_choices(defaults, ask_names)):
break
else:
xtui.error_dialog(screen, 'Error', 'Some options have still undefined values. These options are marked with the "?" sign.')
continue
if (value == 0):
read_preconfigured(PRECONF, MAKEFILE, screen, defaults)
position = 1
continue
position = None
if (not opt2row.has_key(value)):
raise RuntimeError("Error selecting value: %s" % value)
(selname, seltype, name, choices) = opt2row[value]
if (not defaults.has_key(selname)):
default = None
else:
default = defaults[selname]
if (seltype == 'choice'):
defaults[selname] = subchoice(screen, name, choices, default)
elif ((seltype == 'y/n') or (seltype == 'n/y')):
if (defaults[selname] == 'y'):
defaults[selname] = 'n'
else:
defaults[selname] = 'y'
finally:
xtui.screen_done(screen)
create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names)
return 0
 
# Dry run only with defaults
varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
# If not in default mode, present selection of all possibilities
if not defmode:
defopt = 0
while 1:
# varnames contains variable names that were in the
# last question set
choices = [ (x[1],defaults[x[0]]) for x in varnames ]
res = dlg.menu('Configuration',choices,('save','Save'),defopt)
if res == 'save':
parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
break
# transfer description back to varname
for i,(vname,descr) in enumerate(varnames):
if res == descr:
defopt = i
break
# Ask the user a simple question, produce output
# as if the user answered all the other questions
# with default answer
varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults,
askonly=varnames[i][0])
if os.path.exists(OUTPUT):
os.unlink(OUTPUT)
os.rename(TMPOUTPUT, OUTPUT)
if not defmode and dlg.yesno('Rebuild everything?') == 'y':
os.execlp('make','make','clean','build')
 
if __name__ == '__main__':
main()
sys.exit(main())
/branches/arm/tools/xtui.py
0,0 → 1,260
#
# Copyright (c) 2009 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
"""
Text User Interface wrapper
"""
 
import sys
import os
 
def call_dlg(dlgcmd, *args, **kw):
"Wrapper for calling 'dialog' program"
indesc, outdesc = os.pipe()
pid = os.fork()
if (not pid):
os.close(2)
os.dup(outdesc)
os.close(indesc)
dlgargs = [dlgcmd]
for key, val in kw.items():
dlgargs.append('--' + key)
dlgargs.append(val)
dlgargs += args
os.execlp(dlgcmd, *dlgargs)
os.close(outdesc)
try:
errout = os.fdopen(indesc, 'r')
data = errout.read()
errout.close()
pid, status = os.wait()
except:
# Reset terminal
os.system('reset')
raise
if (not os.WIFEXITED(status)):
# Reset terminal
os.system('reset')
raise EOFError
status = os.WEXITSTATUS(status)
if (status == 255):
raise EOFError
return (status, data)
 
try:
import snack
newt = True
dialog = False
except ImportError:
newt = False
dlgcmd = os.environ.get('DIALOG', 'dialog')
if (call_dlg(dlgcmd, '--print-maxsize')[0] != 0):
dialog = False
else:
dialog = True
 
width_extra = 13
height_extra = 11
 
def width_fix(screen, width):
"Correct width to screen size"
if (width + width_extra > screen.width):
width = screen.width - width_extra
if (width <= 0):
width = screen.width
return width
 
def height_fix(screen, height):
"Correct height to screen size"
if (height + height_extra > screen.height):
height = screen.height - height_extra
if (height <= 0):
height = screen.height
return height
 
def screen_init():
"Initialize the screen"
if (newt):
return snack.SnackScreen()
return None
 
def screen_done(screen):
"Cleanup the screen"
if (newt):
screen.finish()
 
def choice_window(screen, title, text, options, position):
"Create options menu"
maxopt = 0
for option in options:
length = len(option)
if (length > maxopt):
maxopt = length
width = maxopt
height = len(options)
if (newt):
width = width_fix(screen, width + width_extra)
height = height_fix(screen, height)
if (height > 3):
large = True
else:
large = False
buttonbar = snack.ButtonBar(screen, ('Done', 'Cancel'))
textbox = snack.TextboxReflowed(width, text)
listbox = snack.Listbox(height, scroll = large, returnExit = 1)
cnt = 0
for option in options:
listbox.append(option, cnt)
cnt += 1
if (position != None):
listbox.setCurrent(position)
grid = snack.GridForm(screen, title, 1, 3)
grid.add(textbox, 0, 0)
grid.add(listbox, 0, 1, padding = (0, 1, 0, 1))
grid.add(buttonbar, 0, 2, growx = 1)
retval = grid.runOnce()
return (buttonbar.buttonPressed(retval), listbox.current())
elif (dialog):
if (width < 35):
width = 35
args = []
cnt = 0
for option in options:
args.append(str(cnt + 1))
args.append(option)
cnt += 1
kw = {}
if (position != None):
kw['default-item'] = str(position + 1)
status, data = call_dlg(dlgcmd, '--title', title, '--extra-button', '--extra-label', 'Done', '--menu', text, str(height + height_extra), str(width + width_extra), str(cnt), *args, **kw)
if (status == 1):
return ('cancel', None)
try:
choice = int(data) - 1
except ValueError:
return ('cancel', None)
if (status == 0):
return (None, choice)
return ('done', choice)
sys.stdout.write("\n *** %s *** \n%s\n\n" % (title, text))
maxcnt = len(str(len(options)))
cnt = 0
for option in options:
sys.stdout.write("%*s. %s\n" % (maxcnt, cnt + 1, option))
cnt += 1
sys.stdout.write("\n%*s. Done\n" % (maxcnt, '0'))
sys.stdout.write("%*s. Quit\n\n" % (maxcnt, 'q'))
while True:
if (position != None):
sys.stdout.write("Selection[%s]: " % str(position + 1))
else:
sys.stdout.write("Selection: ")
inp = sys.stdin.readline()
if (not inp):
raise EOFError
if (not inp.strip()):
if (position != None):
return (None, position)
continue
if (inp.strip() == 'q'):
return ('cancel', None)
try:
choice = int(inp.strip())
except ValueError:
continue
if (choice == 0):
return ('done', 0)
if (choice < 1) or (choice > len(options)):
continue
return (None, choice - 1)
 
def error_dialog(screen, title, msg):
"Print error dialog"
width = len(msg)
if (newt):
width = width_fix(screen, width)
buttonbar = snack.ButtonBar(screen, ['Ok'])
textbox = snack.TextboxReflowed(width, msg)
grid = snack.GridForm(screen, title, 1, 2)
grid.add(textbox, 0, 0, padding = (0, 0, 0, 1))
grid.add(buttonbar, 0, 1, growx = 1)
grid.runOnce()
elif (dialog):
call_dlg(dlgcmd, '--title', title, '--msgbox', msg, '6', str(width + width_extra))
else:
sys.stdout.write("\n%s: %s\n" % (title, msg))
/branches/arm/tools/mktmpfs.py
34,6 → 34,8
import os
import xstruct
 
exclude_names = set(['.svn'])
 
HEADER = """little:
char tag[5] /* 'TMPFS' */
"""
70,7 → 72,7
for name in os.listdir(root):
canon = os.path.join(root, name)
if (os.path.isfile(canon)):
if (os.path.isfile(canon) and (not name in exclude_names)):
size = os.path.getsize(canon)
dentry = xstruct.create(DENTRY_FILE % len(name))
89,7 → 91,7
rd += len(data)
inf.close()
if (os.path.isdir(canon)):
if (os.path.isdir(canon) and (not name in exclude_names)):
dentry = xstruct.create(DENTRY_DIRECTORY % len(name))
dentry.kind = TMPFS_DIRECTORY
dentry.fname_len = len(name)
/branches/arm/Makefile
29,112 → 29,21
## Include configuration
#
 
-include Makefile.config
.PHONY: all config distclean clean cscope
 
## Setup platform configuration
#
all: Makefile.config config.h config.defs
$(MAKE) -C kernel
$(MAKE) -C uspace
$(MAKE) -C boot
 
ifeq ($(PLATFORM),amd64)
KARCH = amd64
MACHINE = opteron
UARCH = amd64
BARCH = amd64
endif
Makefile.config config.h config.defs: HelenOS.config
tools/config.py HelenOS.config default
 
ifeq ($(PLATFORM),arm32)
KARCH = arm32
UARCH = arm32
BARCH = arm32
endif
 
ifeq ($(PLATFORM),ia32)
KARCH = ia32
UARCH = ia32
BARCH = ia32
endif
 
ifeq ($(PLATFORM),ia64)
KARCH = ia64
UARCH = ia64
BARCH = ia64
endif
 
ifeq ($(PLATFORM),mips32)
KARCH = mips32
BARCH = mips32
ifeq ($(MACHINE),msim)
UARCH = mips32
IMAGE = binary
endif
ifeq ($(MACHINE),simics)
UARCH = mips32
IMAGE = ecoff
endif
ifeq ($(MACHINE),bgxemul)
UARCH = mips32eb
IMAGE = ecoff
endif
ifeq ($(MACHINE),lgxemul)
UARCH = mips32
IMAGE = ecoff
endif
endif
 
ifeq ($(PLATFORM),ppc32)
KARCH = ppc32
UARCH = ppc32
BARCH = ppc32
endif
 
ifeq ($(PLATFORM),ppc64)
KARCH = ppc64
UARCH = ppc64
BARCH = ppc64
endif
 
ifeq ($(PLATFORM),sparc64)
KARCH = sparc64
UARCH = sparc64
BARCH = sparc64
endif
 
ifeq ($(PLATFORM),ia32xen)
KARCH = ia32xen
UARCH = ia32
BARCH = ia32xen
endif
 
.PHONY: all build config distclean clean cscope
 
all:
tools/config.py HelenOS.config default $(PLATFORM) $(COMPILER) $(CONFIG_DEBUG)
$(MAKE) -C . build
 
build:
ifneq ($(MACHINE),)
$(MAKE) -C kernel ARCH=$(KARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) MACHINE=$(MACHINE)
else
$(MAKE) -C kernel ARCH=$(KARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG)
endif
$(MAKE) -C uspace ARCH=$(UARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG)
ifneq ($(IMAGE),)
$(MAKE) -C boot ARCH=$(BARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) IMAGE=$(IMAGE) MACHINE=$(MACHINE)
else
$(MAKE) -C boot ARCH=$(BARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) MACHINE=$(MACHINE)
endif
 
config:
tools/config.py HelenOS.config
 
distclean:
-$(MAKE) -C kernel distclean
-$(MAKE) -C uspace distclean
-$(MAKE) -C boot distclean
rm -f Makefile.config tools/*.pyc
distclean: clean
rm -f Makefile.config config.h config.defs tools/*.pyc
 
clean:
-$(MAKE) -C kernel clean
/branches/arm/version
1,8 → 1,42
#
# Copyright (c) 2006 Martin Decky
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - 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.
# - The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# 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.
#
 
## This file defines the release information of HelenOS.
#
# The release string RELEASE consists of three or four components
# (version, patch level, sublevel and optionally an extra level).
#
# The NAME string is the code name of the given release.
#
 
VERSION = 0
PATCHLEVEL = 3
PATCHLEVEL = 4
SUBLEVEL = 0
#EXTRAVERSION = 0
NAME = Tartare
 
ifdef EXTRAVERSION
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION)
9,3 → 43,5
else
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)
endif
 
NAME = Sinister Valentine
/branches/arm/.
Property changes:
Deleted: svn:mergeinfo