default: all
-include config.mk
+include bertos/config.mk
#Include subtargets
include app/demo/demo.mk
#include app/battfs/battfs_test.mk
#include app/triface/triface.mk
-include rules.mk
+include bertos/rules.mk
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief CRC table and support routines
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "crc.h"
-
-/**
- * crctab calculated by Mark G. Mendel, Network Systems Corporation
- */
-const uint16_t crc16tab[256] = {
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
- 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
- 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
- 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
- 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
- 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
- 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
- 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
- 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
- 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
- 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
- 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
- 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
- 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
- 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
- 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
- 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
- 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
- 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
- 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
- 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
- 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
- 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
-};
-
-uint16_t crc16(uint16_t crc, const void *buffer, size_t len)
-{
- const unsigned char *buf = (const unsigned char *)buffer;
- while(len--)
- crc = UPDCRC16(*buf++, crc);
-
- return crc;
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief XModem-CRC16 algorithm (interface)
- *
- * \note This algorithm is incompatible with the CCITT-CRC16.
- *
- * This code is based on the article Copyright 1986 Stephen Satchell.
- *
- * Programmers may incorporate any or all code into their programs,
- * giving proper credit within the source. Publication of the
- * source routines is permitted so long as proper credit is given
- * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
- * Omen Technology.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef ALGO_CRC_H
-#define ALGO_CRC_H
-
-#include <cfg/compiler.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-/* CRC table */
-extern const uint16_t crc16tab[256];
-
-
-/**
- * \brief Compute the updated CRC16 value for one octet (macro version)
- *
- * \note This version is only intended for old/broken compilers.
- * Use the inline function in new code.
- *
- * \param c New octet (range 0-255)
- * \param oldcrc Previous CRC16 value (referenced twice, beware of side effects)
- */
-#define UPDCRC16(c, oldcrc) (crc16tab[((oldcrc) >> 8) ^ ((unsigned char)(c))] ^ ((oldcrc) << 8))
-
-
-#ifdef INLINE
-/**
- * \brief Compute the updated CRC16 value for one octet (macro version)
- */
-INLINE uint16_t updcrc16(uint8_t c, uint16_t oldcrc)
-{
- return crc16tab[(oldcrc >> 8) ^ c] ^ (oldcrc << 8);
-}
-#endif // INLINE
-
-
-/**
- * This function implements the CRC 16 calculation on a buffer.
- *
- * \param crc Current CRC16 value.
- * \param buf The buffer to perform CRC calculation on.
- * \param len The length of the Buffer.
- *
- * \return The updated CRC16 value.
- */
-extern uint16_t crc16(uint16_t crc, const void *buf, size_t len);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* ALGO_CRC_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief MD2 Message-Digest algorithm.
- *
- * The MD2 algorithm work with a constant array of 256 permutationt
- * defined in RFC1319. If you don't want to use a standard array of
- * permutatione you can use a md2_perm() function that generate an
- * array of 256 "casual" permutation. To swich from a standard array
- * to md2_perm function you must chanche CONFIG_MD2_STD_PERM defined in
- * appconfig.h.
- * If you need to store array in program memory you must define
- * a macro _PROGMEM (for more info see mware/pgm.h).
- *
- *
- * \version $Id$
- * \author Daniele Basile <asterix@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.17 2007/06/07 16:06:39 batt
- *#* Fix some doxygen errors.
- *#*
- *#* Revision 1.16 2007/02/15 13:29:49 asterix
- *#* Add MD2_DIGEST_LEN macro.
- *#*
- *#* Revision 1.15 2007/02/06 15:53:34 asterix
- *#* Add ROTR macro in m2d_perm, add comments, typos.
- *#*
- *#* Revision 1.13 2007/02/05 18:44:42 asterix
- *#* Add md2_perm function.
- *#*
- *#* Revision 1.12 2007/02/05 16:52:44 asterix
- *#* Add define for harvard architecture.
- *#*
- *#* Revision 1.11 2007/02/02 18:15:31 asterix
- *#* Add function MD2_test. Fix bug in md2_update function.
- *#*
- *#* Revision 1.9 2007/02/02 13:10:01 asterix
- *#* Fix some bugs in md2_pad and md2_update fuction.
- *#*
- *#* Revision 1.8 2007/02/01 14:45:56 asterix
- *#* Rewrite md2_update function and fix some bug.
- *#*
- *#* Revision 1.7 2007/01/31 18:04:15 asterix
- *#* Write md2_end function
- *#*
- *#* Revision 1.4 2007/01/31 13:51:57 asterix
- *#* Write md2_compute function.
- *#*
- *#* Revision 1.2 2007/01/30 17:31:44 asterix
- *#* Add function prototypes.
- *#*
- *#* Revision 1.1 2007/01/30 15:53:26 batt
- *#* Add first md2 skel.
- *#*
- *#*/
-
-#include "md2.h"
-
-#include <string.h> //memset(), memcpy();
-#include <cfg/compiler.h>
-#include <cfg/debug.h> //ASSERT()
-#include <cfg/macros.h> //MIN(), countof(), ROTR();
-#include <mware/pgm.h>
-
-
-#if CONFIG_MD2_STD_PERM
- /*
- * Official array of 256 byte pemutation contructed from digits of pi, defined
- * in the RFC 1319.
- */
- static const uint8_t PGM_ATTR md2_perm[256] =
- {
- 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
- 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
- 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
- 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
- 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
- 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
- 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
- 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
- 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
- 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
- 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
- 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
- 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
- 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
- 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
- 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
- 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
- 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
- };
-
- #define MD2_PERM(x) PGM_READ_CHAR(&md2_perm[x])
-#else
- /**
- * Md2_perm() function generate an array of 256 "casual" permutation.
- */
-
- /**
- * Costant define for computing an array of 256 "casual" permutation.
- * \{
- */
- #define K1 5
- #define K2 3
- #define R 2
- #define X 172
- /*\}*/
-
- static uint8_t md2_perm(uint8_t i)
- {
-
- i = i * K1;
- i = ROTR(i, R);
- i ^= X;
- i = i * K2;
-
- return i;
- }
-
- #define MD2_PERM(x) md2_perm(x)
-
-#endif
-
-
-/**
- * Pad function. Put len_pad unsigned char in
- * input block.
- */
-static void md2_pad(void *_block, size_t len_pad)
-{
- uint8_t *block;
-
- block = (uint8_t *)_block;
-
- ASSERT(len_pad <= CONFIG_MD2_BLOCK_LEN);
-
- /*
- * Fill input block with len_pad char.
- */
- memset(block, len_pad, len_pad);
-
-}
-
-static void md2_compute(void *_state, void *_checksum, void *_block)
-{
- int i = 0;
- uint16_t t = 0;
- uint8_t compute_array[COMPUTE_ARRAY_LEN];
- uint8_t *state;
- uint8_t *checksum;
- uint8_t *block;
-
- state = (uint8_t *)_state;
- checksum = (uint8_t *)_checksum;
- block = (uint8_t *)_block;
-
- /*
- * Copy state and checksum context in compute array.
- */
- memcpy(compute_array, state, CONFIG_MD2_BLOCK_LEN);
- memcpy(compute_array + CONFIG_MD2_BLOCK_LEN, block, CONFIG_MD2_BLOCK_LEN);
-
- /*
- * Fill compute array with state XOR block
- */
- for(i = 0; i < CONFIG_MD2_BLOCK_LEN; i++)
- compute_array[i + (CONFIG_MD2_BLOCK_LEN * 2)] = state[i] ^ block[i];
-
- /*
- * Encryt block.
- */
- for(i = 0; i < NUM_COMPUTE_ROUNDS; i++)
- {
- for(int j = 0; j < COMPUTE_ARRAY_LEN; j++)
- {
- compute_array[j] ^= MD2_PERM(t);
- t = compute_array[j];
- }
-
- t = (t + i) & 0xff; //modulo 256.
- }
- /*
- * Update checksum.
- */
- t = checksum[CONFIG_MD2_BLOCK_LEN - 1];
-
- for(i = 0; i < CONFIG_MD2_BLOCK_LEN; i++)
- {
- checksum[i] ^= MD2_PERM(block[i] ^ t);
- t = checksum[i];
- }
-
- /*
- * Update state and clean compute array.
- */
- memcpy(state, compute_array, CONFIG_MD2_BLOCK_LEN);
- memset(compute_array, 0, sizeof(compute_array));
-}
-
-/**
- * Algorithm initialization.
- *
- * \param context empty context.
- */
-void md2_init(Md2Context *context)
-{
-
- memset(context, 0, sizeof(Md2Context));
-
-}
-
-/**
- * Update block.
- */
-void md2_update(Md2Context *context, const void *_block_in, size_t block_len)
-{
-
- const uint8_t *block_in;
- size_t cpy_len;
-
-
- block_in = (const uint8_t *)_block_in;
-
- while(block_len > 0)
- {
- /*
- * Choose a number of block that fill input context buffer.
- */
- cpy_len = MIN(block_len, CONFIG_MD2_BLOCK_LEN - context->counter);
-
-
- /*
- * Copy in the buffer input block.
- */
- memcpy(&context->buffer[context->counter], block_in, cpy_len);
-
- /*
- * Update a context counter, input block length and remaning
- * context buffer block lenght.
- */
- context->counter += cpy_len;
- block_len -= cpy_len;
- block_in += cpy_len;
-
- /*
- * If buffer is full, compute it.
- */
- if (context->counter >= CONFIG_MD2_BLOCK_LEN)
- {
- md2_compute(context->state, context->checksum, context->buffer);
- context->counter = 0;
- }
- }
-
-
-}
-/**
- * Ends an MD2 message digest operation.
- * This fuction take an context and return a pointer
- * to context state.
- *
- * \param context in input.
- * \return a pointer to context state (message digest).
- */
-uint8_t *md2_end(Md2Context *context)
-{
-
- uint8_t buf[CONFIG_MD2_BLOCK_LEN];
-
- /*
- * Fill remaning empty context buffer.
- */
- md2_pad(buf, CONFIG_MD2_BLOCK_LEN - context->counter);
-
- /*
- * Update context buffer and compute it.
- */
- md2_update(context, buf, CONFIG_MD2_BLOCK_LEN - context->counter);
-
- /*
- * Add context checksum to message input.
- */
- md2_update(context, context->checksum, CONFIG_MD2_BLOCK_LEN);
-
-
- return context->state; //return a pointer to message digest.
-}
-/**
- * MD2 test fuction.
- * This function test MD2 algorithm with a standard string specified
- * in RFC 1319.
- *
- * \note This test work with official array of 256 byte pemutation
- * contructed from digits of pi, defined in the RFC 1319.
- *
- */
-bool md2_test(void)
-{
-
- Md2Context context;
-
- const char *test[] =
- {
- "",
- "message digest",
- "abcdefghijklmnopqrstuvwxyz",
- "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
- };
-
-
- const uint8_t *result[] = {
- "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73",
- "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0",
- "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47\x94\x0b",
- "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3\xef\xd8",
- };
-
-
- for (int i = 0; i < countof(test); i++)
- {
- md2_init(&context);
- md2_update(&context, test[i], strlen(test[i]));
-
- if(memcmp(result[i], md2_end(&context), MD2_DIGEST_LEN))
- return false;
- }
-
- return true;
-}
-
-#if 0
-
-#include <stdio.h>
-int main(int argc, char * argv[])
-{
-
- if(md2_test())
- printf("MD2 algorithm work well!\n");
- else
- printf("MD2 algorithm doesn't work well.\n");
-
-}
-
-#endif
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief MD2 Message-Digest algorithm.
- *
- * The algorithm takes as input a message of arbitrary length and produces
- * as output a 128-bit message digest of the input.
- * It is conjectured that it is computationally infeasible to produce
- * two messages having the same message digest, or to produce any
- * message having a given prespecified target message digest.
- *
- *
- *
- * \version $Id$
- * \author Daniele Basile <asterix@develer.com>
- */
-
-#ifndef ALGO_MD2_H
-#define ALGO_MD2_H
-
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-#define NUM_COMPUTE_ROUNDS 18 ///< Number of compute rounds.
-#define COMPUTE_ARRAY_LEN CONFIG_MD2_BLOCK_LEN * 3 ///< Lenght of compute array.
-#define MD2_DIGEST_LEN CONFIG_MD2_BLOCK_LEN
-/**
- * Context for MD2 computation.
- */
-typedef struct Md2Context
-{
- uint8_t buffer[CONFIG_MD2_BLOCK_LEN]; ///< Input buffer.
- uint8_t state[CONFIG_MD2_BLOCK_LEN]; ///< Current state buffer.
- uint8_t checksum[CONFIG_MD2_BLOCK_LEN]; ///< Checksum.
- size_t counter; ///< Counter of remaining bytes.
-
-} Md2Context;
-
-void md2_init(Md2Context *context);
-void md2_update(Md2Context *context, const void *block_in, size_t block_len);
-uint8_t *md2_end(Md2Context *context);
-bool md2_test(void);
-
-#endif /* ALGO_MD2_H */
+++ /dev/null
-/*!
- * \file
- * <!--
- * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Compute, save and load ramps for stepper motors (implementation)
- *
- * \version $Id$
- *
- * \author Simone Zinanni <s.zinanni@develer.com>
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- *
- *
- * The formula used by the ramp is the following:
- *
- * <pre>
- * a * b
- * f(t) = -------------
- * lerp(a,b,t)
- * </pre>
- *
- * Where <code>a</code> and <code>b</code> are the maximum and minimum speed
- * respectively (minimum and maximum wavelength respectively), and <code>lerp</code>
- * is a linear interpolation with a factor:
- *
- * <pre>
- * lerp(a,b,t) = a + t * (b - a) = (a * (1 - t)) + (b * t)
- * </pre>
- *
- * <code>t</code> must be in the [0,1] interval. It is easy to see that the
- * following holds true:
- *
- * <pre>
- * f(0) = b, f(1) = a
- * </pre>
- *
- * And that the function is monotonic. So, the function effectively interpolates
- * between the maximum and minimum speed through its domain ([0,1] -> [b,a]).
- *
- * The curve drawn by this function is similar to 1 / (sqrt(n)), so it is slower
- * than a linear acceleration (which would be 1/n).
- *
- * The floating point version uses a slightly modified function which accepts
- * the parameter in the domain [0, MT] (where MT is maxTime, the length of the
- * ramp, which is a setup parameter for the ramp). This is done to reduce the
- * number of operations per step. The formula looks like this:
- *
- * <pre>
- * a * b * MT
- * g(t) = ----------------------------
- * (a * MT) + t * (b - a)
- * </pre>
- *
- * It can be shown that this <code>g(t) = f(t * MT)</code>. The denominator
- * is a linear interpolation in the range [b*MT, a*MT], as t moves in the
- * interval [0, MT]. So the interpolation interval of the function is again
- * [b, a]. The implementation caches the value of the numerator and parts
- * of the denominator, so that the formula becomes:
- *
- * <pre>
- * alpha = a * b * MT
- * beta = a * MT
- * gamma = b - a
- *
- * alpha
- * g(t) = ----------------------
- * beta + t * gamma
- * </pre>
- *
- * and <code>t</code> is exactly the parameter that ramp_evaluate() gets,
- * that is the current time (in range [0, MT]). The operations performed
- * for each step are just an addition, a multiplication and a division.
- *
- * The fixed point version of the formula instead transforms the original
- * function as follows:
- *
- * <pre>
- * a * b a
- * f(t) = ------------------------- = --------------------
- * a a
- * b * ( - * (1 - t) + t ) - * (1 - t) + t
- * b b
- * </pre>
- *
- * <code>t</code> must be computed by dividing the current time (24 bit integer)
- * by the maximum time (24 bit integer). This is done by precomputing the
- * reciprocal of the maximum time as a 0.32 fixed point number, and multiplying
- * it to the current time. Multiplication is performed 8-bits a time by
- * FIX_MULT32(), so that we end up with a 0.16 fixed point number for
- * <code>t</code> (and <code>1-t</code> is just its twos-complement negation).
- * <code>a/b</code> is in the range [0,1] (because a is always less than b,
- * being the minimum wavelength), so it is precomputed as a 0.16 fixed point.
- * The final step is then computing the denominator and executing the division
- * (32 cycles using the 1-step division instruction in the DSP).
- *
- * The assembly implementation is needed for efficiency, but a C version of it
- * can be easily written, in case it is needed in the future.
- *
- */
-
-#include "ramp.h"
-#include <cfg/debug.h>
-
-#include <string.h> // memcpy()
-
-/**
- * Multiply \p a and \p b two integer at 32 bit and extract the high 16 bit word.
- */
-#define FIX_MULT32(a,b) (((uint64_t)(a)*(uint32_t)(b)) >> 16)
-
-void ramp_compute(struct Ramp *ramp, uint32_t clocksRamp, uint16_t clocksMinWL, uint16_t clocksMaxWL)
-{
- ASSERT(clocksMaxWL >= clocksMinWL);
-
- // Save values in ramp struct
- ramp->clocksRamp = clocksRamp;
- ramp->clocksMinWL = clocksMinWL;
- ramp->clocksMaxWL = clocksMaxWL;
-
-#if RAMP_USE_FLOATING_POINT
- ramp->precalc.gamma = ramp->clocksMaxWL - ramp->clocksMinWL;
- ramp->precalc.beta = (float)ramp->clocksMinWL * (float)ramp->clocksRamp;
- ramp->precalc.alpha = ramp->precalc.beta * (float)ramp->clocksMaxWL;
-
-#else
- ramp->precalc.max_div_min = ((uint32_t)clocksMinWL << 16) / (uint32_t)clocksMaxWL;
-
- /* Calcola 1/total_time in fixed point .32. Assumiamo che la rampa possa al
- * massimo avere 25 bit (cioé valore in tick fino a 2^25, che con il
- * prescaler=3 sono circa 7 secondi). Inoltre, togliamo qualche bit di precisione
- * da destra (secondo quanto specificato in RAMP_CLOCK_SHIFT_PRECISION).
- */
- ASSERT(ramp->clocksRamp < (1UL << (24 + RAMP_CLOCK_SHIFT_PRECISION)));
- ramp->precalc.inv_total_time = 0xFFFFFFFFUL / (ramp->clocksRamp >> RAMP_CLOCK_SHIFT_PRECISION);
- ASSERT(ramp->precalc.inv_total_time < 0x1000000UL);
-
-#endif
-}
-
-
-void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq)
-{
- uint32_t minWL, maxWL;
-
- minWL = TIME2CLOCKS(FREQ2MICROS(maxFreq));
- maxWL = TIME2CLOCKS(FREQ2MICROS(minFreq));
-
- ASSERT2(minWL < 65536UL, "Maximum frequency too high");
- ASSERT2(maxWL < 65536UL, "Minimum frequency too high");
- ASSERT(maxFreq > minFreq);
-
- ramp_compute(
- ramp,
- TIME2CLOCKS(length),
- TIME2CLOCKS(FREQ2MICROS(maxFreq)),
- TIME2CLOCKS(FREQ2MICROS(minFreq))
- );
-}
-
-void ramp_default(struct Ramp *ramp)
-{
- ramp_setup(ramp, RAMP_DEF_TIME, RAMP_DEF_MINFREQ, RAMP_DEF_MAXFREQ);
-}
-
-#if RAMP_USE_FLOATING_POINT
-
-float ramp_evaluate(const struct Ramp* ramp, float curClock)
-{
- return ramp->precalc.alpha / (curClock * ramp->precalc.gamma + ramp->precalc.beta);
-}
-
-#else
-
-INLINE uint32_t fix_mult32(uint32_t m1, uint32_t m2)
-{
- uint32_t accum = 0;
- accum += m1 * ((m2 >> 0) & 0xFF);
- accum >>= 8;
- accum += m1 * ((m2 >> 8) & 0xFF);
- accum >>= 8;
- accum += m1 * ((m2 >> 16) & 0xFF);
- return accum;
-}
-
-// a*b >> 16
-INLINE uint16_t fix_mult16(uint16_t a, uint32_t b)
-{
- return (b*(uint32_t)a) >> 16;
-}
-
-uint16_t FAST_FUNC ramp_evaluate(const struct Ramp* ramp, uint32_t curClock)
-{
- uint16_t t = FIX_MULT32(curClock >> RAMP_CLOCK_SHIFT_PRECISION, ramp->precalc.inv_total_time);
- uint16_t denom = fix_mult16((uint16_t)~t + 1, ramp->precalc.max_div_min) + t;
- uint16_t cur_delta = ((uint32_t)ramp->clocksMinWL << 16) / denom;
-
- return cur_delta;
-}
-
-#endif
-
-
+++ /dev/null
-
-/**
- * \file
- * <!--
- * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Compute, save and load ramps for stepper motors (interace)
- *
- * \version $Id$
- *
- * \author Simone Zinanni <s.zinanni@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- *
- * The acceleration ramp is used to properly accelerate a stepper motor. The main
- * entry point is the function ramp_evaluate(), which must be called at every step
- * of the motor: it gets as input the time elapsed since the stepper started
- * accelerating, and returns the time to wait before sending the next step. A pseudo
- * usage pattern is as follows:
- *
- * <pre>
- * float time = 0;
- * while (1)
- * {
- * float delta = ramp_evaluate(&my_ramp, time);
- * sleep(delta);
- * do_motor_step();
- * time += delta;
- * }
- * </pre>
- *
- * A similar pattern can be used to decelerate (it is sufficient to move the total
- * time backward, such as "time -= delta").
- *
- * The ramp can be configured with ramp_setup(), providing it with the minimum and
- * maximum operating frequency of the motor, and the total acceleration time in
- * milliseconds (that is, the time that will be needed to accelerate from the
- * minimum frequency to the maximum frequency).
- *
- * Both a very precise floating point and a very fast fixed point implementation
- * of the ramp evaluation are provided. The fixed point is hand-optimized assembly
- * for DSP56000 (but a portable C version of it can be easily written, see the
- * comments in the code).
- *
- */
-
-#ifndef ALGO_RAMP_H
-#define ALGO_RAMP_H
-
-#include <cfg/compiler.h>
-#include "hw_stepper.h"
-
-/**
- * Define whether the ramp will use floating point calculation within ramp_evaluate().
- * Otherwise, a less precise fixed point version will be used, which is faster on
- * platforms which do no support floating point operations.
- *
- * \note Floating point operations will be always done within ramp_compute() to
- * precalculate values, so there has to be at least a floating point emulation support.
- */
-#define RAMP_USE_FLOATING_POINT 0
-
-
-#if !RAMP_USE_FLOATING_POINT
-
- /**
- * Number of least-significant bits which are stripped away during ramp evaluation.
- * This setting allows to specify larger ramps at the price of less precision.
- *
- * The maximum ramp size allowed is 2^(24 + RAMP_CLOCK_SHIFT_PRECISION), in clocks.
- * For instance, using RAMP_CLOCK_SHIFT_PRECISION 1, and a 8x prescaler, the maximum
- * length of a ramp is about 6.7 secs. Raising RAMP_CLOCK_SHIFT_PRECISION to 2
- * brings the maximum length to 13.4 secs, at the price of less precision.
- *
- * ramp_compute() will check that the length is below the maximum allowed through
- * a runtime assertion.
- *
- * \note This macro is used only for the fixed-point version of the ramp.
- */
- #define RAMP_CLOCK_SHIFT_PRECISION 2
-#endif
-
-
-///< Negative pulse width for ramp
-#define RAMP_PULSE_WIDTH 50
-
-///< Default ramp
-#define RAMP_DEF_TIME 6000000 ///< microsecs
-#define RAMP_DEF_MAXFREQ 5000 ///< Hz
-#define RAMP_DEF_MINFREQ 200 ///< Hz
-#define RAMP_DEF_POWERRUN 10 ///< 10 deciampere (1 ampere)
-#define RAMP_DEF_POWERIDLE 1 ///< 1 deciampere
-
-
-/**
- * Convert microseconds to timer clock ticks
- */
-#define TIME2CLOCKS(micros) ((uint32_t)(micros) * (STEPPER_CLOCK / 1000000))
-
-/**
- * Convert timer clock ticks back to microseconds
- */
-#define CLOCKS2TIME(clocks) ((uint32_t)(clocks) / (STEPPER_CLOCK / 1000000))
-
-/**
- * Convert microseconds to Hz
- */
-#define MICROS2FREQ(micros) (1000000UL / ((uint32_t)(micros)))
-
-/**
- * Convert frequency (in Hz) to time (in microseconds)
- */
-#define FREQ2MICROS(hz) (1000000UL / ((uint32_t)(hz)))
-
-
-
-/**
- * Structure holding pre-calculated data for speeding up real-time evaluation
- * of the ramp. This structure is totally different between the fixed and the
- * floating point version of the code.
- *
- * Consult the file-level documentation of ramp.c for more information about
- * the values of this structure.
- */
-struct RampPrecalc
-{
-#if RAMP_USE_FLOATING_POINT
- float beta;
- float alpha;
- float gamma;
-#else
- uint16_t max_div_min;
- uint32_t inv_total_time;
-#endif
-};
-
-
-/**
- * Ramp structure
- */
-struct Ramp
-{
- uint32_t clocksRamp;
- uint16_t clocksMinWL;
- uint16_t clocksMaxWL;
-
- struct RampPrecalc precalc; ///< pre-calculated values for speed
-};
-
-
-/*
- * Function prototypes
- */
-void ramp_compute(
- struct Ramp * ramp,
- uint32_t clocksInRamp,
- uint16_t clocksInMinWavelength,
- uint16_t clocksInMaxWavelength);
-
-
-/** Setup an acceleration ramp for a stepper motor
- *
- * \param ramp Ramp to fill
- * \param length Length of the ramp (milliseconds)
- * \param minFreq Minimum operating frequency of the motor (hertz)
- * \param maxFreq Maximum operating frequency of the motor (hertz)
- *
- */
-void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq);
-
-
-/**
- * Initialize a new ramp with default values
- */
-void ramp_default(struct Ramp *ramp);
-
-
-/**
- * Evaluate the ramp at the given point. Given a \a ramp, and the current \a clock since
- * the start of the acceleration, compute the next step, that is the interval at which
- * send the signal to the motor.
- *
- * \note The fixed point version does not work when curClock is zero. Anyway,
- * the first step is always clocksMaxWL, as stored within the ramp structure.
- */
-#if RAMP_USE_FLOATING_POINT
- float ramp_evaluate(const struct Ramp* ramp, float curClock);
-#else
- uint16_t ramp_evaluate(const struct Ramp* ramp, uint32_t curClock);
-#endif
-
-
-/** Self test */
-void ramp_test(void);
-
-#endif /* ALGO_RAMP_H */
-
+++ /dev/null
-/*!
- * \file
- * <!--
- * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Test for compute, save and load ramps for stepper motors (implementation)
- *
- * \version $Id$
- *
- * \author Simone Zinanni <s.zinanni@develer.com>
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- *
- *
- * The formula used by the ramp is the following:
- *
- * <pre>
- * a * b
- * f(t) = -------------
- * lerp(a,b,t)
- * </pre>
- *
- * Where <code>a</code> and <code>b</code> are the maximum and minimum speed
- * respectively (minimum and maximum wavelength respectively), and <code>lerp</code>
- * is a linear interpolation with a factor:
- *
- * <pre>
- * lerp(a,b,t) = a + t * (b - a) = (a * (1 - t)) + (b * t)
- * </pre>
- *
- * <code>t</code> must be in the [0,1] interval. It is easy to see that the
- * following holds true:
- *
- * <pre>
- * f(0) = b, f(1) = a
- * </pre>
- *
- * And that the function is monotonic. So, the function effectively interpolates
- * between the maximum and minimum speed through its domain ([0,1] -> [b,a]).
- *
- * The curve drawn by this function is similar to 1 / (sqrt(n)), so it is slower
- * than a linear acceleration (which would be 1/n).
- *
- * The floating point version uses a slightly modified function which accepts
- * the parameter in the domain [0, MT] (where MT is maxTime, the length of the
- * ramp, which is a setup parameter for the ramp). This is done to reduce the
- * number of operations per step. The formula looks like this:
- *
- * <pre>
- * a * b * MT
- * g(t) = ----------------------------
- * (a * MT) + t * (b - a)
- * </pre>
- *
- * It can be shown that this <code>g(t) = f(t * MT)</code>. The denominator
- * is a linear interpolation in the range [b*MT, a*MT], as t moves in the
- * interval [0, MT]. So the interpolation interval of the function is again
- * [b, a]. The implementation caches the value of the numerator and parts
- * of the denominator, so that the formula becomes:
- *
- * <pre>
- * alpha = a * b * MT
- * beta = a * MT
- * gamma = b - a
- *
- * alpha
- * g(t) = ----------------------
- * beta + t * gamma
- * </pre>
- *
- * and <code>t</code> is exactly the parameter that ramp_evaluate() gets,
- * that is the current time (in range [0, MT]). The operations performed
- * for each step are just an addition, a multiplication and a division.
- *
- * The fixed point version of the formula instead transforms the original
- * function as follows:
- *
- * <pre>
- * a * b a
- * f(t) = ------------------------- = --------------------
- * a a
- * b * ( - * (1 - t) + t ) - * (1 - t) + t
- * b b
- * </pre>
- *
- * <code>t</code> must be computed by dividing the current time (24 bit integer)
- * by the maximum time (24 bit integer). This is done by precomputing the
- * reciprocal of the maximum time as a 0.32 fixed point number, and multiplying
- * it to the current time. Multiplication is performed 8-bits a time by
- * FIX_MULT32(), so that we end up with a 0.16 fixed point number for
- * <code>t</code> (and <code>1-t</code> is just its twos-complement negation).
- * <code>a/b</code> is in the range [0,1] (because a is always less than b,
- * being the minimum wavelength), so it is precomputed as a 0.16 fixed point.
- * The final step is then computing the denominator and executing the division
- * (32 cycles using the 1-step division instruction in the DSP).
- *
- * The assembly implementation is needed for efficiency, but a C version of it
- * can be easily written, in case it is needed in the future.
- *
- */
-
-#include "ramp.h"
-#include <cfg/debug.h>
-
-static bool ramp_test_single(uint32_t minFreq, uint32_t maxFreq, uint32_t length)
-{
- struct Ramp r;
- uint16_t cur, old;
- uint32_t clock;
- uint32_t oldclock;
-
- ramp_setup(&r, length, minFreq, maxFreq);
-
- cur = old = r.clocksMaxWL;
- clock = 0;
- oldclock = 0;
-
- kprintf("testing ramp: (length=%lu, min=%lu, max=%lu)\n", length, minFreq, maxFreq);
- kprintf(" [length=%lu, max=%04x, min=%04x]\n", r.clocksRamp, r.clocksMaxWL, r.clocksMinWL);
-
- int i = 0;
- int nonbyte = 0;
-
- while (clock + cur < r.clocksRamp)
- {
- oldclock = clock;
- old = cur;
-
- clock += cur;
- cur = ramp_evaluate(&r, clock);
-
- if (old < cur)
- {
- uint16_t t1 = FIX_MULT32(oldclock >> RAMP_CLOCK_SHIFT_PRECISION, r.precalc.inv_total_time);
- uint16_t t2 = FIX_MULT32(clock >> RAMP_CLOCK_SHIFT_PRECISION, r.precalc.inv_total_time);
- uint16_t denom1 = FIX_MULT32((uint16_t)((~t1) + 1), r.precalc.max_div_min) + t1;
- uint16_t denom2 = FIX_MULT32((uint16_t)((~t2) + 1), r.precalc.max_div_min) + t2;
-
- kprintf(" Failed: %04x @ %lu --> %04x @ %lu\n", old, oldclock, cur, clock);
- kprintf(" T: %04x -> %04x\n", t1, t2);
- kprintf(" DENOM: %04x -> %04x\n", denom1, denom2);
-
- cur = ramp_evaluate(&r, clock);
- return false;
- }
- i++;
- if ((old-cur) >= 256)
- nonbyte++;
- }
-
-
-
- kprintf("Test finished: %04x @ %lu [min=%04x, totlen=%lu, numsteps:%d, nonbyte:%d]\n", cur, clock, r.clocksMinWL, r.clocksRamp, i, nonbyte);
-
- return true;
-}
-
-
-void ramp_test(void)
-{
- bool ok = true;
-
- ok = ramp_test_single(200, 5000, 3000000) && ok;
- ok = ramp_test_single(1000, 2000, 1000000) && ok;
-
- if (ok)
- kputs("Ramp test succeeded!\n");
- else
- kputs("Ramp test fail!\n");
-}
-
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief API function for to manage entropy pool.
- *
- * \version $Id$
- * \author Daniele Basile <asterix@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.20 2007/06/07 16:06:39 batt
- *#* Fix some doxygen errors.
- *#*
- *#* Revision 1.19 2007/02/15 13:54:26 asterix
- *#* Rename randpool_getN in randpool_get. Fix bug in randpool_get.
- *#*
- *#* Revision 1.17 2007/02/15 13:40:42 asterix
- *#* Fix bug in randpool_add and randpool_strir.
- *#*
- *#* Revision 1.16 2007/02/13 15:11:37 asterix
- *#* Typo.
- *#*
- *#* Revision 1.14 2007/02/13 09:57:12 asterix
- *#* Add directive #if in struct EntropyPool, and remove #else in randpool_add.
- *#*
- *#* Revision 1.13 2007/02/12 18:25:34 asterix
- *#* Fix bug in randpool_getN.
- *#*
- *#* Revision 1.12 2007/02/12 09:47:39 asterix
- *#* Remove randpool_save. Add randpool_pool.
- *#*
- *#* Revision 1.10 2007/02/12 09:03:32 asterix
- *#* Add CONFIG_RANDPOOL_TIMER macro to swich on or off timer support
- *#*
- *#* Revision 1.9 2007/02/09 17:58:09 asterix
- *#* Add macro CONFIG_RANDPOOL_TIMER.
- *#*
- *#* Revision 1.6 2007/02/09 09:24:38 asterix
- *#* Typos. Add data_len in randpool_add and n_byte in randpool_push pototypes.
- *#*
- *#* Revision 1.3 2007/02/08 14:25:29 asterix
- *#* Write static funcion push_byte.
- *#*
- *#*/
-
-#include "randpool.h"
-#include "md2.h"
-
-#include <stdio.h> //sprintf();
-#include <string.h> //memset(), memcpy();
-
-#include <cfg/compiler.h>
-#include <cfg/debug.h> //ASSERT()
-#include <cfg/macros.h> //MIN(), ROUND_UP();
-
-#if CONFIG_RANDPOOL_TIMER
- #include <drv/timer.h> //timer_clock();
-#endif
-
-
-
-/*
- * Insert bytes in entropy pool, making a XOR of bytes present
- * in entropy pool.
- */
-static void randpool_push(EntropyPool *pool, void *_byte, size_t n_byte)
-{
- size_t i = pool->pos_add; // Current number of byte insert in entropy pool.
- uint8_t *byte;
-
- byte = (uint8_t *)_byte;
-
- /*
- * Insert a bytes in entropy pool.
- */
- for(int j = 0; j < n_byte; j++)
- {
- pool->pool_entropy[i] = pool->pool_entropy[i] ^ byte[j];
- i = (++i) % CONFIG_SIZE_ENTROPY_POOL;
- }
-
- pool->pos_add = i; // Update a insert bytes.
-}
-
-
-/*
- * This function stir entropy pool with MD2 function hash.
- *
- */
-static void randpool_stir(EntropyPool *pool)
-{
- size_t entropy = pool->entropy; //Save current calue of entropy.
- Md2Context context;
- uint8_t tmp_buf[((sizeof(size_t) * 2) + sizeof(int)) * 2 + 1]; //Temporary buffer.
-
- md2_init(&context); //Init MD2 algorithm.
-
- randpool_add(pool, NULL, 0);
-
- for (int i = 0; i < (CONFIG_SIZE_ENTROPY_POOL / MD2_DIGEST_LEN); i++)
- {
- sprintf(tmp_buf, "%0x%0x%0x",pool->counter, i, pool->pos_add);
-
- /*
- * Hash with MD2 algorithm the entropy pool.
- */
- md2_update(&context, pool->pool_entropy, CONFIG_SIZE_ENTROPY_POOL);
-
- md2_update(&context, tmp_buf, sizeof(tmp_buf) - 1);
-
- /*Insert a message digest in entropy pool.*/
- randpool_push(pool, md2_end(&context), MD2_DIGEST_LEN);
-
- pool->counter = pool->counter + 1;
-
- }
-
- /*Insert in pool the difference between a two call of this function (see above).*/
- randpool_add(pool, NULL, 0);
-
- pool->entropy = entropy; //Restore old value of entropy. We haven't add entropy.
-}
-
-/**
- * Add \param entropy bits from \param data buffer to the entropy \param pool
- */
-void randpool_add(EntropyPool *pool, void *data, size_t entropy)
-{
- uint8_t sep[] = "\xaa\xaa\xaa\xaa"; // ??
- size_t data_len = ROUND_UP(entropy, 8) / 8; //Number of entropy byte in input.
-
- randpool_push(pool, data, data_len); //Insert data to entropy pool.
-
-#if CONFIG_RANDPOOL_TIMER
-
- ticks_t event = timer_clock();
- ticks_t delta;
-
- /*Difference of time between a two accese to entropy pool.*/
- delta = event - pool->last_counter;
-
- randpool_push(pool, &event, sizeof(ticks_t));
- randpool_push(pool, sep, sizeof(sep) - 1); // ??
- randpool_push(pool, &delta, sizeof(delta));
-
- /*
- * Count of number entropy bit add with delta.
- */
- delta = delta & 0xff;
- while(delta)
- {
- delta >>= 1;
- entropy++;
- }
-
- pool->last_counter = event;
-
-#endif
-
- pool->entropy += entropy; //Update a entropy of the pool.
-}
-
-/**
- * Randpool function initialization.
- * The entropy pool can be initialize also with
- * a previous entropy pool.
- */
-void randpool_init(EntropyPool *pool, void *_data, size_t len)
-{
- uint8_t *data;
-
- data = (uint8_t *)_data;
-
- memset(pool, 0, sizeof(EntropyPool));
- pool->pos_get = MD2_DIGEST_LEN;
-
-#if CONFIG_RANDPOOL_TIMER
- pool->last_counter = timer_clock();
-#endif
-
- if(data)
- {
- /*
- * Initialize a entropy pool with a
- * previous pool, and assume all pool as
- * entropy.
- */
- len = MIN(len,(size_t)CONFIG_SIZE_ENTROPY_POOL);
- memcpy(pool->pool_entropy, data, len);
- pool->entropy = len;
- }
-
-}
-
-/**
- * Get the actual value of entropy.
- */
-size_t randpool_size(EntropyPool *pool)
-{
- return pool->entropy;
-}
-
-/**
- * Get \param n_byte from entropy pool. If n_byte is larger than number
- * byte of entropy in entropy pool, randpool_get continue
- * to generate pseudocasual value from previous state of
- * pool.
- * \param n_byte number fo bytes to read.
- * \param pool is the pool entropy context.
- * \param _data is the pointer to write the random data to.
- */
-void randpool_get(EntropyPool *pool, void *_data, size_t n_byte)
-{
- Md2Context context;
- size_t i = pool->pos_get;
- size_t n = n_byte;
- size_t pos_write = 0; //Number of block has been written in data.
- size_t len = MIN((size_t)MD2_DIGEST_LEN, n_byte);
- uint8_t *data;
-
- data = (uint8_t *)_data;
-
- /* Test if i + CONFIG_MD2_BLOCK_LEN is inside of entropy pool.*/
- ASSERT((MD2_DIGEST_LEN + i) < CONFIG_SIZE_ENTROPY_POOL);
-
- md2_init(&context);
-
- while(n > 0)
- {
-
- /*Hash previous state of pool*/
- md2_update(&context, &pool->pool_entropy[i], MD2_DIGEST_LEN);
-
- memcpy(&data[pos_write], md2_end(&context), len);
-
- pos_write += len; //Update number of block has been written in data.
- n -= len; //Number of byte copied in data.
-
- len = MIN(n,(size_t)MD2_DIGEST_LEN);
-
- i = (i + MD2_DIGEST_LEN) % CONFIG_SIZE_ENTROPY_POOL;
-
- /* If we haven't more entropy pool to hash, we stir it.*/
- if(i < MD2_DIGEST_LEN)
- {
- randpool_stir(pool);
- i = pool->pos_get;
- }
-
- }
-
- pool->pos_get = i; //Current number of byte we get from pool.
- pool->entropy -= n_byte; //Update a entropy.
-
- /*If we get all entropy entropy is 0*/
- if(pool->entropy < 0)
- pool->entropy = 0;
-
-}
-
-/**
- * Return a pointer to entropy pool.
- */
-uint8_t *randpool_pool(EntropyPool *pool)
-{
- return pool->pool_entropy;
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/);
- *
- * -->
- *
- * \brief API function for to manage entropy pool.
- *
- *
- * \version $Id$
- * \author Daniele Basile <asterix@develer.com>
- */
-
-#ifndef ALGO_RANDPOOL_H
-#define ALGO_RANDPOOL_H
-
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-
-/**
- * Sturct data of entropy pool.
- */
-typedef struct EntropyPool
-{
- size_t entropy; ///< Actual value of entropy (byte).
- size_t pos_add; ///< Number of byte idd in entropy pool.
- size_t pos_get; ///< Number of byte get in entropy pool.
- size_t counter; ///< Counter.
-
-#if CONFIG_RANDPOOL_TIMER
- size_t last_counter; ///< Last timer value.
-#endif
-
- uint8_t pool_entropy[CONFIG_SIZE_ENTROPY_POOL]; ///< Entropy pool.
-
-} EntropyPool;
-
-
-void randpool_add(EntropyPool *pool, void *data, size_t entropy);
-void randpool_init(EntropyPool *pool, void *_data, size_t len);
-size_t randpool_size(EntropyPool *pool);
-void randpool_get(EntropyPool *pool, void *data, size_t n_byte);
-uint8_t *randpool_pool(EntropyPool *pool);
-
-#endif /* ALGO_RANDPOOL_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Rotating Hash algorithm (interface).
- *
- * This is a simple yet powerfull checksum algorithm.
- * Instead of just xor-ing the data, rotating hash
- * circular shift the checksum 4 place left before xoring.
- * This is a bit more stronger than simply sum the data.
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-
-#ifndef ALGO_ROTATING_H
-#define ALGO_ROTATING_H
-
-#include <cfg/compiler.h>
-
-typedef uint16_t rotating_t;
-
-
-/**
- * Init rotating checksum.
- */
-INLINE void rotating_init(rotating_t *rot)
-{
- *rot = 0;
-}
-
-/**
- * Update checksum pointed by \c rot with \c c data.
- */
-INLINE void rotating_update1(uint8_t c, rotating_t *rot)
-{
- *rot = (*rot << 4) ^ (*rot >> 12) ^ c;
-}
-
-/**
- * Update checksum pointed by \c rot with data supplied in \c buf.
- */
-INLINE void rotating_update(const void *_buf, size_t len, rotating_t *rot)
-{
- const uint8_t *buf = (const uint8_t *)_buf;
-
- while (len--)
- rotating_update1(*buf++, rot);
-}
-
-
-#endif // ALGO_ROTATING_H
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief TEA Tiny Encription Algorith functions (implementation).
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- *
- * The Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham
- * of the Cambridge Computer Laboratory
- *
- * Placed in the Public Domain by David Wheeler and Roger Needham.
- *
- * **** ANSI C VERSION ****
- *
- * Notes:
- *
- * TEA is a Feistel cipher with XOR and and addition as the non-linear
- * mixing functions.
- *
- * Takes 64 bits of data in v[0] and v[1]. Returns 64 bits of data in w[0]
- * and w[1]. Takes 128 bits of key in k[0] - k[3].
- *
- * TEA can be operated in any of the modes of DES. Cipher Block Chaining is,
- * for example, simple to implement.
- *
- * n is the number of iterations. 32 is ample, 16 is sufficient, as few
- * as eight may be OK. The algorithm achieves good dispersion after six
- * iterations. The iteration count can be made variable if required.
- *
- * Note this is optimised for 32-bit CPUs with fast shift capabilities. It
- * can very easily be ported to assembly language on most CPUs.
- *
- * delta is chosen to be the real part of (the golden ratio Sqrt(5/4) -
- * 1/2 ~ 0.618034 multiplied by 2^32).
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2007/09/19 16:23:27 batt
- *#* Fix doxygen warnings.
- *#*
- *#* Revision 1.1 2007/06/07 09:13:40 batt
- *#* Add TEA enc/decryption algorithm.
- *#*
- *#* Revision 1.1 2007/01/10 17:30:10 batt
- *#* Add cryptographic routines.
- *#*
- *#*/
-
-#include "tea.h"
-#include <mware/byteorder.h>
-
-static uint32_t tea_func(uint32_t *in, uint32_t *sum, uint32_t *k)
-{
- return ((*in << 4) + cpu_to_le32(k[0])) ^ (*in + *sum) ^ ((*in >> 5) + cpu_to_le32(k[1]));
-}
-
-/**
- * \brief TEA encryption function.
- * This function encrypts <EM>v</EM> with <EM>k</EM> and returns the
- * encrypted data in <EM>v</EM>.
- * \param _v Array of two long values containing the data block.
- * \param _k Array of four long values containing the key.
- */
-void tea_enc(void *_v, void *_k)
-{
- uint32_t y, z;
- uint32_t sum = 0;
- uint8_t n = ROUNDS;
- uint32_t *v = (uint32_t *)_v;
- uint32_t *k = (uint32_t *)_k;
-
- y=cpu_to_le32(v[0]);
- z=cpu_to_le32(v[1]);
-
- while(n-- > 0)
- {
- sum += DELTA;
- y += tea_func(&z, &sum, &(k[0]));
- z += tea_func(&y, &sum, &(k[2]));
- }
-
- v[0] = le32_to_cpu(y);
- v[1] = le32_to_cpu(z);
-}
-
-/**
- * \brief TEA decryption function.
- * This function decrypts <EM>v</EM> with <EM>k</EM> and returns the
- * decrypted data in <EM>v</EM>.
- * \param _v Array of two long values containing the data block.
- * \param _k Array of four long values containing the key.
- */
-void tea_dec(void *_v, void *_k)
-{
- uint32_t y, z;
- uint32_t sum = DELTA * ROUNDS;
- uint8_t n = ROUNDS;
- uint32_t *v = (uint32_t *)_v;
- uint32_t *k = (uint32_t *)_k;
-
- y = cpu_to_le32(v[0]);
- z = cpu_to_le32(v[1]);
-
- while(n-- > 0)
- {
- z -= tea_func(&y, &sum, &(k[2]));
- y -= tea_func(&z, &sum, &(k[0]));
- sum -= DELTA;
- }
-
- v[0] = le32_to_cpu(y);
- v[1] = le32_to_cpu(z);
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief TEA Tiny Encription Algorith functions (interface).
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- *
- * Documentation for TEA is available at
- * http://www.cl.cam.ac.uk/ftp/users/djw3/tea.ps.
- */
-
-#ifndef ALGO_TEA_H
-#define ALGO_TEA_H
-
-#include <cfg/compiler.h>
-
-#define TEA_KEY_LEN 16 //!< TEA key size.
-#define TEA_BLOCK_LEN 8 //!< TEA block length.
-
-#define DELTA 0x9E3779B9 //!< Magic value. (Golden number * 2^31)
-#define ROUNDS 32 //!< Number of rounds.
-
-void tea_enc(void *_v, void *_k);
-void tea_dec(void *_v, void *_k);
-
-#endif /* ALGO_TEA_H */
-
# Author: Bernardo Innocenti <bernie@develer.com>
#
-include fonts/fonts.mk
-include emul/emul.mk
+include bertos/fonts/fonts.mk
+include bertos/emul/emul.mk
# Set to 1 for debug builds
demo_DEBUG = 1
CC = g++
demo_CXXSRC = \
- emul/emul.cpp \
- emul/emulwin.cpp \
- emul/emulkbd.cpp \
- drv/lcd_gfx_qt.cpp
+ bertos/emul/emul.cpp \
+ bertos/emul/emulwin.cpp \
+ bertos/emul/emulkbd.cpp \
+ bertos/drv/lcd_gfx_qt.cpp
demo_CSRC = \
app/demo/demo.c \
- os/hptime.c \
- gfx/bitmap.c \
- gfx/line.c \
- gfx/win.c \
- gfx/text.c \
- gfx/text_format.c \
- gui/menu.c \
- fonts/helvB10.c \
- fonts/luBS14.c \
- fonts/ncenB18.c \
- icons/logo.c \
- drv/kbd.c \
- drv/timer.c \
- drv/buzzer.c \
- drv/ser.c \
- drv/ser_posix.c \
- mware/formatwr.c \
- mware/hex.c \
- mware/event.c \
- mware/observer.c \
- mware/resource.c \
- mware/sprintf.c \
- kern/proc.c \
- kern/sem.c \
- kern/signal.c \
- kern/monitor.c \
- kern/proc_test.c \
- verstag.c
+ bertos/os/hptime.c \
+ bertos/gfx/bitmap.c \
+ bertos/gfx/line.c \
+ bertos/gfx/win.c \
+ bertos/gfx/text.c \
+ bertos/gfx/text_format.c \
+ bertos/gui/menu.c \
+ bertos/fonts/helvB10.c \
+ bertos/fonts/luBS14.c \
+ bertos/fonts/ncenB18.c \
+ bertos/icons/logo.c \
+ bertos/drv/kbd.c \
+ bertos/drv/timer.c \
+ bertos/drv/buzzer.c \
+ bertos/drv/ser.c \
+ bertos/drv/ser_posix.c \
+ bertos/mware/formatwr.c \
+ bertos/mware/hex.c \
+ bertos/mware/event.c \
+ bertos/mware/observer.c \
+ bertos/mware/resource.c \
+ bertos/mware/sprintf.c \
+ bertos/kern/proc.c \
+ bertos/kern/sem.c \
+ bertos/kern/signal.c \
+ bertos/kern/monitor.c \
+ bertos/kern/proc_test.c \
+ bertos/verstag.c
demo_CPPASRC = \
- kern/switch.S
+ bertos/kern/switch.S
# FIXME: maybe this junk should go in emul/emul.mk?
-$(OBJDIR)/demo/emul/emulwin.o: emul/emulwin_moc.cpp
-$(OBJDIR)/demo/drv/lcd_gfx_qt.o: drv/lcd_gfx_qt_moc.cpp
-$(OBJDIR)/demo/drv/timer.o: drv/timer_qt_moc.cpp
-$(OBJDIR)/demo/emul/emulkbd.o: emul/emulkbd_moc.cpp
+$(OBJDIR)/demo/bertos/emul/emulwin.o: bertos/emul/emulwin_moc.cpp
+$(OBJDIR)/demo/bertos/drv/lcd_gfx_qt.o: bertos/drv/lcd_gfx_qt_moc.cpp
+$(OBJDIR)/demo/bertos/drv/timer.o: bertos/drv/timer_qt_moc.cpp
+$(OBJDIR)/demo/bertos/emul/emulkbd.o: bertos/emul/emulkbd_moc.cpp
#FIXME: isn't there a way to avoid repeating the pattern rule?
-drv/timer_qt_moc.cpp: drv/timer_qt.c
+bertos/drv/timer_qt_moc.cpp: bertos/drv/timer_qt.c
$(QT_MOC) -o $@ $<
-demo_CFLAGS = -D_QT=4 -D'ARCH=ARCH_EMUL' -Iapp/demo -Ihw $(EMUL_CFLAGS)
-demo_CXXFLAGS = -D_QT=4 -D'ARCH=ARCH_EMUL' -Iapp/demo -Ihw $(EMUL_CFLAGS)
+demo_CFLAGS = -D_QT=4 -D'ARCH=ARCH_EMUL' -Iapp/demo $(EMUL_CFLAGS)
+demo_CXXFLAGS = -D_QT=4 -D'ARCH=ARCH_EMUL' -Iapp/demo $(EMUL_CFLAGS)
demo_LDFLAGS = $(EMUL_LDFLAGS)
# Debug stuff
ifeq ($(demo_DEBUG),1)
demo_CFLAGS += -D_DEBUG
demo_CXXFLAGS += -D_DEBUG
- demo_CSRC += drv/kdebug.c
+ demo_CSRC += bertos/drv/kdebug.c
else
demo_CFLAGS += -Os
demo_CXXFLAGS += -Os
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief DevLib configuration options
- *
- * You should copy this header in your project and rename it to
- * "config.h" and delete the CONFIG_ macros for the modules
- * you're not using.
- *
- * <h2>Working with multiple applications</h2>
- *
- * If your project is made of multiple DevLib-based applications,
- * create a custom "config.h" file in each application subdirectory
- * and play with the compiler include path to get the desired result.
- * You can share common options by creationg a "config_common.h" header
- * and including it from all your "config.h" copies.
- *
- * <h2>Configuration style</h2>
- *
- * For improved compile-time checking of configuration options,
- * the preferred way to use a \c CONFIG_ symbol is keeping it
- * always defined with a value of either 0 or 1. This lets
- * you write tests like this:
- *
- * \code
- * #if CONFIG_FOO
- * void foo(void)
- * {
- * if (CONFIG_BAR)
- * bar();
- * }
- * #endif // CONFIG_FOO
- * \endcode
- *
- * In most cases, we rely on the optimizer to discard checks
- * on constant values and performing dead-code elimination.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#ifndef APPCONFIG_COMMON_H
-#define APPCONFIG_COMMON_H
-
-/** kdebug console */
-#define CONFIG_KDEBUG_PORT 0
-
-/** Baud-rate for the kdebug console */
-#define CONFIG_KDEBUG_BAUDRATE 19200
-
-/**
- * printf()-style formatter configuration.
- *
- * \sa PRINTF_DISABLED
- * \sa PRINTF_NOMODIFIERS
- * \sa PRINTF_REDUCED
- * \sa PRINTF_NOFLOAT
- * \sa PRINTF_FULL
- */
-#define CONFIG_PRINTF PRINTF_FULL
-
-/**
- * Multithreading kernel.
- *
- * \sa config_kern.h
- */
-#define CONFIG_KERNEL 0
-
-/**
- * \name Serial driver parameters
- * \{
- */
- /** [bytes] Size of the outbound FIFO buffer for port 0. */
- #define CONFIG_UART0_TXBUFSIZE 32
-
- /** [bytes] Size of the inbound FIFO buffer for port 0. */
- #define CONFIG_UART0_RXBUFSIZE 64
-
- /** [bytes] Size of the outbound FIFO buffer for port 1. */
- #define CONFIG_UART1_TXBUFSIZE 32
-
- /** [bytes] Size of the inbound FIFO buffer for port 1. */
- #define CONFIG_UART1_RXBUFSIZE CONFIG_PROTOCOL_BUFLEN
-
- /** [bytes] Size of the outbound FIFO buffer for SPI port 0. */
- #define CONFIG_SPI0_TXBUFSIZE 16
-
- /** [bytes] Size of the inbound FIFO buffer for SPI port 0. */
- #define CONFIG_SPI0_RXBUFSIZE 32
-
- /** [bytes] Size of the outbound FIFO buffer for SPI port 1. */
- #define CONFIG_SPI1_TXBUFSIZE 16
-
- /** [bytes] Size of the inbound FIFO buffer for SPI port 1. */
- #define CONFIG_SPI1_RXBUFSIZE 32
-
- /** SPI data order (AVR only). */
- #define CONFIG_SPI_DATA_ORDER SER_MSB_FIRST
-
- /** SPI clock division factor (AVR only). */
- #define CONFIG_SPI_CLOCK_DIV 16
-
- /** SPI clock polarity: 0 = normal low, 1 = normal high (AVR only). */
- #define CONFIG_SPI_CLOCK_POL 0
-
- /** SPI clock phase: 0 = sample on first edge, 1 = sample on second clock edge (AVR only). */
- #define CONFIG_SPI_CLOCK_PHASE 0
-
- /** Default transmit timeout (ms). Set to -1 to disable timeout support */
- #define CONFIG_SER_TXTIMEOUT -1
-
- /** Default receive timeout (ms). Set to -1 to disable timeout support */
- #define CONFIG_SER_RXTIMEOUT -1
-
- /** Use RTS/CTS handshake */
- #define CONFIG_SER_HWHANDSHAKE 0
-
- /** Default baud rate (set to 0 to disable) */
- #define CONFIG_SER_DEFBAUDRATE 0
-
- /** Enable ser_gets() and ser_gets_echo() */
- #define CONFIG_SER_GETS 0
-
- /** Enable second serial port in emulator. */
- #define CONFIG_EMUL_UART1 0
-
- /**
- * Transmit always something on serial port 0 TX
- * to avoid interference when sending burst of data,
- * using AVR multiprocessor serial mode
- */
- #define CONFIG_SER_TXFILL 0
-
- #define CONFIG_SER_STROBE 0
-/*\}*/
-
-/// Hardware timer selection for drv/timer.c
-#define CONFIG_TIMER TIMER_ON_OUTPUT_COMPARE2
-
-/// Debug timer interrupt using a strobe pin.
-#define CONFIG_TIMER_STROBE 0
-
-/// Enable ADS strobe.
-#define CONFIG_ADC_STROBE 0
-
-/// Enable watchdog timer.
-#define CONFIG_WATCHDOG 0
-
-/// EEPROM type for drv/eeprom.c
-#define CONFIG_EEPROM_TYPE EEPROM_24XX256
-
-/// Select bitmap pixel format.
-#define CONFIG_BITMAP_FMT BITMAP_FMT_PLANAR_V_LSB
-
-/// Enable line clipping algorithm.
-#define CONFIG_GFX_CLIPPING 1
-
-/// Enable text rendering in bitmaps.
-#define CONFIG_GFX_TEXT 1
-
-/// Enable virtual coordinate system.
-#define CONFIG_GFX_VCOORDS 1
-
-/// Keyboard polling method
-#define CONFIG_KBD_POLL KBD_POLL_SOFTINT
-
-/// Enable keyboard event delivery to observers
-#define CONFIG_KBD_OBSERVER 0
-
-/// Enable key beeps
-#define CONFIG_KBD_BEEP 1
-
-/// Enable long pression handler for keys
-#define CONFIG_KBD_LONGPRESS 1
-
-/**
- * \name Type for the chart dataset
- * \{
- */
-#define CONFIG_CHART_TYPE_X uint8_t
-#define CONFIG_CHART_TYPE_Y uint8_t
-/*\}*/
-
-/// Enable button bar behind menus
-#define CONFIG_MENU_MENUBAR 0
-
-/// Enable smooth scrolling in menus
-#define CONFIG_MENU_SMOOTH 1
-
-/// Size of block for MD2 algorithm.
-#define CONFIG_MD2_BLOCK_LEN 16
-
-/// Use standard permutation in MD2 algorithm.
-#define CONFIG_MD2_STD_PERM 0
-
-/// Define a size, in byte, of entropy pool.
-#define CONFIG_SIZE_ENTROPY_POOL 64
-
-/// Turn on or off timer support in Randpool.
-#define CONFIG_RANDPOOL_TIMER 1
-
-/**
- * ADC timing setting parameter
- *
- * - CONFIG_ADC_CLOCK is frequency clock for ADC conversion.
- * - CONFIG_ADC_STARTUP_TIME minimum time for startup a conversion in micro second.
- * - CONFIG_ADC_SHTIME minimum time for sample and hold in nano second.
- * \{
- */
-#define CONFIG_ADC_CLOCK 4800000UL
-#define CONFIG_ADC_STARTUP_TIME 20
-#define CONFIG_ADC_SHTIME 834
-/* \} */
-
-#endif /* APPCONFIG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief CRC table and support routines
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "crc.h"
+
+/**
+ * crctab calculated by Mark G. Mendel, Network Systems Corporation
+ */
+const uint16_t crc16tab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+uint16_t crc16(uint16_t crc, const void *buffer, size_t len)
+{
+ const unsigned char *buf = (const unsigned char *)buffer;
+ while(len--)
+ crc = UPDCRC16(*buf++, crc);
+
+ return crc;
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief XModem-CRC16 algorithm (interface)
+ *
+ * \note This algorithm is incompatible with the CCITT-CRC16.
+ *
+ * This code is based on the article Copyright 1986 Stephen Satchell.
+ *
+ * Programmers may incorporate any or all code into their programs,
+ * giving proper credit within the source. Publication of the
+ * source routines is permitted so long as proper credit is given
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
+ * Omen Technology.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef ALGO_CRC_H
+#define ALGO_CRC_H
+
+#include <cfg/compiler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* CRC table */
+extern const uint16_t crc16tab[256];
+
+
+/**
+ * \brief Compute the updated CRC16 value for one octet (macro version)
+ *
+ * \note This version is only intended for old/broken compilers.
+ * Use the inline function in new code.
+ *
+ * \param c New octet (range 0-255)
+ * \param oldcrc Previous CRC16 value (referenced twice, beware of side effects)
+ */
+#define UPDCRC16(c, oldcrc) (crc16tab[((oldcrc) >> 8) ^ ((unsigned char)(c))] ^ ((oldcrc) << 8))
+
+
+#ifdef INLINE
+/**
+ * \brief Compute the updated CRC16 value for one octet (macro version)
+ */
+INLINE uint16_t updcrc16(uint8_t c, uint16_t oldcrc)
+{
+ return crc16tab[(oldcrc >> 8) ^ c] ^ (oldcrc << 8);
+}
+#endif // INLINE
+
+
+/**
+ * This function implements the CRC 16 calculation on a buffer.
+ *
+ * \param crc Current CRC16 value.
+ * \param buf The buffer to perform CRC calculation on.
+ * \param len The length of the Buffer.
+ *
+ * \return The updated CRC16 value.
+ */
+extern uint16_t crc16(uint16_t crc, const void *buf, size_t len);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ALGO_CRC_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief MD2 Message-Digest algorithm.
+ *
+ * The MD2 algorithm work with a constant array of 256 permutationt
+ * defined in RFC1319. If you don't want to use a standard array of
+ * permutatione you can use a md2_perm() function that generate an
+ * array of 256 "casual" permutation. To swich from a standard array
+ * to md2_perm function you must chanche CONFIG_MD2_STD_PERM defined in
+ * appconfig.h.
+ * If you need to store array in program memory you must define
+ * a macro _PROGMEM (for more info see mware/pgm.h).
+ *
+ *
+ * \version $Id$
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.17 2007/06/07 16:06:39 batt
+ *#* Fix some doxygen errors.
+ *#*
+ *#* Revision 1.16 2007/02/15 13:29:49 asterix
+ *#* Add MD2_DIGEST_LEN macro.
+ *#*
+ *#* Revision 1.15 2007/02/06 15:53:34 asterix
+ *#* Add ROTR macro in m2d_perm, add comments, typos.
+ *#*
+ *#* Revision 1.13 2007/02/05 18:44:42 asterix
+ *#* Add md2_perm function.
+ *#*
+ *#* Revision 1.12 2007/02/05 16:52:44 asterix
+ *#* Add define for harvard architecture.
+ *#*
+ *#* Revision 1.11 2007/02/02 18:15:31 asterix
+ *#* Add function MD2_test. Fix bug in md2_update function.
+ *#*
+ *#* Revision 1.9 2007/02/02 13:10:01 asterix
+ *#* Fix some bugs in md2_pad and md2_update fuction.
+ *#*
+ *#* Revision 1.8 2007/02/01 14:45:56 asterix
+ *#* Rewrite md2_update function and fix some bug.
+ *#*
+ *#* Revision 1.7 2007/01/31 18:04:15 asterix
+ *#* Write md2_end function
+ *#*
+ *#* Revision 1.4 2007/01/31 13:51:57 asterix
+ *#* Write md2_compute function.
+ *#*
+ *#* Revision 1.2 2007/01/30 17:31:44 asterix
+ *#* Add function prototypes.
+ *#*
+ *#* Revision 1.1 2007/01/30 15:53:26 batt
+ *#* Add first md2 skel.
+ *#*
+ *#*/
+
+#include "md2.h"
+
+#include <string.h> //memset(), memcpy();
+#include <cfg/compiler.h>
+#include <cfg/debug.h> //ASSERT()
+#include <cfg/macros.h> //MIN(), countof(), ROTR();
+#include <mware/pgm.h>
+
+
+#if CONFIG_MD2_STD_PERM
+ /*
+ * Official array of 256 byte pemutation contructed from digits of pi, defined
+ * in the RFC 1319.
+ */
+ static const uint8_t PGM_ATTR md2_perm[256] =
+ {
+ 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+ 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+ 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+ 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+ 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+ 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+ 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+ 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+ 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+ 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+ 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+ 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+ 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+ 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+ 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+ 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+ 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+ 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+ };
+
+ #define MD2_PERM(x) PGM_READ_CHAR(&md2_perm[x])
+#else
+ /**
+ * Md2_perm() function generate an array of 256 "casual" permutation.
+ */
+
+ /**
+ * Costant define for computing an array of 256 "casual" permutation.
+ * \{
+ */
+ #define K1 5
+ #define K2 3
+ #define R 2
+ #define X 172
+ /*\}*/
+
+ static uint8_t md2_perm(uint8_t i)
+ {
+
+ i = i * K1;
+ i = ROTR(i, R);
+ i ^= X;
+ i = i * K2;
+
+ return i;
+ }
+
+ #define MD2_PERM(x) md2_perm(x)
+
+#endif
+
+
+/**
+ * Pad function. Put len_pad unsigned char in
+ * input block.
+ */
+static void md2_pad(void *_block, size_t len_pad)
+{
+ uint8_t *block;
+
+ block = (uint8_t *)_block;
+
+ ASSERT(len_pad <= CONFIG_MD2_BLOCK_LEN);
+
+ /*
+ * Fill input block with len_pad char.
+ */
+ memset(block, len_pad, len_pad);
+
+}
+
+static void md2_compute(void *_state, void *_checksum, void *_block)
+{
+ int i = 0;
+ uint16_t t = 0;
+ uint8_t compute_array[COMPUTE_ARRAY_LEN];
+ uint8_t *state;
+ uint8_t *checksum;
+ uint8_t *block;
+
+ state = (uint8_t *)_state;
+ checksum = (uint8_t *)_checksum;
+ block = (uint8_t *)_block;
+
+ /*
+ * Copy state and checksum context in compute array.
+ */
+ memcpy(compute_array, state, CONFIG_MD2_BLOCK_LEN);
+ memcpy(compute_array + CONFIG_MD2_BLOCK_LEN, block, CONFIG_MD2_BLOCK_LEN);
+
+ /*
+ * Fill compute array with state XOR block
+ */
+ for(i = 0; i < CONFIG_MD2_BLOCK_LEN; i++)
+ compute_array[i + (CONFIG_MD2_BLOCK_LEN * 2)] = state[i] ^ block[i];
+
+ /*
+ * Encryt block.
+ */
+ for(i = 0; i < NUM_COMPUTE_ROUNDS; i++)
+ {
+ for(int j = 0; j < COMPUTE_ARRAY_LEN; j++)
+ {
+ compute_array[j] ^= MD2_PERM(t);
+ t = compute_array[j];
+ }
+
+ t = (t + i) & 0xff; //modulo 256.
+ }
+ /*
+ * Update checksum.
+ */
+ t = checksum[CONFIG_MD2_BLOCK_LEN - 1];
+
+ for(i = 0; i < CONFIG_MD2_BLOCK_LEN; i++)
+ {
+ checksum[i] ^= MD2_PERM(block[i] ^ t);
+ t = checksum[i];
+ }
+
+ /*
+ * Update state and clean compute array.
+ */
+ memcpy(state, compute_array, CONFIG_MD2_BLOCK_LEN);
+ memset(compute_array, 0, sizeof(compute_array));
+}
+
+/**
+ * Algorithm initialization.
+ *
+ * \param context empty context.
+ */
+void md2_init(Md2Context *context)
+{
+
+ memset(context, 0, sizeof(Md2Context));
+
+}
+
+/**
+ * Update block.
+ */
+void md2_update(Md2Context *context, const void *_block_in, size_t block_len)
+{
+
+ const uint8_t *block_in;
+ size_t cpy_len;
+
+
+ block_in = (const uint8_t *)_block_in;
+
+ while(block_len > 0)
+ {
+ /*
+ * Choose a number of block that fill input context buffer.
+ */
+ cpy_len = MIN(block_len, CONFIG_MD2_BLOCK_LEN - context->counter);
+
+
+ /*
+ * Copy in the buffer input block.
+ */
+ memcpy(&context->buffer[context->counter], block_in, cpy_len);
+
+ /*
+ * Update a context counter, input block length and remaning
+ * context buffer block lenght.
+ */
+ context->counter += cpy_len;
+ block_len -= cpy_len;
+ block_in += cpy_len;
+
+ /*
+ * If buffer is full, compute it.
+ */
+ if (context->counter >= CONFIG_MD2_BLOCK_LEN)
+ {
+ md2_compute(context->state, context->checksum, context->buffer);
+ context->counter = 0;
+ }
+ }
+
+
+}
+/**
+ * Ends an MD2 message digest operation.
+ * This fuction take an context and return a pointer
+ * to context state.
+ *
+ * \param context in input.
+ * \return a pointer to context state (message digest).
+ */
+uint8_t *md2_end(Md2Context *context)
+{
+
+ uint8_t buf[CONFIG_MD2_BLOCK_LEN];
+
+ /*
+ * Fill remaning empty context buffer.
+ */
+ md2_pad(buf, CONFIG_MD2_BLOCK_LEN - context->counter);
+
+ /*
+ * Update context buffer and compute it.
+ */
+ md2_update(context, buf, CONFIG_MD2_BLOCK_LEN - context->counter);
+
+ /*
+ * Add context checksum to message input.
+ */
+ md2_update(context, context->checksum, CONFIG_MD2_BLOCK_LEN);
+
+
+ return context->state; //return a pointer to message digest.
+}
+/**
+ * MD2 test fuction.
+ * This function test MD2 algorithm with a standard string specified
+ * in RFC 1319.
+ *
+ * \note This test work with official array of 256 byte pemutation
+ * contructed from digits of pi, defined in the RFC 1319.
+ *
+ */
+bool md2_test(void)
+{
+
+ Md2Context context;
+
+ const char *test[] =
+ {
+ "",
+ "message digest",
+ "abcdefghijklmnopqrstuvwxyz",
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+ };
+
+
+ const uint8_t *result[] = {
+ "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73",
+ "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0",
+ "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47\x94\x0b",
+ "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3\xef\xd8",
+ };
+
+
+ for (int i = 0; i < countof(test); i++)
+ {
+ md2_init(&context);
+ md2_update(&context, test[i], strlen(test[i]));
+
+ if(memcmp(result[i], md2_end(&context), MD2_DIGEST_LEN))
+ return false;
+ }
+
+ return true;
+}
+
+#if 0
+
+#include <stdio.h>
+int main(int argc, char * argv[])
+{
+
+ if(md2_test())
+ printf("MD2 algorithm work well!\n");
+ else
+ printf("MD2 algorithm doesn't work well.\n");
+
+}
+
+#endif
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief MD2 Message-Digest algorithm.
+ *
+ * The algorithm takes as input a message of arbitrary length and produces
+ * as output a 128-bit message digest of the input.
+ * It is conjectured that it is computationally infeasible to produce
+ * two messages having the same message digest, or to produce any
+ * message having a given prespecified target message digest.
+ *
+ *
+ *
+ * \version $Id$
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+#ifndef ALGO_MD2_H
+#define ALGO_MD2_H
+
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+#define NUM_COMPUTE_ROUNDS 18 ///< Number of compute rounds.
+#define COMPUTE_ARRAY_LEN CONFIG_MD2_BLOCK_LEN * 3 ///< Lenght of compute array.
+#define MD2_DIGEST_LEN CONFIG_MD2_BLOCK_LEN
+/**
+ * Context for MD2 computation.
+ */
+typedef struct Md2Context
+{
+ uint8_t buffer[CONFIG_MD2_BLOCK_LEN]; ///< Input buffer.
+ uint8_t state[CONFIG_MD2_BLOCK_LEN]; ///< Current state buffer.
+ uint8_t checksum[CONFIG_MD2_BLOCK_LEN]; ///< Checksum.
+ size_t counter; ///< Counter of remaining bytes.
+
+} Md2Context;
+
+void md2_init(Md2Context *context);
+void md2_update(Md2Context *context, const void *block_in, size_t block_len);
+uint8_t *md2_end(Md2Context *context);
+bool md2_test(void);
+
+#endif /* ALGO_MD2_H */
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Compute, save and load ramps for stepper motors (implementation)
+ *
+ * \version $Id$
+ *
+ * \author Simone Zinanni <s.zinanni@develer.com>
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ *
+ *
+ * The formula used by the ramp is the following:
+ *
+ * <pre>
+ * a * b
+ * f(t) = -------------
+ * lerp(a,b,t)
+ * </pre>
+ *
+ * Where <code>a</code> and <code>b</code> are the maximum and minimum speed
+ * respectively (minimum and maximum wavelength respectively), and <code>lerp</code>
+ * is a linear interpolation with a factor:
+ *
+ * <pre>
+ * lerp(a,b,t) = a + t * (b - a) = (a * (1 - t)) + (b * t)
+ * </pre>
+ *
+ * <code>t</code> must be in the [0,1] interval. It is easy to see that the
+ * following holds true:
+ *
+ * <pre>
+ * f(0) = b, f(1) = a
+ * </pre>
+ *
+ * And that the function is monotonic. So, the function effectively interpolates
+ * between the maximum and minimum speed through its domain ([0,1] -> [b,a]).
+ *
+ * The curve drawn by this function is similar to 1 / (sqrt(n)), so it is slower
+ * than a linear acceleration (which would be 1/n).
+ *
+ * The floating point version uses a slightly modified function which accepts
+ * the parameter in the domain [0, MT] (where MT is maxTime, the length of the
+ * ramp, which is a setup parameter for the ramp). This is done to reduce the
+ * number of operations per step. The formula looks like this:
+ *
+ * <pre>
+ * a * b * MT
+ * g(t) = ----------------------------
+ * (a * MT) + t * (b - a)
+ * </pre>
+ *
+ * It can be shown that this <code>g(t) = f(t * MT)</code>. The denominator
+ * is a linear interpolation in the range [b*MT, a*MT], as t moves in the
+ * interval [0, MT]. So the interpolation interval of the function is again
+ * [b, a]. The implementation caches the value of the numerator and parts
+ * of the denominator, so that the formula becomes:
+ *
+ * <pre>
+ * alpha = a * b * MT
+ * beta = a * MT
+ * gamma = b - a
+ *
+ * alpha
+ * g(t) = ----------------------
+ * beta + t * gamma
+ * </pre>
+ *
+ * and <code>t</code> is exactly the parameter that ramp_evaluate() gets,
+ * that is the current time (in range [0, MT]). The operations performed
+ * for each step are just an addition, a multiplication and a division.
+ *
+ * The fixed point version of the formula instead transforms the original
+ * function as follows:
+ *
+ * <pre>
+ * a * b a
+ * f(t) = ------------------------- = --------------------
+ * a a
+ * b * ( - * (1 - t) + t ) - * (1 - t) + t
+ * b b
+ * </pre>
+ *
+ * <code>t</code> must be computed by dividing the current time (24 bit integer)
+ * by the maximum time (24 bit integer). This is done by precomputing the
+ * reciprocal of the maximum time as a 0.32 fixed point number, and multiplying
+ * it to the current time. Multiplication is performed 8-bits a time by
+ * FIX_MULT32(), so that we end up with a 0.16 fixed point number for
+ * <code>t</code> (and <code>1-t</code> is just its twos-complement negation).
+ * <code>a/b</code> is in the range [0,1] (because a is always less than b,
+ * being the minimum wavelength), so it is precomputed as a 0.16 fixed point.
+ * The final step is then computing the denominator and executing the division
+ * (32 cycles using the 1-step division instruction in the DSP).
+ *
+ * The assembly implementation is needed for efficiency, but a C version of it
+ * can be easily written, in case it is needed in the future.
+ *
+ */
+
+#include "ramp.h"
+#include <cfg/debug.h>
+
+#include <string.h> // memcpy()
+
+/**
+ * Multiply \p a and \p b two integer at 32 bit and extract the high 16 bit word.
+ */
+#define FIX_MULT32(a,b) (((uint64_t)(a)*(uint32_t)(b)) >> 16)
+
+void ramp_compute(struct Ramp *ramp, uint32_t clocksRamp, uint16_t clocksMinWL, uint16_t clocksMaxWL)
+{
+ ASSERT(clocksMaxWL >= clocksMinWL);
+
+ // Save values in ramp struct
+ ramp->clocksRamp = clocksRamp;
+ ramp->clocksMinWL = clocksMinWL;
+ ramp->clocksMaxWL = clocksMaxWL;
+
+#if RAMP_USE_FLOATING_POINT
+ ramp->precalc.gamma = ramp->clocksMaxWL - ramp->clocksMinWL;
+ ramp->precalc.beta = (float)ramp->clocksMinWL * (float)ramp->clocksRamp;
+ ramp->precalc.alpha = ramp->precalc.beta * (float)ramp->clocksMaxWL;
+
+#else
+ ramp->precalc.max_div_min = ((uint32_t)clocksMinWL << 16) / (uint32_t)clocksMaxWL;
+
+ /* Calcola 1/total_time in fixed point .32. Assumiamo che la rampa possa al
+ * massimo avere 25 bit (cioé valore in tick fino a 2^25, che con il
+ * prescaler=3 sono circa 7 secondi). Inoltre, togliamo qualche bit di precisione
+ * da destra (secondo quanto specificato in RAMP_CLOCK_SHIFT_PRECISION).
+ */
+ ASSERT(ramp->clocksRamp < (1UL << (24 + RAMP_CLOCK_SHIFT_PRECISION)));
+ ramp->precalc.inv_total_time = 0xFFFFFFFFUL / (ramp->clocksRamp >> RAMP_CLOCK_SHIFT_PRECISION);
+ ASSERT(ramp->precalc.inv_total_time < 0x1000000UL);
+
+#endif
+}
+
+
+void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq)
+{
+ uint32_t minWL, maxWL;
+
+ minWL = TIME2CLOCKS(FREQ2MICROS(maxFreq));
+ maxWL = TIME2CLOCKS(FREQ2MICROS(minFreq));
+
+ ASSERT2(minWL < 65536UL, "Maximum frequency too high");
+ ASSERT2(maxWL < 65536UL, "Minimum frequency too high");
+ ASSERT(maxFreq > minFreq);
+
+ ramp_compute(
+ ramp,
+ TIME2CLOCKS(length),
+ TIME2CLOCKS(FREQ2MICROS(maxFreq)),
+ TIME2CLOCKS(FREQ2MICROS(minFreq))
+ );
+}
+
+void ramp_default(struct Ramp *ramp)
+{
+ ramp_setup(ramp, RAMP_DEF_TIME, RAMP_DEF_MINFREQ, RAMP_DEF_MAXFREQ);
+}
+
+#if RAMP_USE_FLOATING_POINT
+
+float ramp_evaluate(const struct Ramp* ramp, float curClock)
+{
+ return ramp->precalc.alpha / (curClock * ramp->precalc.gamma + ramp->precalc.beta);
+}
+
+#else
+
+INLINE uint32_t fix_mult32(uint32_t m1, uint32_t m2)
+{
+ uint32_t accum = 0;
+ accum += m1 * ((m2 >> 0) & 0xFF);
+ accum >>= 8;
+ accum += m1 * ((m2 >> 8) & 0xFF);
+ accum >>= 8;
+ accum += m1 * ((m2 >> 16) & 0xFF);
+ return accum;
+}
+
+// a*b >> 16
+INLINE uint16_t fix_mult16(uint16_t a, uint32_t b)
+{
+ return (b*(uint32_t)a) >> 16;
+}
+
+uint16_t FAST_FUNC ramp_evaluate(const struct Ramp* ramp, uint32_t curClock)
+{
+ uint16_t t = FIX_MULT32(curClock >> RAMP_CLOCK_SHIFT_PRECISION, ramp->precalc.inv_total_time);
+ uint16_t denom = fix_mult16((uint16_t)~t + 1, ramp->precalc.max_div_min) + t;
+ uint16_t cur_delta = ((uint32_t)ramp->clocksMinWL << 16) / denom;
+
+ return cur_delta;
+}
+
+#endif
+
+
--- /dev/null
+
+/**
+ * \file
+ * <!--
+ * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Compute, save and load ramps for stepper motors (interace)
+ *
+ * \version $Id$
+ *
+ * \author Simone Zinanni <s.zinanni@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ *
+ * The acceleration ramp is used to properly accelerate a stepper motor. The main
+ * entry point is the function ramp_evaluate(), which must be called at every step
+ * of the motor: it gets as input the time elapsed since the stepper started
+ * accelerating, and returns the time to wait before sending the next step. A pseudo
+ * usage pattern is as follows:
+ *
+ * <pre>
+ * float time = 0;
+ * while (1)
+ * {
+ * float delta = ramp_evaluate(&my_ramp, time);
+ * sleep(delta);
+ * do_motor_step();
+ * time += delta;
+ * }
+ * </pre>
+ *
+ * A similar pattern can be used to decelerate (it is sufficient to move the total
+ * time backward, such as "time -= delta").
+ *
+ * The ramp can be configured with ramp_setup(), providing it with the minimum and
+ * maximum operating frequency of the motor, and the total acceleration time in
+ * milliseconds (that is, the time that will be needed to accelerate from the
+ * minimum frequency to the maximum frequency).
+ *
+ * Both a very precise floating point and a very fast fixed point implementation
+ * of the ramp evaluation are provided. The fixed point is hand-optimized assembly
+ * for DSP56000 (but a portable C version of it can be easily written, see the
+ * comments in the code).
+ *
+ */
+
+#ifndef ALGO_RAMP_H
+#define ALGO_RAMP_H
+
+#include <cfg/compiler.h>
+#include "hw_stepper.h"
+
+/**
+ * Define whether the ramp will use floating point calculation within ramp_evaluate().
+ * Otherwise, a less precise fixed point version will be used, which is faster on
+ * platforms which do no support floating point operations.
+ *
+ * \note Floating point operations will be always done within ramp_compute() to
+ * precalculate values, so there has to be at least a floating point emulation support.
+ */
+#define RAMP_USE_FLOATING_POINT 0
+
+
+#if !RAMP_USE_FLOATING_POINT
+
+ /**
+ * Number of least-significant bits which are stripped away during ramp evaluation.
+ * This setting allows to specify larger ramps at the price of less precision.
+ *
+ * The maximum ramp size allowed is 2^(24 + RAMP_CLOCK_SHIFT_PRECISION), in clocks.
+ * For instance, using RAMP_CLOCK_SHIFT_PRECISION 1, and a 8x prescaler, the maximum
+ * length of a ramp is about 6.7 secs. Raising RAMP_CLOCK_SHIFT_PRECISION to 2
+ * brings the maximum length to 13.4 secs, at the price of less precision.
+ *
+ * ramp_compute() will check that the length is below the maximum allowed through
+ * a runtime assertion.
+ *
+ * \note This macro is used only for the fixed-point version of the ramp.
+ */
+ #define RAMP_CLOCK_SHIFT_PRECISION 2
+#endif
+
+
+///< Negative pulse width for ramp
+#define RAMP_PULSE_WIDTH 50
+
+///< Default ramp
+#define RAMP_DEF_TIME 6000000 ///< microsecs
+#define RAMP_DEF_MAXFREQ 5000 ///< Hz
+#define RAMP_DEF_MINFREQ 200 ///< Hz
+#define RAMP_DEF_POWERRUN 10 ///< 10 deciampere (1 ampere)
+#define RAMP_DEF_POWERIDLE 1 ///< 1 deciampere
+
+
+/**
+ * Convert microseconds to timer clock ticks
+ */
+#define TIME2CLOCKS(micros) ((uint32_t)(micros) * (STEPPER_CLOCK / 1000000))
+
+/**
+ * Convert timer clock ticks back to microseconds
+ */
+#define CLOCKS2TIME(clocks) ((uint32_t)(clocks) / (STEPPER_CLOCK / 1000000))
+
+/**
+ * Convert microseconds to Hz
+ */
+#define MICROS2FREQ(micros) (1000000UL / ((uint32_t)(micros)))
+
+/**
+ * Convert frequency (in Hz) to time (in microseconds)
+ */
+#define FREQ2MICROS(hz) (1000000UL / ((uint32_t)(hz)))
+
+
+
+/**
+ * Structure holding pre-calculated data for speeding up real-time evaluation
+ * of the ramp. This structure is totally different between the fixed and the
+ * floating point version of the code.
+ *
+ * Consult the file-level documentation of ramp.c for more information about
+ * the values of this structure.
+ */
+struct RampPrecalc
+{
+#if RAMP_USE_FLOATING_POINT
+ float beta;
+ float alpha;
+ float gamma;
+#else
+ uint16_t max_div_min;
+ uint32_t inv_total_time;
+#endif
+};
+
+
+/**
+ * Ramp structure
+ */
+struct Ramp
+{
+ uint32_t clocksRamp;
+ uint16_t clocksMinWL;
+ uint16_t clocksMaxWL;
+
+ struct RampPrecalc precalc; ///< pre-calculated values for speed
+};
+
+
+/*
+ * Function prototypes
+ */
+void ramp_compute(
+ struct Ramp * ramp,
+ uint32_t clocksInRamp,
+ uint16_t clocksInMinWavelength,
+ uint16_t clocksInMaxWavelength);
+
+
+/** Setup an acceleration ramp for a stepper motor
+ *
+ * \param ramp Ramp to fill
+ * \param length Length of the ramp (milliseconds)
+ * \param minFreq Minimum operating frequency of the motor (hertz)
+ * \param maxFreq Maximum operating frequency of the motor (hertz)
+ *
+ */
+void ramp_setup(struct Ramp* ramp, uint32_t length, uint32_t minFreq, uint32_t maxFreq);
+
+
+/**
+ * Initialize a new ramp with default values
+ */
+void ramp_default(struct Ramp *ramp);
+
+
+/**
+ * Evaluate the ramp at the given point. Given a \a ramp, and the current \a clock since
+ * the start of the acceleration, compute the next step, that is the interval at which
+ * send the signal to the motor.
+ *
+ * \note The fixed point version does not work when curClock is zero. Anyway,
+ * the first step is always clocksMaxWL, as stored within the ramp structure.
+ */
+#if RAMP_USE_FLOATING_POINT
+ float ramp_evaluate(const struct Ramp* ramp, float curClock);
+#else
+ uint16_t ramp_evaluate(const struct Ramp* ramp, uint32_t curClock);
+#endif
+
+
+/** Self test */
+void ramp_test(void);
+
+#endif /* ALGO_RAMP_H */
+
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Test for compute, save and load ramps for stepper motors (implementation)
+ *
+ * \version $Id$
+ *
+ * \author Simone Zinanni <s.zinanni@develer.com>
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ *
+ *
+ * The formula used by the ramp is the following:
+ *
+ * <pre>
+ * a * b
+ * f(t) = -------------
+ * lerp(a,b,t)
+ * </pre>
+ *
+ * Where <code>a</code> and <code>b</code> are the maximum and minimum speed
+ * respectively (minimum and maximum wavelength respectively), and <code>lerp</code>
+ * is a linear interpolation with a factor:
+ *
+ * <pre>
+ * lerp(a,b,t) = a + t * (b - a) = (a * (1 - t)) + (b * t)
+ * </pre>
+ *
+ * <code>t</code> must be in the [0,1] interval. It is easy to see that the
+ * following holds true:
+ *
+ * <pre>
+ * f(0) = b, f(1) = a
+ * </pre>
+ *
+ * And that the function is monotonic. So, the function effectively interpolates
+ * between the maximum and minimum speed through its domain ([0,1] -> [b,a]).
+ *
+ * The curve drawn by this function is similar to 1 / (sqrt(n)), so it is slower
+ * than a linear acceleration (which would be 1/n).
+ *
+ * The floating point version uses a slightly modified function which accepts
+ * the parameter in the domain [0, MT] (where MT is maxTime, the length of the
+ * ramp, which is a setup parameter for the ramp). This is done to reduce the
+ * number of operations per step. The formula looks like this:
+ *
+ * <pre>
+ * a * b * MT
+ * g(t) = ----------------------------
+ * (a * MT) + t * (b - a)
+ * </pre>
+ *
+ * It can be shown that this <code>g(t) = f(t * MT)</code>. The denominator
+ * is a linear interpolation in the range [b*MT, a*MT], as t moves in the
+ * interval [0, MT]. So the interpolation interval of the function is again
+ * [b, a]. The implementation caches the value of the numerator and parts
+ * of the denominator, so that the formula becomes:
+ *
+ * <pre>
+ * alpha = a * b * MT
+ * beta = a * MT
+ * gamma = b - a
+ *
+ * alpha
+ * g(t) = ----------------------
+ * beta + t * gamma
+ * </pre>
+ *
+ * and <code>t</code> is exactly the parameter that ramp_evaluate() gets,
+ * that is the current time (in range [0, MT]). The operations performed
+ * for each step are just an addition, a multiplication and a division.
+ *
+ * The fixed point version of the formula instead transforms the original
+ * function as follows:
+ *
+ * <pre>
+ * a * b a
+ * f(t) = ------------------------- = --------------------
+ * a a
+ * b * ( - * (1 - t) + t ) - * (1 - t) + t
+ * b b
+ * </pre>
+ *
+ * <code>t</code> must be computed by dividing the current time (24 bit integer)
+ * by the maximum time (24 bit integer). This is done by precomputing the
+ * reciprocal of the maximum time as a 0.32 fixed point number, and multiplying
+ * it to the current time. Multiplication is performed 8-bits a time by
+ * FIX_MULT32(), so that we end up with a 0.16 fixed point number for
+ * <code>t</code> (and <code>1-t</code> is just its twos-complement negation).
+ * <code>a/b</code> is in the range [0,1] (because a is always less than b,
+ * being the minimum wavelength), so it is precomputed as a 0.16 fixed point.
+ * The final step is then computing the denominator and executing the division
+ * (32 cycles using the 1-step division instruction in the DSP).
+ *
+ * The assembly implementation is needed for efficiency, but a C version of it
+ * can be easily written, in case it is needed in the future.
+ *
+ */
+
+#include "ramp.h"
+#include <cfg/debug.h>
+
+static bool ramp_test_single(uint32_t minFreq, uint32_t maxFreq, uint32_t length)
+{
+ struct Ramp r;
+ uint16_t cur, old;
+ uint32_t clock;
+ uint32_t oldclock;
+
+ ramp_setup(&r, length, minFreq, maxFreq);
+
+ cur = old = r.clocksMaxWL;
+ clock = 0;
+ oldclock = 0;
+
+ kprintf("testing ramp: (length=%lu, min=%lu, max=%lu)\n", length, minFreq, maxFreq);
+ kprintf(" [length=%lu, max=%04x, min=%04x]\n", r.clocksRamp, r.clocksMaxWL, r.clocksMinWL);
+
+ int i = 0;
+ int nonbyte = 0;
+
+ while (clock + cur < r.clocksRamp)
+ {
+ oldclock = clock;
+ old = cur;
+
+ clock += cur;
+ cur = ramp_evaluate(&r, clock);
+
+ if (old < cur)
+ {
+ uint16_t t1 = FIX_MULT32(oldclock >> RAMP_CLOCK_SHIFT_PRECISION, r.precalc.inv_total_time);
+ uint16_t t2 = FIX_MULT32(clock >> RAMP_CLOCK_SHIFT_PRECISION, r.precalc.inv_total_time);
+ uint16_t denom1 = FIX_MULT32((uint16_t)((~t1) + 1), r.precalc.max_div_min) + t1;
+ uint16_t denom2 = FIX_MULT32((uint16_t)((~t2) + 1), r.precalc.max_div_min) + t2;
+
+ kprintf(" Failed: %04x @ %lu --> %04x @ %lu\n", old, oldclock, cur, clock);
+ kprintf(" T: %04x -> %04x\n", t1, t2);
+ kprintf(" DENOM: %04x -> %04x\n", denom1, denom2);
+
+ cur = ramp_evaluate(&r, clock);
+ return false;
+ }
+ i++;
+ if ((old-cur) >= 256)
+ nonbyte++;
+ }
+
+
+
+ kprintf("Test finished: %04x @ %lu [min=%04x, totlen=%lu, numsteps:%d, nonbyte:%d]\n", cur, clock, r.clocksMinWL, r.clocksRamp, i, nonbyte);
+
+ return true;
+}
+
+
+void ramp_test(void)
+{
+ bool ok = true;
+
+ ok = ramp_test_single(200, 5000, 3000000) && ok;
+ ok = ramp_test_single(1000, 2000, 1000000) && ok;
+
+ if (ok)
+ kputs("Ramp test succeeded!\n");
+ else
+ kputs("Ramp test fail!\n");
+}
+
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief API function for to manage entropy pool.
+ *
+ * \version $Id$
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.20 2007/06/07 16:06:39 batt
+ *#* Fix some doxygen errors.
+ *#*
+ *#* Revision 1.19 2007/02/15 13:54:26 asterix
+ *#* Rename randpool_getN in randpool_get. Fix bug in randpool_get.
+ *#*
+ *#* Revision 1.17 2007/02/15 13:40:42 asterix
+ *#* Fix bug in randpool_add and randpool_strir.
+ *#*
+ *#* Revision 1.16 2007/02/13 15:11:37 asterix
+ *#* Typo.
+ *#*
+ *#* Revision 1.14 2007/02/13 09:57:12 asterix
+ *#* Add directive #if in struct EntropyPool, and remove #else in randpool_add.
+ *#*
+ *#* Revision 1.13 2007/02/12 18:25:34 asterix
+ *#* Fix bug in randpool_getN.
+ *#*
+ *#* Revision 1.12 2007/02/12 09:47:39 asterix
+ *#* Remove randpool_save. Add randpool_pool.
+ *#*
+ *#* Revision 1.10 2007/02/12 09:03:32 asterix
+ *#* Add CONFIG_RANDPOOL_TIMER macro to swich on or off timer support
+ *#*
+ *#* Revision 1.9 2007/02/09 17:58:09 asterix
+ *#* Add macro CONFIG_RANDPOOL_TIMER.
+ *#*
+ *#* Revision 1.6 2007/02/09 09:24:38 asterix
+ *#* Typos. Add data_len in randpool_add and n_byte in randpool_push pototypes.
+ *#*
+ *#* Revision 1.3 2007/02/08 14:25:29 asterix
+ *#* Write static funcion push_byte.
+ *#*
+ *#*/
+
+#include "randpool.h"
+#include "md2.h"
+
+#include <stdio.h> //sprintf();
+#include <string.h> //memset(), memcpy();
+
+#include <cfg/compiler.h>
+#include <cfg/debug.h> //ASSERT()
+#include <cfg/macros.h> //MIN(), ROUND_UP();
+
+#if CONFIG_RANDPOOL_TIMER
+ #include <drv/timer.h> //timer_clock();
+#endif
+
+
+
+/*
+ * Insert bytes in entropy pool, making a XOR of bytes present
+ * in entropy pool.
+ */
+static void randpool_push(EntropyPool *pool, void *_byte, size_t n_byte)
+{
+ size_t i = pool->pos_add; // Current number of byte insert in entropy pool.
+ uint8_t *byte;
+
+ byte = (uint8_t *)_byte;
+
+ /*
+ * Insert a bytes in entropy pool.
+ */
+ for(int j = 0; j < n_byte; j++)
+ {
+ pool->pool_entropy[i] = pool->pool_entropy[i] ^ byte[j];
+ i = (++i) % CONFIG_SIZE_ENTROPY_POOL;
+ }
+
+ pool->pos_add = i; // Update a insert bytes.
+}
+
+
+/*
+ * This function stir entropy pool with MD2 function hash.
+ *
+ */
+static void randpool_stir(EntropyPool *pool)
+{
+ size_t entropy = pool->entropy; //Save current calue of entropy.
+ Md2Context context;
+ uint8_t tmp_buf[((sizeof(size_t) * 2) + sizeof(int)) * 2 + 1]; //Temporary buffer.
+
+ md2_init(&context); //Init MD2 algorithm.
+
+ randpool_add(pool, NULL, 0);
+
+ for (int i = 0; i < (CONFIG_SIZE_ENTROPY_POOL / MD2_DIGEST_LEN); i++)
+ {
+ sprintf(tmp_buf, "%0x%0x%0x",pool->counter, i, pool->pos_add);
+
+ /*
+ * Hash with MD2 algorithm the entropy pool.
+ */
+ md2_update(&context, pool->pool_entropy, CONFIG_SIZE_ENTROPY_POOL);
+
+ md2_update(&context, tmp_buf, sizeof(tmp_buf) - 1);
+
+ /*Insert a message digest in entropy pool.*/
+ randpool_push(pool, md2_end(&context), MD2_DIGEST_LEN);
+
+ pool->counter = pool->counter + 1;
+
+ }
+
+ /*Insert in pool the difference between a two call of this function (see above).*/
+ randpool_add(pool, NULL, 0);
+
+ pool->entropy = entropy; //Restore old value of entropy. We haven't add entropy.
+}
+
+/**
+ * Add \param entropy bits from \param data buffer to the entropy \param pool
+ */
+void randpool_add(EntropyPool *pool, void *data, size_t entropy)
+{
+ uint8_t sep[] = "\xaa\xaa\xaa\xaa"; // ??
+ size_t data_len = ROUND_UP(entropy, 8) / 8; //Number of entropy byte in input.
+
+ randpool_push(pool, data, data_len); //Insert data to entropy pool.
+
+#if CONFIG_RANDPOOL_TIMER
+
+ ticks_t event = timer_clock();
+ ticks_t delta;
+
+ /*Difference of time between a two accese to entropy pool.*/
+ delta = event - pool->last_counter;
+
+ randpool_push(pool, &event, sizeof(ticks_t));
+ randpool_push(pool, sep, sizeof(sep) - 1); // ??
+ randpool_push(pool, &delta, sizeof(delta));
+
+ /*
+ * Count of number entropy bit add with delta.
+ */
+ delta = delta & 0xff;
+ while(delta)
+ {
+ delta >>= 1;
+ entropy++;
+ }
+
+ pool->last_counter = event;
+
+#endif
+
+ pool->entropy += entropy; //Update a entropy of the pool.
+}
+
+/**
+ * Randpool function initialization.
+ * The entropy pool can be initialize also with
+ * a previous entropy pool.
+ */
+void randpool_init(EntropyPool *pool, void *_data, size_t len)
+{
+ uint8_t *data;
+
+ data = (uint8_t *)_data;
+
+ memset(pool, 0, sizeof(EntropyPool));
+ pool->pos_get = MD2_DIGEST_LEN;
+
+#if CONFIG_RANDPOOL_TIMER
+ pool->last_counter = timer_clock();
+#endif
+
+ if(data)
+ {
+ /*
+ * Initialize a entropy pool with a
+ * previous pool, and assume all pool as
+ * entropy.
+ */
+ len = MIN(len,(size_t)CONFIG_SIZE_ENTROPY_POOL);
+ memcpy(pool->pool_entropy, data, len);
+ pool->entropy = len;
+ }
+
+}
+
+/**
+ * Get the actual value of entropy.
+ */
+size_t randpool_size(EntropyPool *pool)
+{
+ return pool->entropy;
+}
+
+/**
+ * Get \param n_byte from entropy pool. If n_byte is larger than number
+ * byte of entropy in entropy pool, randpool_get continue
+ * to generate pseudocasual value from previous state of
+ * pool.
+ * \param n_byte number fo bytes to read.
+ * \param pool is the pool entropy context.
+ * \param _data is the pointer to write the random data to.
+ */
+void randpool_get(EntropyPool *pool, void *_data, size_t n_byte)
+{
+ Md2Context context;
+ size_t i = pool->pos_get;
+ size_t n = n_byte;
+ size_t pos_write = 0; //Number of block has been written in data.
+ size_t len = MIN((size_t)MD2_DIGEST_LEN, n_byte);
+ uint8_t *data;
+
+ data = (uint8_t *)_data;
+
+ /* Test if i + CONFIG_MD2_BLOCK_LEN is inside of entropy pool.*/
+ ASSERT((MD2_DIGEST_LEN + i) < CONFIG_SIZE_ENTROPY_POOL);
+
+ md2_init(&context);
+
+ while(n > 0)
+ {
+
+ /*Hash previous state of pool*/
+ md2_update(&context, &pool->pool_entropy[i], MD2_DIGEST_LEN);
+
+ memcpy(&data[pos_write], md2_end(&context), len);
+
+ pos_write += len; //Update number of block has been written in data.
+ n -= len; //Number of byte copied in data.
+
+ len = MIN(n,(size_t)MD2_DIGEST_LEN);
+
+ i = (i + MD2_DIGEST_LEN) % CONFIG_SIZE_ENTROPY_POOL;
+
+ /* If we haven't more entropy pool to hash, we stir it.*/
+ if(i < MD2_DIGEST_LEN)
+ {
+ randpool_stir(pool);
+ i = pool->pos_get;
+ }
+
+ }
+
+ pool->pos_get = i; //Current number of byte we get from pool.
+ pool->entropy -= n_byte; //Update a entropy.
+
+ /*If we get all entropy entropy is 0*/
+ if(pool->entropy < 0)
+ pool->entropy = 0;
+
+}
+
+/**
+ * Return a pointer to entropy pool.
+ */
+uint8_t *randpool_pool(EntropyPool *pool)
+{
+ return pool->pool_entropy;
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/);
+ *
+ * -->
+ *
+ * \brief API function for to manage entropy pool.
+ *
+ *
+ * \version $Id$
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+#ifndef ALGO_RANDPOOL_H
+#define ALGO_RANDPOOL_H
+
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+
+/**
+ * Sturct data of entropy pool.
+ */
+typedef struct EntropyPool
+{
+ size_t entropy; ///< Actual value of entropy (byte).
+ size_t pos_add; ///< Number of byte idd in entropy pool.
+ size_t pos_get; ///< Number of byte get in entropy pool.
+ size_t counter; ///< Counter.
+
+#if CONFIG_RANDPOOL_TIMER
+ size_t last_counter; ///< Last timer value.
+#endif
+
+ uint8_t pool_entropy[CONFIG_SIZE_ENTROPY_POOL]; ///< Entropy pool.
+
+} EntropyPool;
+
+
+void randpool_add(EntropyPool *pool, void *data, size_t entropy);
+void randpool_init(EntropyPool *pool, void *_data, size_t len);
+size_t randpool_size(EntropyPool *pool);
+void randpool_get(EntropyPool *pool, void *data, size_t n_byte);
+uint8_t *randpool_pool(EntropyPool *pool);
+
+#endif /* ALGO_RANDPOOL_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Rotating Hash algorithm (interface).
+ *
+ * This is a simple yet powerfull checksum algorithm.
+ * Instead of just xor-ing the data, rotating hash
+ * circular shift the checksum 4 place left before xoring.
+ * This is a bit more stronger than simply sum the data.
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+
+#ifndef ALGO_ROTATING_H
+#define ALGO_ROTATING_H
+
+#include <cfg/compiler.h>
+
+typedef uint16_t rotating_t;
+
+
+/**
+ * Init rotating checksum.
+ */
+INLINE void rotating_init(rotating_t *rot)
+{
+ *rot = 0;
+}
+
+/**
+ * Update checksum pointed by \c rot with \c c data.
+ */
+INLINE void rotating_update1(uint8_t c, rotating_t *rot)
+{
+ *rot = (*rot << 4) ^ (*rot >> 12) ^ c;
+}
+
+/**
+ * Update checksum pointed by \c rot with data supplied in \c buf.
+ */
+INLINE void rotating_update(const void *_buf, size_t len, rotating_t *rot)
+{
+ const uint8_t *buf = (const uint8_t *)_buf;
+
+ while (len--)
+ rotating_update1(*buf++, rot);
+}
+
+
+#endif // ALGO_ROTATING_H
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief TEA Tiny Encription Algorith functions (implementation).
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * The Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham
+ * of the Cambridge Computer Laboratory
+ *
+ * Placed in the Public Domain by David Wheeler and Roger Needham.
+ *
+ * **** ANSI C VERSION ****
+ *
+ * Notes:
+ *
+ * TEA is a Feistel cipher with XOR and and addition as the non-linear
+ * mixing functions.
+ *
+ * Takes 64 bits of data in v[0] and v[1]. Returns 64 bits of data in w[0]
+ * and w[1]. Takes 128 bits of key in k[0] - k[3].
+ *
+ * TEA can be operated in any of the modes of DES. Cipher Block Chaining is,
+ * for example, simple to implement.
+ *
+ * n is the number of iterations. 32 is ample, 16 is sufficient, as few
+ * as eight may be OK. The algorithm achieves good dispersion after six
+ * iterations. The iteration count can be made variable if required.
+ *
+ * Note this is optimised for 32-bit CPUs with fast shift capabilities. It
+ * can very easily be ported to assembly language on most CPUs.
+ *
+ * delta is chosen to be the real part of (the golden ratio Sqrt(5/4) -
+ * 1/2 ~ 0.618034 multiplied by 2^32).
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2007/09/19 16:23:27 batt
+ *#* Fix doxygen warnings.
+ *#*
+ *#* Revision 1.1 2007/06/07 09:13:40 batt
+ *#* Add TEA enc/decryption algorithm.
+ *#*
+ *#* Revision 1.1 2007/01/10 17:30:10 batt
+ *#* Add cryptographic routines.
+ *#*
+ *#*/
+
+#include "tea.h"
+#include <mware/byteorder.h>
+
+static uint32_t tea_func(uint32_t *in, uint32_t *sum, uint32_t *k)
+{
+ return ((*in << 4) + cpu_to_le32(k[0])) ^ (*in + *sum) ^ ((*in >> 5) + cpu_to_le32(k[1]));
+}
+
+/**
+ * \brief TEA encryption function.
+ * This function encrypts <EM>v</EM> with <EM>k</EM> and returns the
+ * encrypted data in <EM>v</EM>.
+ * \param _v Array of two long values containing the data block.
+ * \param _k Array of four long values containing the key.
+ */
+void tea_enc(void *_v, void *_k)
+{
+ uint32_t y, z;
+ uint32_t sum = 0;
+ uint8_t n = ROUNDS;
+ uint32_t *v = (uint32_t *)_v;
+ uint32_t *k = (uint32_t *)_k;
+
+ y=cpu_to_le32(v[0]);
+ z=cpu_to_le32(v[1]);
+
+ while(n-- > 0)
+ {
+ sum += DELTA;
+ y += tea_func(&z, &sum, &(k[0]));
+ z += tea_func(&y, &sum, &(k[2]));
+ }
+
+ v[0] = le32_to_cpu(y);
+ v[1] = le32_to_cpu(z);
+}
+
+/**
+ * \brief TEA decryption function.
+ * This function decrypts <EM>v</EM> with <EM>k</EM> and returns the
+ * decrypted data in <EM>v</EM>.
+ * \param _v Array of two long values containing the data block.
+ * \param _k Array of four long values containing the key.
+ */
+void tea_dec(void *_v, void *_k)
+{
+ uint32_t y, z;
+ uint32_t sum = DELTA * ROUNDS;
+ uint8_t n = ROUNDS;
+ uint32_t *v = (uint32_t *)_v;
+ uint32_t *k = (uint32_t *)_k;
+
+ y = cpu_to_le32(v[0]);
+ z = cpu_to_le32(v[1]);
+
+ while(n-- > 0)
+ {
+ z -= tea_func(&y, &sum, &(k[2]));
+ y -= tea_func(&z, &sum, &(k[0]));
+ sum -= DELTA;
+ }
+
+ v[0] = le32_to_cpu(y);
+ v[1] = le32_to_cpu(z);
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief TEA Tiny Encription Algorith functions (interface).
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * Documentation for TEA is available at
+ * http://www.cl.cam.ac.uk/ftp/users/djw3/tea.ps.
+ */
+
+#ifndef ALGO_TEA_H
+#define ALGO_TEA_H
+
+#include <cfg/compiler.h>
+
+#define TEA_KEY_LEN 16 //!< TEA key size.
+#define TEA_BLOCK_LEN 8 //!< TEA block length.
+
+#define DELTA 0x9E3779B9 //!< Magic value. (Golden number * 2^31)
+#define ROUNDS 32 //!< Number of rounds.
+
+void tea_enc(void *_v, void *_k);
+void tea_dec(void *_v, void *_k);
+
+#endif /* ALGO_TEA_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief DevLib configuration options
+ *
+ * You should copy this header in your project and rename it to
+ * "config.h" and delete the CONFIG_ macros for the modules
+ * you're not using.
+ *
+ * <h2>Working with multiple applications</h2>
+ *
+ * If your project is made of multiple DevLib-based applications,
+ * create a custom "config.h" file in each application subdirectory
+ * and play with the compiler include path to get the desired result.
+ * You can share common options by creationg a "config_common.h" header
+ * and including it from all your "config.h" copies.
+ *
+ * <h2>Configuration style</h2>
+ *
+ * For improved compile-time checking of configuration options,
+ * the preferred way to use a \c CONFIG_ symbol is keeping it
+ * always defined with a value of either 0 or 1. This lets
+ * you write tests like this:
+ *
+ * \code
+ * #if CONFIG_FOO
+ * void foo(void)
+ * {
+ * if (CONFIG_BAR)
+ * bar();
+ * }
+ * #endif // CONFIG_FOO
+ * \endcode
+ *
+ * In most cases, we rely on the optimizer to discard checks
+ * on constant values and performing dead-code elimination.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#ifndef APPCONFIG_COMMON_H
+#define APPCONFIG_COMMON_H
+
+/** kdebug console */
+#define CONFIG_KDEBUG_PORT 0
+
+/** Baud-rate for the kdebug console */
+#define CONFIG_KDEBUG_BAUDRATE 19200
+
+/**
+ * printf()-style formatter configuration.
+ *
+ * \sa PRINTF_DISABLED
+ * \sa PRINTF_NOMODIFIERS
+ * \sa PRINTF_REDUCED
+ * \sa PRINTF_NOFLOAT
+ * \sa PRINTF_FULL
+ */
+#define CONFIG_PRINTF PRINTF_FULL
+
+/**
+ * Multithreading kernel.
+ *
+ * \sa config_kern.h
+ */
+#define CONFIG_KERNEL 0
+
+/**
+ * \name Serial driver parameters
+ * \{
+ */
+ /** [bytes] Size of the outbound FIFO buffer for port 0. */
+ #define CONFIG_UART0_TXBUFSIZE 32
+
+ /** [bytes] Size of the inbound FIFO buffer for port 0. */
+ #define CONFIG_UART0_RXBUFSIZE 64
+
+ /** [bytes] Size of the outbound FIFO buffer for port 1. */
+ #define CONFIG_UART1_TXBUFSIZE 32
+
+ /** [bytes] Size of the inbound FIFO buffer for port 1. */
+ #define CONFIG_UART1_RXBUFSIZE CONFIG_PROTOCOL_BUFLEN
+
+ /** [bytes] Size of the outbound FIFO buffer for SPI port 0. */
+ #define CONFIG_SPI0_TXBUFSIZE 16
+
+ /** [bytes] Size of the inbound FIFO buffer for SPI port 0. */
+ #define CONFIG_SPI0_RXBUFSIZE 32
+
+ /** [bytes] Size of the outbound FIFO buffer for SPI port 1. */
+ #define CONFIG_SPI1_TXBUFSIZE 16
+
+ /** [bytes] Size of the inbound FIFO buffer for SPI port 1. */
+ #define CONFIG_SPI1_RXBUFSIZE 32
+
+ /** SPI data order (AVR only). */
+ #define CONFIG_SPI_DATA_ORDER SER_MSB_FIRST
+
+ /** SPI clock division factor (AVR only). */
+ #define CONFIG_SPI_CLOCK_DIV 16
+
+ /** SPI clock polarity: 0 = normal low, 1 = normal high (AVR only). */
+ #define CONFIG_SPI_CLOCK_POL 0
+
+ /** SPI clock phase: 0 = sample on first edge, 1 = sample on second clock edge (AVR only). */
+ #define CONFIG_SPI_CLOCK_PHASE 0
+
+ /** Default transmit timeout (ms). Set to -1 to disable timeout support */
+ #define CONFIG_SER_TXTIMEOUT -1
+
+ /** Default receive timeout (ms). Set to -1 to disable timeout support */
+ #define CONFIG_SER_RXTIMEOUT -1
+
+ /** Use RTS/CTS handshake */
+ #define CONFIG_SER_HWHANDSHAKE 0
+
+ /** Default baud rate (set to 0 to disable) */
+ #define CONFIG_SER_DEFBAUDRATE 0
+
+ /** Enable ser_gets() and ser_gets_echo() */
+ #define CONFIG_SER_GETS 0
+
+ /** Enable second serial port in emulator. */
+ #define CONFIG_EMUL_UART1 0
+
+ /**
+ * Transmit always something on serial port 0 TX
+ * to avoid interference when sending burst of data,
+ * using AVR multiprocessor serial mode
+ */
+ #define CONFIG_SER_TXFILL 0
+
+ #define CONFIG_SER_STROBE 0
+/*\}*/
+
+/// Hardware timer selection for drv/timer.c
+#define CONFIG_TIMER TIMER_ON_OUTPUT_COMPARE2
+
+/// Debug timer interrupt using a strobe pin.
+#define CONFIG_TIMER_STROBE 0
+
+/// Enable ADS strobe.
+#define CONFIG_ADC_STROBE 0
+
+/// Enable watchdog timer.
+#define CONFIG_WATCHDOG 0
+
+/// EEPROM type for drv/eeprom.c
+#define CONFIG_EEPROM_TYPE EEPROM_24XX256
+
+/// Select bitmap pixel format.
+#define CONFIG_BITMAP_FMT BITMAP_FMT_PLANAR_V_LSB
+
+/// Enable line clipping algorithm.
+#define CONFIG_GFX_CLIPPING 1
+
+/// Enable text rendering in bitmaps.
+#define CONFIG_GFX_TEXT 1
+
+/// Enable virtual coordinate system.
+#define CONFIG_GFX_VCOORDS 1
+
+/// Keyboard polling method
+#define CONFIG_KBD_POLL KBD_POLL_SOFTINT
+
+/// Enable keyboard event delivery to observers
+#define CONFIG_KBD_OBSERVER 0
+
+/// Enable key beeps
+#define CONFIG_KBD_BEEP 1
+
+/// Enable long pression handler for keys
+#define CONFIG_KBD_LONGPRESS 1
+
+/**
+ * \name Type for the chart dataset
+ * \{
+ */
+#define CONFIG_CHART_TYPE_X uint8_t
+#define CONFIG_CHART_TYPE_Y uint8_t
+/*\}*/
+
+/// Enable button bar behind menus
+#define CONFIG_MENU_MENUBAR 0
+
+/// Enable smooth scrolling in menus
+#define CONFIG_MENU_SMOOTH 1
+
+/// Size of block for MD2 algorithm.
+#define CONFIG_MD2_BLOCK_LEN 16
+
+/// Use standard permutation in MD2 algorithm.
+#define CONFIG_MD2_STD_PERM 0
+
+/// Define a size, in byte, of entropy pool.
+#define CONFIG_SIZE_ENTROPY_POOL 64
+
+/// Turn on or off timer support in Randpool.
+#define CONFIG_RANDPOOL_TIMER 1
+
+/**
+ * ADC timing setting parameter
+ *
+ * - CONFIG_ADC_CLOCK is frequency clock for ADC conversion.
+ * - CONFIG_ADC_STARTUP_TIME minimum time for startup a conversion in micro second.
+ * - CONFIG_ADC_SHTIME minimum time for sample and hold in nano second.
+ * \{
+ */
+#define CONFIG_ADC_CLOCK 4800000UL
+#define CONFIG_ADC_STARTUP_TIME 20
+#define CONFIG_ADC_SHTIME 834
+/* \} */
+
+#endif /* APPCONFIG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001,2002,2003 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Set system configuration
+ */
+
+
+#ifndef ARCH_CONFIG_H
+#define ARCH_CONFIG_H
+
+/**
+ * \name Architectures
+ * \{
+ */
+#define ARCH_FOO (1<<0)
+#define ARCH_BAR (1<<1)
+#define ARCH_EMUL (1<<8)
+/*\}*/
+
+#endif /* ARCH_CONFIG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001, 2002, 2003 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \brief Additional support macros for compiler independance
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef BERTOS_COMPILER_H
+#define BERTOS_COMPILER_H
+
+#include <cpu/detect.h>
+
+
+#if defined __GNUC__ && defined __GNUC_MINOR__
+ #define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+ #define GNUC_PREREQ(maj, min) 0
+#endif
+
+/* Some CW versions do not allow enabling C99 from the settings panel. */
+#if defined(__MWERKS__)
+ #pragma c99 on
+#endif
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+ #define COMPILER_C99 1
+#else
+ #define COMPILER_C99 0
+#endif
+
+
+/** Concatenate two different preprocessor tokens (allowing macros to expand) */
+#define PP_CAT(x,y) PP_CAT__(x,y)
+#define PP_CAT__(x,y) x ## y
+#define PP_CAT3(x,y,z) PP_CAT(PP_CAT(x,y),z)
+#define PP_CAT4(x,y,z,w) PP_CAT(PP_CAT3(x,y,z),w)
+#define PP_CAT5(x,y,z,w,j) PP_CAT(PP_CAT4(x,y,z,w),j)
+
+/** String-ize a token (allowing macros to expand) */
+#define PP_STRINGIZE(x) PP_STRINGIZE__(x)
+#define PP_STRINGIZE__(x) #x
+
+
+#if defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)
+
+ #pragma language=extended
+
+ #if CPU_ARM
+
+ #define COMPILER_VARIADIC_MACROS 1
+
+ #define INTERRUPT(x) __irq __arm void x (void)
+ #define INLINE static inline
+
+ /* Include some standard C89/C99 stuff */
+ #include <stddef.h>
+ #include <stdint.h>
+ #include <stdbool.h>
+
+ #elif CPU_I196
+
+ // IAR has size_t as built-in type, but does not define this symbol.
+ #define _SIZE_T_DEFINED
+
+ #define INTERRUPT(x) interrupt [x]
+ #define REGISTER shortad
+ #define INLINE /* unsupported */
+
+ /*
+ * Imported from <longjmp.h>. Unfortunately, we can't just include
+ * this header because it typedefs jmp_buf to be an array of chars.
+ * This would allow the compiler to place the buffer on an odd address.
+ * The CPU _should_ be able to perform word accesses to
+ * unaligned data, but there are *BUGS* in the 80196KC with
+ * some combinations of opcodes and addressing modes. One of
+ * these, "ST SP,[?GR]+" is used in the longjmp() implementation
+ * provided by the IAR compiler ANSI C library. When ?GR contains
+ * an odd address, surprisingly the CPU will copy the high order
+ * byte of the source operand (SP) in the low order byte of the
+ * destination operand (the memory location pointed to by ?GR).
+ *
+ * We also need to replace the library setjmp()/longjmp() with
+ * our own versions because the IAR implementation "forgets" to
+ * save the contents of local registers (?LR).
+ */
+ struct _JMP_BUF
+ {
+ void *sp; /* Stack pointer */
+ void *return_addr; /* Return address */
+ int lr[6]; /* 6 local registers */
+ };
+
+ typedef struct _JMP_BUF jmp_buf[1];
+
+ int setjmp(jmp_buf env);
+ void longjmp(jmp_buf env, int val);
+
+ /* Fake bool support */
+ #define true (1==1)
+ #define false (1!=1)
+ typedef unsigned char bool;
+
+ #else
+ #error Unsupported CPU
+ #endif
+
+#elif defined(_MSC_VER) /* Win32 emulation support */
+
+ /* MSVC doesn't provide <stdbool.h>. */
+ #ifndef __cplusplus
+ #define true (1==1)
+ #define false (1!=1)
+ typedef int bool;
+ #endif /* !__cplusplus */
+
+ /* These C99 functions are oddly named in MSVCRT32.lib */
+ #define snprintf _snprintf
+ #define vsnprintf _vsnprintf
+
+ /* MSVC doesn't support C99's __func__, but has a similar extension. */
+ #define __func__ __FUNCTION__
+
+ /* MSVC doesn't support C99's inline keyword */
+ #ifndef __cplusplus
+ #define INLINE __inline
+ #endif
+
+#elif defined(__GNUC__)
+
+ /* Compiler features */
+ #define COMPILER_VARIADIC_MACROS 1 /* Even in C++ */
+ #define COMPILER_TYPEOF 1
+ #define COMPILER_STATEMENT_EXPRESSIONS 1
+
+ /* GCC attributes */
+ #define FORMAT(type,fmt,first) __attribute__((__format__(type, fmt, first)))
+ #define NORETURN __attribute__((__noreturn__))
+ #define UNUSED_ARG(type,arg) __attribute__((__unused__)) type arg
+ #define UNUSED_VAR(type,name) __attribute__((__unused__)) type name
+ #define USED_VAR(type,name) __attribute__((__used__)) type name
+ #define INLINE static inline __attribute__((__always_inline__))
+ #define LIKELY(x) __builtin_expect(!!(x), 1)
+ #define UNLIKELY(x) __builtin_expect(!!(x), 0)
+ #define PURE_FUNC __attribute__((pure))
+ #define CONST_FUNC __attribute__((const))
+ #define UNUSED_FUNC __attribute__((unused))
+ #define USED_FUNC __attribute__((__used__))
+ #define RESTRICT __restrict__
+ #define MUST_CHECK __attribute__((warn_unused_result))
+ #define PACKED __attribute__((packed))
+ /**
+ * Force compiler to realod context variable.
+ */
+ #define MEMORY_BARRIER asm volatile ("" : : : "memory")
+
+ #if GNUC_PREREQ(3,1)
+ #define DEPRECATED __attribute__((__deprecated__))
+ #endif
+
+ #ifndef __cplusplus
+ #define ASSERT_TYPE_EQUAL(var1, var2) \
+ STATIC_ASSERT(__builtin_types_compatible_p(typeof(var1), typeof(var2)))
+ #define ASSERT_TYPE_IS(var, type) \
+ STATIC_ASSERT(__builtin_types_compatible_p(typeof(var), type))
+ #endif
+
+ /* Include some standard C89/C99 stuff */
+ #include <stddef.h>
+ #include <stdint.h>
+ #include <stdbool.h>
+ #if !CPU_AVR
+ #include <sys/types.h> /* for ssize_t */
+ #endif
+
+ #ifndef __cplusplus
+ /*
+ * Disallow some C++ keywords as identifiers in C programs,
+ * for improved portability.
+ */
+ #pragma GCC poison new delete class template typename
+ #pragma GCC poison private protected public operator
+ #pragma GCC poison friend mutable using namespace
+ #pragma GCC poison cin cout cerr clog
+ #endif
+
+
+
+#elif defined(__MWERKS__)
+
+ /* Compiler features */
+ #define COMPILER_VARIADIC_MACROS 1
+ #define COMPILER_TYPEOF 1
+ #define COMPILER_STATEMENT_EXPRESSIONS 1
+
+ #define typeof __typeof__
+
+ #define UNUSED_ARG(type,arg) type
+
+ #include <stddef.h>
+ #include <stdint.h>
+ #include <stdbool.h>
+
+ // CodeWarrior has size_t as built-in type, but does not define this symbol.
+ #define _SIZE_T_DEFINED
+
+#else
+ #error unknown compiler
+#endif
+
+
+/* Defaults for compiler extensions. */
+
+/**
+ * \def COMPILER_VARIADIC_MACROS
+ * Support for macros with variable arguments.
+ */
+#ifndef COMPILER_VARIADIC_MACROS
+#define COMPILER_VARIADIC_MACROS (COMPILER_C99 != 0)
+#endif
+
+/**
+ * \def COMPILER_TYPEOF
+ * Support for dynamic type identification.
+ */
+#ifndef COMPILER_TYPEOF
+#define COMPILER_TYPEOF 0
+#endif
+
+/**
+ * \def COMPILER_STATEMENT_EXPRESSIONS
+ * Support for statement expressions.
+ */
+#ifndef COMPILER_STATEMENT_EXPRESSIONS
+#define COMPILER_STATEMENT_EXPRESSIONS 0
+#endif
+
+/* A few defaults for missing compiler features. */
+#ifndef INLINE
+#define INLINE static inline
+#endif
+#ifndef NORETURN
+#define NORETURN /* nothing */
+#endif
+#ifndef FORMAT
+#define FORMAT(type,fmt,first) /* nothing */
+#endif
+#ifndef DEPRECATED
+#define DEPRECATED /* nothing */
+#endif
+#ifndef UNUSED_ARG
+#define UNUSED_ARG(type,arg) type arg
+#endif
+#define UNUSED UNUSED_ARG /* OBSOLETE */
+#ifndef UNUSED_VAR
+#define UNUSED_VAR(type,name) type name
+#endif
+#ifndef USED_VAR
+#define USED_VAR(type,name) type name
+#endif
+#ifndef REGISTER
+#define REGISTER /* nothing */
+#endif
+#ifndef LIKELY
+#define LIKELY(x) x
+#endif
+#ifndef UNLIKELY
+#define UNLIKELY(x) x
+#endif
+#ifndef PURE_FUNC
+#define PURE_FUNC /* nothing */
+#endif
+#ifndef CONST_FUNC
+#define CONST_FUNC /* nothing */
+#endif
+#ifndef UNUSED_FUNC
+#define UNUSED_FUNC /* nothing */
+#endif
+#ifndef USED_FUNC
+#define USED_FUNC /* nothing */
+#endif
+#ifndef RESTRICT
+#define RESTRICT /* nothing */
+#endif
+#ifndef MUST_CHECK
+#define MUST_CHECK /* nothing */
+#endif
+#ifndef PACKED
+#define PACKED /* nothing */
+#endif
+#ifndef MEMORY_BARRIER
+#define MEMORY_BARRIER /* nothing */
+#warning No memory barrier defined for select compiler. If you use the kernel check it.
+#endif
+
+
+/* Misc definitions */
+#ifndef NULL
+#define NULL (void *)0
+#endif
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+/* Support for hybrid C/C++ applications. */
+#ifdef __cplusplus
+ #define EXTERN_C extern "C"
+ #define EXTERN_C_BEGIN extern "C" {
+ #define EXTERN_C_END }
+ #define EXTERN_CONST extern const
+ #define CONST_CAST(TYPE,EXPR) (const_cast<TYPE>(EXPR))
+#else
+ #define EXTERN_C extern
+ #define EXTERN_C_BEGIN /* nothing */
+ #define EXTERN_C_END /* nothing */
+ #define EXTERN_CONST const
+ #define CONST_CAST(TYPE,EXPR) ((TYPE)(EXPR)) /* FIXME: How can we suppress the warning in C? */
+#endif
+
+
+#if defined(_MSC_VER) \
+ || ((defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)) && CPU_I196)
+ /**
+ * \name ISO C99 fixed-size types
+ *
+ * These should be in <stdint.h>, but a few compilers lack them.
+ * \{
+ */
+ typedef signed char int8_t;
+ typedef unsigned char uint8_t;
+ typedef short int int16_t;
+ typedef unsigned short int uint16_t;
+ typedef long int int32_t; /* _WIN64 safe */
+ typedef unsigned long int uint32_t; /* _WIN64 safe */
+
+ #ifdef _MSC_VER
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ #else
+ typedef long long int64_t;
+ typedef unsigned long long uint64_t;
+ #endif
+ /* \} */
+#else
+ /* This is the standard location. */
+ #include <stdint.h>
+#endif
+
+#if CPU_AVR_ATMEGA8
+ /*
+ * The ATmega8 has a very small Flash, so we can't afford
+ * to link in support routines for 32bit integer arithmetic.
+ */
+ typedef int16_t ticks_t; /**< Type for time expressed in ticks. */
+ typedef int16_t mtime_t; /**< Type for time expressed in milliseconds. */
+ typedef int16_t utime_t; /**< Type for time expressed in microseconds. */
+ #define SIZEOF_MTIME_T (16 / CPU_BITS_PER_CHAR)
+ #define SIZEOF_UTIME_T (16 / CPU_BITS_PER_CHAR)
+ #define MTIME_INFINITE 0x7FFFL
+#else
+ typedef int32_t ticks_t; /**< Type for time expressed in ticks. */
+
+ typedef int32_t utime_t; /**< Type for time expressed in microseconds. */
+ #define SIZEOF_UTIME_T (32 / CPU_BITS_PER_CHAR)
+
+ #ifndef DEVLIB_MTIME_DEFINED
+ #define DEVLIB_MTIME_DEFINED 1 /* Resolve conflict with <os/hptime.h> */
+ typedef int32_t mtime_t; /**< Type for time expressed in milliseconds. */
+ #define SIZEOF_MTIME_T (32 / CPU_BITS_PER_CHAR)
+ #define MTIME_INFINITE 0x7FFFFFFFL
+ #endif
+#endif
+
+/** Bulk storage large enough for both pointers or integers. */
+typedef void * iptr_t;
+
+/** Bulk storage large enough for both pointers to constants or integers. */
+typedef const void * const_iptr_t;
+
+typedef unsigned char sigbit_t; /**< Type for signal bits. */
+typedef unsigned char sigmask_t; /**< Type for signal masks. */
+typedef unsigned char page_t; /**< Type for banked memory pages. */
+
+
+/**
+ * \name Standard type definitions.
+ *
+ * These should be in <sys/types.h> or <stddef.h>, but many compilers
+ * and C libraries lack them.
+ *
+ * We check for some common definitions to avoid redefinitions:
+ *
+ * glibc, avr-libc: _SIZE_T_DEFINED, __ssize_t_defined
+ * Darwin libc: _BSD_SIZE_T_DEFINED_, _SIZE_T
+ * IAR ARM: _SIZE_T
+ *
+ * \{
+ */
+#if !(defined(size_t) || defined(_SIZE_T_DEFINED) || defined(_BSD_SIZE_T_DEFINED_) \
+ || defined(_SIZE_T))
+ #if CPU_X86
+ /* 32bit or 64bit (32bit for _WIN64). */
+ typedef unsigned long size_t;
+ #else
+ #error Unknown CPU
+ #endif
+#endif
+
+#if !(defined(ssize_t) || defined(_SSIZE_T) || defined(__ssize_t_defined))
+ #if CPU_X86
+ /* 32bit or 64bit (32bit for _WIN64). */
+ typedef long ssize_t;
+ #elif CPU_ARM
+ typedef int ssize_t;
+ #elif CPU_AVR
+ /* 16bit (missing in avr-libc's sys/types.h). */
+ typedef int ssize_t;
+ #else
+ #error Unknown CPU
+ #endif
+#endif
+/*\}*/
+
+
+/**
+ * \name Types for hardware registers.
+ *
+ * Only use these types for registers whose contents can
+ * be changed asynchronously by external hardware.
+ *
+ * \{
+ */
+#if CPU_DSP56K
+ /* Registers can be accessed only through 16-bit pointers */
+ typedef volatile uint16_t reg16_t;
+#else
+ typedef volatile uint8_t reg8_t;
+ typedef volatile uint16_t reg16_t;
+ typedef volatile uint32_t reg32_t;
+#endif
+/*\}*/
+
+
+/* Quasi-ANSI macros */
+#ifndef offsetof
+ /**
+ * Return the byte offset of the member \a m in struct \a s.
+ *
+ * \note This macro should be defined in "stddef.h" and is sometimes
+ * compiler-specific (g++ has a builtin for it).
+ */
+ #define offsetof(s,m) (size_t)&(((s *)0)->m)
+#endif
+#ifndef countof
+ /**
+ * Count the number of elements in the static array \a a.
+ *
+ * \note This macro is non-standard, but implements a very common idiom
+ */
+ #define countof(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+/**
+ * Cast a member of a structure out to the containing structure.
+ *
+ * \param ptr the pointer to the member.
+ * \param type the type of the container struct this is embedded in.
+ * \param member the name of the member within the struct.
+ */
+#if COMPILER_TYPEOF && COMPILER_STATEMENT_EXPRESSIONS
+ #define containerof(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *_mptr = (ptr); /* type check */ \
+ (type *)((char *)_mptr - offsetof(type, member)); \
+ })
+#else
+ #define containerof(ptr, type, member) \
+ ( (type *)((char *)(ptr) - offsetof(type, member)) )
+#endif
+
+/** Issue a compilation error if the \a condition is false */
+#define STATIC_ASSERT(condition) \
+ UNUSED_VAR(extern char, STATIC_ASSERTION_FAILED__[(condition) ? 1 : -1])
+
+#ifndef ASSERT_TYPE_EQUAL
+ /** Ensure two variables have the same type. */
+ #define ASSERT_TYPE_EQUAL(var1, var2) \
+ do { (void)(&(var1) == &(var2)); } while(0)
+#endif
+
+#ifndef ASSERT_TYPE_IS
+ /** Ensure variable is of specified type. */
+ #define ASSERT_TYPE_IS(var, type) \
+ do { (void)(&(var) == (type *)0); } while(0)
+#endif
+
+#endif /* BERTOS_COMPILER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Simple debug facilities for hosted and embedded C/C++ applications.
+ *
+ * Debug output goes to stderr in hosted applications.
+ * Freestanding (AKA embedded) applications use \c drv/kdebug.c to output
+ * diagnostic messages to a serial terminal or a JTAG debugger.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef DEVLIB_DEBUG_H
+#define DEVLIB_DEBUG_H
+
+#include <cfg/os.h>
+#include <cfg/compiler.h>
+
+
+/*
+ * Defaults for rarely used config stuff.
+ */
+#ifndef CONFIG_KDEBUG_DISABLE_TRACE
+#define CONFIG_KDEBUG_DISABLE_TRACE 0
+#endif
+
+#ifndef CONFIG_KDEBUG_ASSERT_NO_TEXT
+#define CONFIG_KDEBUG_ASSERT_NO_TEXT 0
+#endif
+
+#if defined(__doxygen__)
+ /**
+ * Preprocessor symbol defined only for debug builds.
+ *
+ * The build infrastructure must arrange for _DEBUG to
+ * be predefined for all the source files being compiled.
+ *
+ * This is compatible with the MSVC convention for the
+ * default Debug and Release project targets.
+ */
+ #define _DEBUG 1
+#endif
+
+#ifdef _DEBUG
+
+ // STLport specific: enable extra checks
+ #define __STL_DEBUG 1
+
+ // MSVC specific: Enable memory allocation debug
+ #if defined(_MSC_VER)
+ #include <crtdbg.h>
+ #endif
+
+ /*
+ * On UNIX systems the extabilished practice is to define
+ * NDEBUG for release builds and nothing for debug builds.
+ */
+ #ifdef NDEBUG
+ #undef NDEBUG
+ #endif
+
+ /**
+ * This macro duplicates the old MSVC trick of redefining
+ * THIS_FILE locally to avoid the overhead of many duplicate
+ * strings in ASSERT().
+ */
+ #ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+ #endif
+
+ /**
+ * This macro can be used to conditionally exclude one or more
+ * statements conditioned on \c _DEBUG, avoiding the clutter
+ * of ifdef/endif pairs.
+ *
+ * \code
+ * struct FooBar
+ * {
+ * int foo;
+ * bool bar;
+ * DB(int ref_count;) // Track number of users
+ *
+ * void release()
+ * {
+ * DB(--ref_count;)
+ * }
+ * };
+ * \endcode
+ */
+ #define DB(x) x
+
+ #include <appconfig.h> /* CONFIG_KDEBUG_ASSERT_NO_TEXT */
+ #include <cpu/attr.h> /* CPU_HARVARD */
+
+ /* These are implemented in drv/kdebug.c */
+ void kdbg_init(void);
+ void kputchar(char c);
+ int kputnum(int num);
+ void kdump(const void *buf, size_t len);
+ void __init_wall(long *wall, int size);
+
+ #if CPU_HARVARD
+ #include <mware/pgm.h>
+ void kputs_P(const char *PROGMEM str);
+ void kprintf_P(const char *PROGMEM fmt, ...) FORMAT(__printf__, 1, 2);
+ int __assert_P(const char *PROGMEM cond, const char *PROGMEM file, int line);
+ void __trace_P(const char *func);
+ void __tracemsg_P(const char *func, const char *PROGMEM fmt, ...);
+ int __invalid_ptr_P(void *p, const char *PROGMEM name, const char *PROGMEM file, int line);
+ int __check_wall_P(long *wall, int size, const char * PGM_ATTR name, const char * PGM_ATTR file, int line);
+ #define kputs(str) kputs_P(PSTR(str))
+ #define kprintf(fmt, ...) kprintf_P(PSTR(fmt) ,## __VA_ARGS__)
+ #define __assert(cond, file, line) __assert_P(PSTR(cond), PSTR(file), (line))
+ #define __trace(func) __trace_P(func)
+ #define __tracemsg(func, fmt, ...) __tracemsg_P(func, PSTR(fmt), ## __VA_ARGS__)
+ #define __invalid_ptr(p, name, file, line) __invalid_ptr_P((p), PSTR(name), PSTR(file), (line))
+ #define __check_wall(wall, size, name, file, line) __check_wall_P(wall, size, PSTR(name), PSTR(file), (line))
+ #else /* !CPU_HARVARD */
+ void kputs(const char *str);
+ void kprintf(const char *fmt, ...) FORMAT(__printf__, 1, 2);
+ int __assert(const char *cond, const char *file, int line);
+ void __trace(const char *func);
+ void __tracemsg(const char *func, const char *fmt, ...) FORMAT(__printf__, 2, 3);
+ int __invalid_ptr(void *p, const char *name, const char *file, int line);
+ int __check_wall(long *wall, int size, const char *name, const char *file, int line);
+ #endif /* !CPU_HARVARD */
+
+ #if !CONFIG_KDEBUG_ASSERT_NO_TEXT
+ #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __assert(#x, THIS_FILE, __LINE__)))
+ #define ASSERT2(x, help) ((void)(LIKELY(x) ? 0 : __assert(help " (" #x ")", THIS_FILE, __LINE__)))
+ #else
+ #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __assert("", THIS_FILE, __LINE__)))
+ #define ASSERT2(x, help) ((void)ASSERT(x))
+ #endif
+
+ /**
+ * Check that the given pointer is either NULL or pointing to valid memory.
+ *
+ * The assumption here is that valid pointers never point to low
+ * memory regions. This helps catching pointers taken from
+ * struct/class memebers when the struct pointer was NULL.
+ */
+ #define ASSERT_VALID_PTR(p) ((void)(LIKELY((p) >= 0x200) ? 0 : __invalid_ptr(p, #p, THIS_FILE, __LINE__)))
+
+ /**
+ * Check that the given pointer is not pointing to invalid memory.
+ *
+ * \see ASSERT_VALID_PTR()
+ */
+ #define ASSERT_VALID_PTR_OR_NULL(p) ((void)(LIKELY((p == NULL) || ((p) >= 0x200)) ? 0 : __invalid_ptr((p), #p, THIS_FILE, __LINE__)))
+
+ #if !CONFIG_KDEBUG_DISABLE_TRACE
+ #define TRACE __trace(__func__)
+ #define TRACEMSG(msg,...) __tracemsg(__func__, msg, ## __VA_ARGS__)
+ #else
+ #define TRACE do {} while(0)
+ #define TRACEMSG(...) do {} while(0)
+ #endif
+
+ /**
+ * \name Walls to detect data corruption
+ * \{
+ */
+ #define WALL_SIZE 8
+ #define WALL_VALUE (long)0xABADCAFEL
+ #define DECLARE_WALL(name,size) long name[(size) / sizeof(long)];
+ #define FWD_DECLARE_WALL(name,size) extern long name[(size) / sizeof(long)];
+ #define INIT_WALL(name) __init_wall((name), countof(name))
+ #define CHECK_WALL(name) __check_wall((name), countof(name), #name, THIS_FILE, __LINE__)
+ /*\}*/
+
+ /**
+ * Check that the given pointer actually points to an object
+ * of the specified type.
+ */
+ #define ASSERT_VALID_OBJ(_t, _o) do { \
+ ASSERT_VALID_PTR((_o)); \
+ ASSERT(dynamic_cast<_t>((_o)) != NULL); \
+ }
+
+ /**
+ * \name Debug object creation and destruction.
+ *
+ * These macros help track some kinds of leaks in C++ programs.
+ * Usage is as follows:
+ *
+ * \code
+ * class Foo
+ * {
+ * DECLARE_INSTANCE_TRACKING(Foo)
+ *
+ * Foo()
+ * {
+ * NEW_INSTANCE(Foo);
+ * // ...
+ * }
+ *
+ * ~Foo()
+ * {
+ * DELETE_INSTANCE(Foo);
+ * // ...
+ * }
+ * };
+ *
+ * // Put this in the implementation file of the class
+ * IMPLEMENT_INSTANCE_TRACKING(Foo)
+ *
+ * // Client code
+ * int main(void)
+ * {
+ * Foo *foo = new Foo;
+ * cout << GET_INSTANCE_COUNT(Foo) << endl; // prints "1"
+ * delete foo;
+ * ASSERT_ZERO_INSTANCES(Foo); // OK
+ * }
+ * \endcode
+ * \{
+ */
+ #define NEW_INSTANCE(CLASS) do { ++CLASS::__instances } while (0)
+ #define DELETE_INSTANCE(CLASS) do { --CLASS::__instances } while (0)
+ #define ASSERT_ZERO_INSTANCES(CLASS) ASSERT(CLASS::__instances == 0)
+ #define GET_INSTANCE_COUNT(CLASS) (CLASS::__instances)
+ #define DECLARE_INSTANCE_TRACKING(CLASS) static int __instances
+ #define IMPLEMENT_INSTANCE_TRACKING(CLASS) int CLASS::__instances = 0
+ /*\}*/
+
+#else /* !_DEBUG */
+
+ /*
+ * On UNIX systems the extabilished practice is to define
+ * NDEBUG for release builds and nothing for debug builds.
+ */
+ #ifndef NDEBUG
+ #define NDEBUG 1
+ #endif
+
+ #define DB(x) /* nothing */
+ #ifndef ASSERT
+ #define ASSERT(x) ((void)0)
+ #endif /* ASSERT */
+ #define ASSERT2(x, help) ((void)0)
+ #define ASSERT_VALID_PTR(p) ((void)0)
+ #define ASSERT_VALID_PTR_OR_NULL(p) ((void)0)
+ #define ASSERT_VALID_OBJ(_t, _o) ((void)0)
+ #define TRACE do {} while (0)
+ #if COMPILER_VARIADIC_MACROS
+ #define TRACEMSG(x, ...) do {} while (0)
+ #else
+ INLINE void TRACEMSG(UNUSED_ARG(const char *, msg), ...)
+ {
+ /* NOP */
+ }
+ #endif
+
+ #define DECLARE_WALL(name, size) /* nothing */
+ #define FWD_DECLARE_WALL(name, size) /* nothing */
+ #define INIT_WALL(name) do {} while (0)
+ #define CHECK_WALL(name) do {} while (0)
+
+ #define NEW_INSTANCE(CLASS) do {} while (0)
+ #define DELETE_INSTANCE(CLASS) do {} while (0)
+ #define ASSERT_ZERO_INSTANCES(CLASS) do {} while (0)
+ #define GET_INSTANCE_COUNT(CLASS) ERROR_ONLY_FOR_DEBUG
+ #define DECLARE_INSTANCE_TRACKING(CLASS)
+ #define IMPLEMENT_INSTANCE_TRACKING(CLASS)
+
+ INLINE void kdbg_init(void) { /* nop */ }
+ INLINE void kputchar(UNUSED_ARG(char, c)) { /* nop */ }
+ INLINE int kputnum(UNUSED_ARG(int, num)) { return 0; }
+ INLINE void kputs(UNUSED_ARG(const char *, str)) { /* nop */ }
+ INLINE void kdump(UNUSED_ARG(const void *, buf), UNUSED_ARG(size_t, len)) { /* nop */ }
+
+ #if defined(__cplusplus) && COMPILER_VARIADIC_MACROS
+ /* G++ can't inline functions with variable arguments... */
+ #define kprintf(fmt,...) do { (void)(fmt); } while(0)
+ #else
+ /* ...but GCC can. */
+ INLINE void kprintf(UNUSED_ARG(const char *, fmt), ...) { /* nop */ }
+ #endif
+
+#endif /* _DEBUG */
+
+#endif /* DEVLIB_DEBUG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Common and handy function macros
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+#ifndef CFG_MACROS_H
+#define CFG_MACROS_H
+
+#include <cfg/compiler.h>
+
+/* avr-gcc does not seem to support libstdc++ */
+#if defined(__cplusplus) && !CPU_AVR
+ /* Type-generic macros implemented with template functions. */
+ #include <algorithm>
+
+ template<class T> inline T ABS(T n) { return n >= 0 ? n : -n; }
+ #define MIN(a,b) std::min(a, b)
+ #define MAX(a,b) std::max(a, b)
+ #define SWAP(a,b) std::swap(a, b)
+#elif (COMPILER_STATEMENT_EXPRESSIONS && COMPILER_TYPEOF)
+ /* Type-generic macros implemented with statement expressions. */
+ #define ABS(n) ({ \
+ typeof(n) _n = (n); \
+ (_n < 0) ? -_n : _n; \
+ })
+ #define MIN(a,b) ({ \
+ typeof(a) _a = (a); \
+ typeof(b) _b = (b); \
+ ASSERT_TYPE_EQUAL(_a, _b); \
+ /** \
+ * The (typeof(_a)) cast in necessary: \
+ * result type of conditional expressions is \
+ * *NOT* the type of the value returned but \
+ * the type that would be produced if _a and _b \
+ * were mixed in an expression. \
+ * Even in _a and _b are of the same type, \
+ * if mixed in an expression the type will be \
+ * promoted to int! \
+ */ \
+ ((typeof(_a))((_a < _b) ? _a : _b)); \
+ })
+ #define MAX(a,b) ({ \
+ typeof(a) _a = (a); \
+ typeof(b) _b = (b); \
+ ASSERT_TYPE_EQUAL(_a, _b); \
+ /** \
+ * The (typeof(_a)) cast in necessary: \
+ * result type of conditional expressions is \
+ * *NOT* the type of the value returned but \
+ * the type that would be produced if _a and _b \
+ * were mixed in an expression. \
+ * Even in _a and _b are of the same type, \
+ * if mixed in an expression the type will be \
+ * promoted to int! \
+ */ \
+ ((typeof(_a))((_a > _b) ? _a : _b)); \
+ })
+#else /* !(COMPILER_STATEMENT_EXPRESSIONS && COMPILER_TYPEOF) */
+ /* Buggy macros for inferior compilers. */
+ #define ABS(a) (((a) < 0) ? -(a) : (a))
+ #define MIN(a,b) (((a) < (b)) ? (a) : (b))
+ #define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* !(COMPILER_STATEMENT_EXPRESSIONS && COMPILER_TYPEOF) */
+
+/** Bound \a x between \a min and \a max. */
+#define MINMAX(min,x,max) (MIN(MAX(min, x), max))
+
+#ifdef __cplusplus
+ /* Use standard implementation from <algorithm> */
+ #define SWAP(a,b) std::swap(a, b)
+#elif COMPILER_TYPEOF
+ /**
+ * Type-generic macro to swap \a a with \a b.
+ *
+ * \note Arguments are evaluated multiple times.
+ */
+ #define SWAP(a, b) \
+ do { \
+ typeof(a) tmp; \
+ ASSERT_TYPE_EQUAL(a, b); \
+ tmp = (a); \
+ (a) = (b); \
+ (b) = tmp; \
+ } while (0)
+#else /* !COMPILER_TYPEOF */
+ /* Sub-optimal implementation that only works with integral types. */
+ #define SWAP(a, b) \
+ do { \
+ (a) ^= (b); \
+ (b) ^= (a); \
+ (a) ^= (b); \
+ } while (0)
+
+#endif /* COMPILER_TYPEOF */
+
+/**
+ * Macro to swap \a a with \a b, with explicit type \a T for dumb C89 compilers.
+ *
+ * \note Arguments are evaluated multiple times.
+ */
+#define SWAP_T(a, b, T) \
+ do { \
+ T tmp; \
+ ASSERT_TYPE_IS(a, T); \
+ ASSERT_TYPE_IS(b, T); \
+ tmp = (a); \
+ (a) = (b); \
+ (b) = tmp; \
+ } while (0)
+
+
+#ifndef BV
+ /** Convert a bit value to a binary flag. */
+ #define BV(x) (1<<(x))
+#endif
+
+/** Same as BV() but with 32 bit result */
+#define BV32(x) ((uint32_t)1<<(x))
+
+/** Same as BV() but with 16 bit result */
+#define BV16(x) ((uint16_t)1<<(x))
+
+/** Same as BV() but with 8 bit result */
+#define BV8(x) ((uint8_t)1<<(x))
+
+/**
+ * Perform an integer division rounding the result to the nearest int value.
+ * \note \a divisor should preferibly be a costant, otherwise this macro generates
+ * 2 division. Also divisor is evaluated twice.
+ */
+#define DIV_ROUND(dividend, divisor) (((dividend) + (divisor) / 2) / (divisor))
+
+/** Round up \a x to an even multiple of the 2's power \a pad. */
+#define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
+
+/* OBSOLETE */
+#define ROUND2 ROUND_UP2
+
+/**
+ * \name Integer round macros.
+ *
+ * Round \a x to a multiple of \a base.
+ * \note If \a x is signed these macros generate a lot of code.
+ * \{
+ */
+#define ROUND_DOWN(x, base) ( (x) - ((x) % (base)) )
+#define ROUND_UP(x, base) ( ((x) + (base) - 1) - (((x) + (base) - 1) % (base)) )
+#define ROUND_NEAREST(x, base) ( ((x) + (base) / 2) - (((x) + (base) / 2) % (base)) )
+/* \} */
+
+/** Check if \a x is an integer power of 2. */
+#define IS_POW2(x) (!(bool)((x) & ((x)-1)))
+
+/** Calculate a compile-time log2 for a uint8_t */
+#define UINT8_LOG2(x) \
+ ((x) < 2 ? 0 : \
+ ((x) < 4 ? 1 : \
+ ((x) < 8 ? 2 : \
+ ((x) < 16 ? 3 : \
+ ((x) < 32 ? 4 : \
+ ((x) < 64 ? 5 : \
+ ((x) < 128 ? 6 : 7)))))))
+
+/** Calculate a compile-time log2 for a uint16_t */
+#define UINT16_LOG2(x) \
+ ((x < 256) ? UINT8_LOG2(x) : UINT8_LOG2((x) >> 8) + 8)
+
+/** Calculate a compile-time log2 for a uint32_t */
+#define UINT32_LOG2(x) \
+ ((x < 65536UL) ? UINT16_LOG2(x) : UINT16_LOG2((x) >> 16) + 16)
+
+#if COMPILER_VARIADIC_MACROS
+ /** Count the number of arguments (up to 16). */
+ #define PP_COUNT(...) \
+ PP_COUNT__(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
+ #define PP_COUNT__(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,count,...) \
+ count
+#endif
+
+#if COMPILER_VARIADIC_MACROS
+ /**
+ * \def BIT_CHANGE(reg, (mask, value), ...)
+ *
+ * This macro allows for efficient and compact bit toggling in a hardware
+ * register. It is meant to replace hand-coded cruft which toggles bits
+ * in sequence.
+ *
+ * It is possible to specify an unlimited pair of (mask, value) parameters.
+ * For instance:
+ *
+ * \code
+ * void set_timer(bool start)
+ * {
+ * BIT_CHANGE(REG_CTRL_TIMER,
+ * (TIMER_MODE, MODE_COUNT),
+ * (OVL_IRQ, 1),
+ * (CMP_IRQ, 1),
+ * (START, start)
+ * );
+ * }
+ * \endcode
+ *
+ * The macro expansion will be roughly the following:
+ *
+ * \code
+ * REG_CTRL_TIMER = (REG_CTRL_TIMER & ~(TIMER_MODE|OVL_IRQ|CMP_IRQ|START)
+ * | (MODE_COUNT|OVL_IRQ|CMP_IRQ|(start ? START : 0));
+ * \endcode
+ *
+ * It is up to the compiler to produce the optimal code. We checked that GCC produces
+ * the best code in most cases. We preferred this expansion over the use of a block
+ * with a local variable because CodeWarrior 6.1 was not able to remove completely the
+ * allocation of the local from the stack.
+ *
+ * \note This macro is available only in C99 because it makes use of variadic macros.
+ * It would be possible to make up an implementation with a slightly different syntax
+ * for use with C90 compilers, through Boost Preprocessor.
+ */
+
+ /**
+ * \def BIT_CHANGE_BV(reg, (bit, value), ...)
+ *
+ * Similar to BIT_CHANGE(), but get bits instead of masks (and applies BV() to convert
+ * them to masks).
+ */
+
+ #define BIT_EXTRACT_FLAG_0(bit, value) bit
+ #define BIT_EXTRACT_FLAG_1(bit, value) BV(bit)
+ #define BIT_EXTRACT_VALUE__(bit, value) value
+
+ #define BIT_MASK_SINGLE__(use_bv, index, max, arg) \
+ ((index < max) ? (PP_CAT(BIT_EXTRACT_FLAG_, use_bv) arg) : 0) \
+ /**/
+
+ #define BIT_MASK_IF_SINGLE__(use_bv, index, max, arg) \
+ (((index < max) && (BIT_EXTRACT_VALUE__ arg)) ? (PP_CAT(BIT_EXTRACT_FLAG_, use_bv) arg) : 0) \
+ /**/
+
+ #define BIT_ITER__2(macro, use_bv, max, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15, ...) \
+ (macro(use_bv, 0, max, a0) | \
+ macro(use_bv, 1, max, a1) | \
+ macro(use_bv, 2, max, a2) | \
+ macro(use_bv, 3, max, a3) | \
+ macro(use_bv, 4, max, a4) | \
+ macro(use_bv, 5, max, a5) | \
+ macro(use_bv, 6, max, a6) | \
+ macro(use_bv, 7, max, a7) | \
+ macro(use_bv, 8, max, a8) | \
+ macro(use_bv, 9, max, a9) | \
+ macro(use_bv, 10, max, a10) | \
+ macro(use_bv, 11, max, a11) | \
+ macro(use_bv, 12, max, a12) | \
+ macro(use_bv, 13, max, a13) | \
+ macro(use_bv, 14, max, a14) | \
+ macro(use_bv, 15, max, a15)) \
+ /**/
+
+ #define BIT_ITER__(macro, use_bv, ...) \
+ BIT_ITER__2(macro, use_bv, PP_COUNT(__VA_ARGS__), __VA_ARGS__, (0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1)) \
+ /**/
+
+ #define BIT_MASKS__(use_bv, ...) \
+ BIT_ITER__(BIT_MASK_SINGLE__, use_bv, __VA_ARGS__)
+ /**/
+
+ #define BIT_MASKS_CONDITIONAL__(use_bv, ...) \
+ BIT_ITER__(BIT_MASK_IF_SINGLE__, use_bv, __VA_ARGS__)
+ /**/
+
+ #define BIT_CHANGE__(reg, use_bv, ...) \
+ ((reg) = ((reg) & ~BIT_MASKS__(use_bv, __VA_ARGS__)) | BIT_MASKS_CONDITIONAL__(use_bv, __VA_ARGS__)) \
+ /**/
+
+ #define BIT_CHANGE(reg, ...) BIT_CHANGE__(reg, 0, __VA_ARGS__)
+ #define BIT_CHANGE_BV(reg, ...) BIT_CHANGE__(reg, 1, __VA_ARGS__)
+
+#endif /* COMPILER_VARIADIC_MACROS */
+
+/**
+ * Macro for rotating bit left or right.
+ * \{
+ */
+#define ROTR(var, rot) (((var) >> (rot)) | ((var) << ((sizeof(var) * 8) - (rot))))
+#define ROTL(var, rot) (((var) << (rot)) | ((var) >> ((sizeof(var) * 8) - (rot))))
+/*\}*/
+
+/**
+ * Make an id from 4 letters, useful for
+ * file formats and kfile ids.
+ */
+#define MAKE_ID(a,b,c,d) \
+ ( ((uint32_t)(a) << 24) \
+ | ((uint32_t)(b) << 16) \
+ | ((uint32_t)(c) << 8) \
+ | ((uint32_t)(d) << 0) )
+
+/**
+ * Type for id generated by MAKE_ID().
+ */
+typedef uint32_t id_t;
+
+#endif /* MACROS_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Debug macros for inter-module dependency checking.
+ *
+ * These macros expand to nothing in release builds. In debug
+ * builds, they perform run-time dependency checks for modules.
+ *
+ * The usage pattern looks like this:
+ *
+ * \code
+ * MOD_DEFINE(phaser)
+ *
+ * void phaser_init(void)
+ * {
+ * MOD_CHECK(computer);
+ * MOD_CHECK(warp_core);
+ *
+ * [...charge weapons...]
+ *
+ * MOD_INIT(phaser);
+ * }
+ *
+ * void phaser_cleanup(void)
+ * {
+ * MOD_CLEANUP(phaser);
+ *
+ * [...disarm phaser...]
+ * }
+ * \endcode
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+#ifndef CFG_MODULE_H
+#define CFG_MODULE_H
+
+#include <cfg/debug.h>
+
+/**
+ * Declare a global variable for module dependency check.
+ *
+ * \see MOD_INIT(), MOD_CHECK()
+ */
+#define MOD_DEFINE(module) DB(extern bool module ## _initialized; bool module ## _initialized;)
+
+/**
+ * Check that \a module was already initialized.
+ *
+ * Put this check just before accessing any facility
+ * provided by a module that requires prior initialization.
+ *
+ * \see MOD_INIT()
+ */
+
+#define MOD_CHECK(module) \
+do { \
+ DB(extern bool module ## _initialized;) \
+ ASSERT(module ## _initialized); \
+} while (0)
+
+/**
+ * Mark module as initialized.
+ *
+ * Marking initialization requires the global data
+ * previously defined by MOD_DEFINE().
+ *
+ * To prevent double initialization bugs, an initialized
+ * module must first be cleaned up with MOD_CLEANUP() before
+ * calling MOD_INIT() another time.
+ *
+ * \see MOD_CLEANUP(), MOD_CHECK(), MOD_DEFINE()
+ */
+#define MOD_INIT(module) \
+do { \
+ ASSERT(!module ## _initialized); \
+ DB(module ## _initialized = true;) \
+} while (0)
+
+/**
+ * Mark module as being no longer initialized.
+ *
+ * Marking initialization requires the global data
+ * previously defined by MOD_DEFINE().
+ *
+ * \see MOD_INIT(), MOD_CHECK(), MOD_DEFINE()
+ */
+#define MOD_CLEANUP(module) \
+do { \
+ ASSERT(module ## _initialized); \
+ DB(module ## _initialized = false;) \
+} while (0)
+
+#endif /* CFG_MODULE_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief OS-specific definitions
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef DEVLIB_OS_H
+#define DEVLIB_OS_H
+
+/** Macro to include OS-specific versions of the headers. */
+#define OS_HEADER(module) PP_STRINGIZE(PP_CAT3(module, _, OS_ID).h)
+#define OS_CSOURCE(module) PP_STRINGIZE(PP_CAT3(module, _, OS_ID).c)
+
+/*
+ * OS autodetection (Some systems trigger multiple OS definitions)
+ */
+#ifdef _WIN32
+ #define OS_WIN32 1
+ #define OS_ID win32
+
+ // FIXME: Maybe disable Win32 exceptions?
+ typedef int cpuflags_t;
+ #define IRQ_DISABLE /* FIXME */
+ #define IRQ_ENABLE /* FIXME */
+ #define IRQ_SAVE_DISABLE(old_sigs) /* FIXME */
+ #define IRQ_RESTORE(old_sigs) /* FIXME */
+
+#else
+ #define OS_WIN32 0
+#endif
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+ #define OS_UNIX 1
+ #define OS_POSIX 1 /* Not strictly UNIX, but no way to autodetect it. */
+ #define OS_ID posix
+
+ /*
+ * The POSIX moral equivalent of disabling IRQs is disabling signals.
+ */
+ #include <signal.h>
+ typedef sigset_t cpuflags_t;
+
+ #define SET_ALL_SIGNALS(sigs) \
+ do { \
+ sigfillset(&sigs); \
+ sigdelset(&sigs, SIGINT); \
+ sigdelset(&sigs, SIGSTOP); \
+ sigdelset(&sigs, SIGCONT); \
+ } while(0)
+
+ #define IRQ_DISABLE \
+ do { \
+ sigset_t sigs; \
+ SET_ALL_SIGNALS(sigs); \
+ sigprocmask(SIG_BLOCK, &sigs, NULL); \
+ } while (0)
+
+ #define IRQ_ENABLE \
+ do { \
+ sigset_t sigs; \
+ SET_ALL_SIGNALS(sigs); \
+ sigprocmask(SIG_UNBLOCK, &sigs, NULL); \
+ } while (0)
+
+ #define IRQ_SAVE_DISABLE(old_sigs) \
+ do { \
+ sigset_t sigs; \
+ SET_ALL_SIGNALS(sigs); \
+ sigprocmask(SIG_BLOCK, &sigs, &old_sigs); \
+ } while (0)
+
+ #define IRQ_RESTORE(old_sigs) \
+ do { \
+ sigprocmask(SIG_SETMASK, &old_sigs, NULL); \
+ } while (0)
+
+ #define IRQ_ENABLED() \
+ ({ \
+ sigset_t sigs; \
+ sigprocmask(SIG_SETMASK, NULL, &sigs); \
+ sigismember(&sigs, SIGALRM) ? false : true; \
+ })
+
+#else
+ #define OS_UNIX 0
+ #define OS_POSIX 0
+#endif
+
+#ifdef __linux__
+ #define OS_LINUX 1
+#else
+ #define OS_LINUX 0
+#endif
+
+#if defined(__APPLE__) && defined(__MACH__)
+ #define OS_DARWIN 1
+#else
+ #define OS_DARWIN 0
+#endif
+
+/*
+ * We want Qt and other frameworks to look like OSes because you would
+ * tipically want their portable abstractions if you're using one of these.
+ */
+#if defined(_QT)
+ #define OS_QT 1
+ #undef OS_ID
+ #define OS_ID qt
+#else
+ #define OS_QT 0
+#endif
+
+/*
+ * Summarize hosted environments as OS_HOSTED and embedded
+ * environment with OS_EMBEDDED.
+ */
+#if OS_WIN32 || OS_UNIX || OS_DARWIN || OS_QT
+ #define OS_HOSTED 1
+ #define OS_EMBEDDED 0
+#else
+ #define OS_HOSTED 0
+ #define OS_EMBEDDED 1
+
+ /* Embedded environments fall back to CPU-specific code. */
+ #define OS_ID CPU_ID
+#endif
+
+/* Self-check for the detection */
+#if !defined(OS_ID)
+ #error OS_ID not defined
+#endif
+#if OS_HOSTED && OS_EMBEDDED
+ #error Both hosted and embedded OS environment
+#endif
+#if !OS_HOSTED && !OS_EMBEDDED
+ #error Neither hosted nor embedded OS environment
+#endif
+
+#endif /* DEVLIB_OS_H */
--- /dev/null
+#
+# $Id$
+# Copyright 2002,2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+# All rights reserved.
+#
+# Author: Bernardo Innocenti <bernie@develer.com>
+# Based on: GCC-AVR standard Makefile part 1, Volker Oth 1/2000
+#
+
+#
+# Programmer type
+# see local pgm_config.mk for programmer customization.
+-include pgm_config.mk
+DPROG ?= -V -c stk500 -P /dev/ttyS0
+
+# Set to 1 to build for embedded devices.
+# e.g. produce target.elf instead of target and target_nostrip
+EMBEDDED_TARGET = 1
+#EMBEDDED_TARGET = 0
+
+OPTCFLAGS = -ffunction-sections -fdata-sections
+#OPTCFLAGS = -funsafe-loop-optimizations
+
+# For AVRStudio
+#DEBUGCFLAGS = -gdwarf-2
+
+# For GDB
+DEBUGCFLAGS = -ggdb
+
+#
+# define some variables based on the AVR base path in $(AVR)
+#
+#CROSS = avr-
+CC = gcc
+CXX = g++
+AS = $(CC) -x assembler-with-cpp
+LD = $(CC)
+LDXX = $(CXX)
+OBJCOPY = objcopy
+STRIP = strip
+INSTALL = cp -a
+RM = rm -f
+RM_R = rm -rf
+RN = mv
+MKDIR_P = mkdir -p
+SHELL = /bin/sh
+CHECKER = sparse
+DOXYGEN = doxygen
+AVRDUDE = avrdude
+MOC = moc-qt4
+FLEXCAT = $(top_srcdir)/tools/flexcat/flexcat
+
+# For conversion from ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT=$(OBJCOPY) \
+ --debugging \
+ --change-section-address .data-0x800000 \
+ --change-section-address .bss-0x800000 \
+ --change-section-address .noinit-0x800000 \
+ --change-section-address .eeprom-0x810000
+
+INCDIR = -I. -Ibertos -Ibertos/hw
+LIBDIR = lib
+OBJDIR = obj
+OUTDIR = images
+
+# output format can be srec, ihex (avrobj is always created)
+FORMAT = srec
+#FORMAT = ihex
+
+# Compiler flags for generating dependencies
+DEP_FLAGS = -MMD -MP
+
+# Compiler flags for generating source listings
+LIST_FLAGS = -Wa,-anhlmsd=$(@:.o=.lst)
+
+# Linker flags for generating map files
+ifeq ($(EMBEDDED_TARGET), 1)
+MAP_FLAGS = -Wl,-Map=$(@:%.elf=%.map),--cref
+else
+MAP_FLAGS =
+endif
+
+# Compiler warning flags for both C and C++
+WARNFLAGS = \
+ -W -Wformat -Wall -Wundef -Wpointer-arith -Wcast-qual \
+ -Wcast-align -Wwrite-strings -Wsign-compare \
+ -Wmissing-noreturn \
+ -Wextra -Wstrict-aliasing=2 \
+# -Wunsafe-loop-optimizations
+
+# Compiler warning flags for C only
+C_WARNFLAGS = \
+ -Wmissing-prototypes -Wstrict-prototypes
+
+# Default C preprocessor flags (for C, C++ and cpp+as)
+CPPFLAGS = $(INCDIR)
+
+# Default C compiler flags
+CFLAGS = $(OPTCFLAGS) $(DEBUGCFLAGS) $(WARNFLAGS) $(C_WARNFLAGS) \
+ $(DEP_FLAGS) $(LIST_FLAGS) -std=gnu99
+
+# Default C++ compiler flags
+CXXFLAGS = $(OPTCFLAGS) $(DEBUGCFLAGS) $(WARNFLAGS) \
+ $(DEP_FLAGS) $(LIST_FLAGS)
+
+# Default compiler assembly flags
+CPPAFLAGS = $(DEBUGCFLAGS) -MMD
+
+# Default assembler flags
+ASFLAGS = $(DEBUGCFLAGS)
+
+# Default linker flags
+#LDFLAGS = $(MAP_FLAGS)
+
+#bernie: does not complain for missing symbols!
+LDFLAGS = $(MAP_FLAGS) -Wl,--gc-sections
+
+# Flags for avrdude
+AVRDUDEFLAGS = $(DPROG)
+
+# additional libs
+LIB = -lm
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Kernel configuration parameters
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.8 2006/07/19 12:56:24 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.7 2006/02/21 16:05:53 bernie
+ *#* Move from cfg/ to top-level.
+ *#*
+ *#* Revision 1.3 2005/11/04 16:20:01 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.2 2005/04/11 19:10:27 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.1 2005/04/11 19:04:13 bernie
+ *#* Move top-level headers to cfg/ subdir.
+ *#*
+ *#* Revision 1.5 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.4 2004/08/24 16:19:38 bernie
+ *#* Add missing header.
+ *#*
+ *#* Revision 1.3 2004/07/30 14:24:16 rasky
+ *#* Task switching con salvataggio perfetto stato di interrupt (SR)
+ *#* Kernel monitor per dump informazioni su stack dei processi
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 17:48:35 bernie
+ *#* Add top-level files.
+ *#*
+ *#*/
+#ifndef CONFIG_KERN_H
+#define CONFIG_KERN_H
+
+#include <cfg/arch_config.h> /* ARCH_EMUL */
+
+/**
+ * \name Modules activation
+ *
+ * \{
+ */
+/* Module/option Active Dependencies */
+#define CONFIG_KERN_SCHED (1)
+#define CONFIG_KERN_SIGNALS (1 && CONFIG_KERN_SCHED)
+#define CONFIG_KERN_TIMER (1)
+#define CONFIG_KERN_HEAP (0)
+#define CONFIG_KERN_SEMAPHORES (0 && CONFIG_KERN_SIGNALS)
+#define CONFIG_KERN_MONITOR (1 && CONFIG_KERN_SCHED)
+/*\}*/
+
+/* EXPERIMENTAL */
+#define CONFIG_KERN_PREEMPTIVE (0 && CONFIG_KERN_SCHED && CONFIG_KERN_TIMER)
+
+#define CONFIG_KERN_QUANTUM 50 /**< Time sharing quantum in timer ticks. */
+
+#if (ARCH & ARCH_EMUL)
+ /* We need a large stack because system libraries are bloated */
+ #define CONFIG_PROC_DEFSTACKSIZE 65536
+#else
+ /**
+ * Default stack size for each thread, in bytes.
+ *
+ * The goal here is to allow a minimal task to save all of its
+ * registers twice, plus push a maximum of 32 variables on the
+ * stack.
+ *
+ * The actual size computed by the default formula is:
+ * AVR: 102
+ * i386: 156
+ * ARM: 164
+ * x86_64: 184
+ *
+ * Note that on most 16bit architectures, interrupts will also
+ * run on the stack of the currently running process. Nested
+ * interrupts will greatly increases the amount of stack space
+ * required per process. Use irqmanager to minimize stack
+ * usage.
+ */
+ #define CONFIG_PROC_DEFSTACKSIZE \
+ (CPU_SAVED_REGS_CNT * 2 * sizeof(cpustack_t) \
+ + 32 * sizeof(int))
+#endif
+
+/* OBSOLETE */
+#define CONFIG_KERN_DEFSTACKSIZE CONFIG_PROC_DEFSTACKSIZE
+
+/* Memory fill codes to help debugging */
+#if CONFIG_KERN_MONITOR
+ #include <cpu/types.h>
+ #if (SIZEOF_CPUSTACK_T == 1)
+ /* 8bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5
+ #define CONFIG_KERN_MEMFILLCODE 0xDB
+ #elif (SIZEOF_CPUSTACK_T == 2)
+ /* 16bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5A5
+ #define CONFIG_KERN_MEMFILLCODE 0xDBDB
+ #elif (SIZEOF_CPUSTACK_T == 4)
+ /* 16bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5UL
+ #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBUL
+ #elif (SIZEOF_CPUSTACK_T == 8)
+ /* 16bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5A5A5A5A5UL
+ #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBDBDBDBDBUL
+ #else
+ #error No cpustack_t size supported!
+ #endif
+#endif
+
+
+#endif /* CONFIG_KERN_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief ADC driver (implementation)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+
+#include <drv/adc.h>
+#include <drv/timer.h>
+
+#include CPU_CSOURCE(adc)
+
+#include <cfg/debug.h> // ASSERT()
+#include <cfg/macros.h> // MIN()
+#include <cfg/compiler.h>
+#include <cfg/module.h>
+
+/**
+ * Read the ADC channel \a ch.
+ */
+adcread_t adc_read(adc_ch_t ch)
+{
+ ASSERT(ch <= (adc_ch_t)ADC_MUX_MAXCH);
+ ch = MIN(ch, (adc_ch_t)ADC_MUX_MAXCH);
+
+ adc_hw_select_ch(ch);
+
+ return(adc_hw_read());
+}
+
+MOD_DEFINE(adc);
+
+/**
+ * Initialize the ADC hardware.
+ */
+void adc_init(void)
+{
+ adc_hw_init();
+
+ MOD_INIT(adc);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief ADC driver (interface)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+
+#ifndef DRV_ADC_H
+#define DRV_ADC_H
+
+#include <cfg/compiler.h>
+#include <cfg/debug.h>
+#include <cpu/attr.h>
+#include CPU_HEADER(adc)
+
+/** Type for ADC return value. */
+typedef uint16_t adcread_t;
+
+/** Type for channel */
+typedef uint8_t adc_ch_t;
+
+#define adc_bits() ADC_BITS
+
+adcread_t adc_read(adc_ch_t ch);
+void adc_init(void);
+
+/**
+ * Macro used to convert data from adc range (0...(2 ^ADC_BITS - 1)) to
+ * \a y1 ... \a y2 range.
+ * \note \a y1, \a y2 can be negative, and put in ascending or descending order as well.
+ * \note \a data and \a y2 are evaluated only once, \a y1 twice.
+ */
+#define ADC_RANGECONV(data, y1, y2) ((((data) * ((y2) - (y1))) / ((1 << ADC_BITS) - 1)) + (y1))
+
+#endif /* DRV_ADC_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Buzzer driver (implementation)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.19 2006/07/19 12:56:25 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.18 2006/02/17 21:15:25 bernie
+ *#* Add MOD_CHECK() checks.
+ *#*
+ *#* Revision 1.17 2006/02/10 12:30:18 bernie
+ *#* Push interrupt protection inside hw module.
+ *#*
+ *#* Revision 1.16 2005/11/04 16:19:33 bernie
+ *#* buz_init(): Restore IRQ protection as in project_bko.
+ *#*
+ *#* Revision 1.15 2005/06/27 21:25:50 bernie
+ *#* Modularize hardware access; Port to new timer interface.
+ *#*
+ *#* Revision 1.14 2005/04/11 19:10:27 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.13 2005/02/18 11:20:15 bernie
+ *#* Use mware/event.h; Update copyright info.
+ *#*
+ *#* Revision 1.12 2004/12/13 12:07:06 bernie
+ *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE.
+ *#*
+ *#* Revision 1.11 2004/12/08 09:11:53 bernie
+ *#* Rename time_t to mtime_t.
+ *#*
+ *#* Revision 1.10 2004/10/03 18:38:51 bernie
+ *#* Add missing AVR header; Fix header.
+ *#*
+ *#* Revision 1.9 2004/09/14 21:01:25 bernie
+ *#* Use new AVR port pin names.
+ *#*/
+
+#include "buzzer.h"
+
+#include <hw_buzzer.h>
+#include <drv/timer.h>
+
+#include <mware/event.h>
+
+#include <cfg/debug.h>
+#include <cfg/module.h>
+
+
+/* Local vars */
+static Timer buz_timer;
+static bool buz_timer_running;
+static mtime_t buz_repeat_interval;
+static mtime_t buz_repeat_duration;
+
+
+/**
+ * Turn off buzzer, called by software timer
+ */
+static void buz_softint(void)
+{
+ if (IS_BUZZER_ON)
+ {
+ BUZZER_OFF;
+ if (buz_repeat_interval)
+ {
+ /* Wait for interval time */
+ timer_setDelay(&buz_timer, ms_to_ticks(buz_repeat_interval));
+ timer_add(&buz_timer);
+ }
+ else
+ buz_timer_running = false;
+ }
+ else if (buz_repeat_interval)
+ {
+ /* Wait for beep time */
+ BUZZER_ON;
+ timer_setDelay(&buz_timer, ms_to_ticks(buz_repeat_duration));
+ timer_add(&buz_timer);
+ }
+ else
+ buz_timer_running = false;
+}
+
+
+/**
+ * Beep for the specified ms time
+ */
+void buz_beep(mtime_t time)
+{
+ cpuflags_t flags;
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Remove the software interrupt if it was already queued */
+ if (buz_timer_running)
+ timer_abort(&buz_timer);
+
+ /* Turn on buzzer */
+ BUZZER_ON;
+
+ /* Add software interrupt to turn the buzzer off later */
+ buz_timer_running = true;
+ timer_setDelay(&buz_timer, ms_to_ticks(time));
+ timer_add(&buz_timer);
+
+ IRQ_RESTORE(flags);
+}
+
+
+/**
+ * Start buzzer repetition
+ */
+void buz_repeat_start(mtime_t duration, mtime_t interval)
+{
+ buz_repeat_interval = interval;
+ buz_repeat_duration = duration;
+ buz_beep(duration);
+}
+
+
+/**
+ * Stop buzzer repetition
+ */
+void buz_repeat_stop(void)
+{
+ cpuflags_t flags;
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Remove the software interrupt if it was already queued */
+ if (buz_timer_running)
+ {
+ timer_abort(&buz_timer);
+ buz_timer_running = false;
+ }
+
+ buz_repeat_interval = 0;
+ BUZZER_OFF;
+
+ IRQ_RESTORE(flags);
+}
+
+MOD_DEFINE(buzzer)
+
+/**
+ * Initialize buzzer.
+ */
+void buz_init(void)
+{
+ MOD_CHECK(timer);
+
+ BUZZER_HW_INIT;
+
+ /* Init software interrupt. */
+ timer_set_event_softint(&buz_timer, (Hook)buz_softint, 0);
+
+ MOD_INIT(buzzer);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003,2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Buzzer driver
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.10 2006/07/19 12:56:25 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.9 2005/11/27 23:32:15 bernie
+ *#* Update copyright information.
+ *#*
+ *#* Revision 1.8 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.7 2005/04/11 19:10:27 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.6 2004/12/08 09:11:53 bernie
+ *#* Rename time_t to mtime_t.
+ *#*
+ *#* Revision 1.5 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.4 2004/08/24 16:53:43 bernie
+ *#* Add missing headers.
+ *#*
+ *#* Revision 1.3 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.2 2004/05/23 18:21:53 bernie
+ *#* Trim CVS logs and cleanup header info.
+ *#*
+ *#*/
+#ifndef DRV_BUZZER_H
+#define DRV_BUZZER_H
+
+#include <cfg/compiler.h>
+
+extern void buz_init(void);
+extern void buz_beep(mtime_t time);
+extern void buz_repeat_start(mtime_t duration, mtime_t interval);
+extern void buz_repeat_stop(void);
+
+#endif /* DRV_BUZZER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ *
+ * -->
+ *
+ * \brief Generic library to handle buzzers and leds
+ *
+ * This library is divided into three different layers:
+ *
+ * - The topmost portable layer is buzzerled.[ch] which exposes a common API
+ * enable/disable the devices. Basically, it handles the asynchronism to
+ * implement bld_beep and bld_repeat.
+ * - The middle layer is CPU-specific and exposes a single main function which
+ * turns on/off each device.
+ * - The lower layer is board-specific and communicates with the middle layer
+ * with any required API. The idea is that devices can be tied to the CPU in
+ * many different ways (many different pins), so this part should describe
+ * which devices are present, and how they are connected.
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:25 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.5 2004/12/08 09:43:41 bernie
+ *#* Add a todo item.
+ *#*
+ *#* Revision 1.4 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.3 2004/07/14 14:04:29 rasky
+ *#* Merge da SC: spostata bld_set inline perché si ottimizza parecchio tramite propagazione di costanti
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 18:36:05 bernie
+ *#* Import buzzerled driver.
+ *#*
+ *#*/
+
+#include "buzzerled.h"
+#include "timer.h"
+
+static struct Timer timers[NUM_BLDS];
+static bool timer_go[NUM_BLDS];
+
+INLINE enum BLD_DEVICE hook_parm_to_device(void* parm)
+{
+ struct Timer* t = (struct Timer*)parm;
+ int num_bld = t - &timers[0];
+
+ ASSERT(num_bld >= 0);
+ ASSERT(num_bld < NUM_BLDS);
+
+ return (enum BLD_DEVICE)num_bld;
+}
+
+static void hook_turn_off(void* parm)
+{
+ enum BLD_DEVICE num_bld = hook_parm_to_device(parm);
+ bld_set(num_bld, false);
+}
+
+void bld_init(void)
+{
+ bld_hw_init();
+}
+
+void bld_beep(enum BLD_DEVICE device, uint16_t duration)
+{
+ // \todo This is not reentrant for the same device. FIXME!
+ struct Timer *t = &timers[device];
+ timer_set_delay(t, duration);
+ timer_set_event_softint(t, hook_turn_off, t);
+ timer_add(t);
+
+ bld_set(device, true);
+}
+
+void bld_beep_and_wait(enum BLD_DEVICE device, uint16_t duration)
+{
+ bld_set(device, true);
+ timer_delay(duration);
+ bld_set(device, false);
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ *
+ * -->
+ *
+ * \brief Generic library to handle buzzers and leds
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+#ifndef DRV_BUZZERLED_H
+#define DRV_BUZZERLED_H
+
+#include <cpu/attr.h>
+
+/** Include hw.h. We expect hw.h to define enum BLD_DEVICE, which must contain
+ * an enumarator for each device, plus a special symbol NUM_BLDS containing the
+ * number of devices.
+ */
+#include <hw.h>
+
+
+/* Include hw-level implementation. This allows inlining of bld_set, which in turns
+ * should allow fast constant propagation for the common case (where the parameter
+ * device is a constant).
+ */
+#include CPU_HEADER(buzzerled)
+
+
+/** Initialize the buzzerled library.
+ *
+ * \note This function must be called before any other function in the library.
+ */
+void bld_init(void);
+
+
+/** Set or reset a device.
+ *
+ * \param device Device to be set
+ * \param enable Enable/disable status
+ */
+#define bld_set(device, enable) bld_hw_set(device, enable)
+
+
+/** Enable a device for a certain interval of time
+ *
+ * \param device Device to be enabled
+ * \param duration Number of milliseconds the device must be enabled
+ *
+ * \note This function is non-blocking, so it will return immediately.
+ */
+void bld_beep(enum BLD_DEVICE device, uint16_t duration);
+
+
+/** Enable a device for a certain interval of time and wait.
+ *
+ * \param device Device to be enabled
+ * \param duration Number of milliseconds the device must be enabled
+ *
+ * \note This function is blocking, so it will return after the specified period of time.
+ */
+void bld_beep_and_wait(enum BLD_DEVICE device, uint16_t duration);
+
+#endif /* DRV_BUZZERLED_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Function library for AT45DBXX Data Flash memory.
+ *
+ *
+ * \version $Id: dataflash.c 20677 2008-02-19 14:29:52Z batt $
+ * \author Daniele Basile <asterix@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#include "dataflash.h"
+#include <appconfig.h>
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+#include <cfg/module.h>
+#include <drv/timer.h>
+#include <kern/kfile.h>
+
+#if CONFIG_KERNEL
+#include <kern/proc.h>
+#endif
+
+#include <string.h>
+
+/**
+ * Array used to describe dataflash memory devices currently supported.
+ */
+static const DataflashInfo mem_info[] =
+{
+ {
+ /* AT45DB041B */
+ .density_id = 0x07,
+ .page_size = 264,
+ .page_bits = 9,
+ .page_cnt = 2048,
+ .read_cmd = DFO_READ_FLASH_MEM_BYTE_B,
+ },
+ {
+ /* AT45DB081D */
+ .density_id = 0x09,
+ .page_size = 264,
+ .page_bits = 9,
+ .page_cnt = 4096,
+ .read_cmd = DFO_READ_FLASH_MEM_BYTE_D,
+ },
+ {
+ /* AT45DB161D */
+ .density_id = 0x0B,
+ .page_size = 528,
+ .page_bits = 10,
+ .page_cnt = 4096,
+ .read_cmd = DFO_READ_FLASH_MEM_BYTE_D,
+ },
+ /* Add other memories here */
+};
+
+STATIC_ASSERT(countof(mem_info) == DFT_CNT);
+
+/**
+ * Macro that toggle CS of dataflash.
+ * \note This is equivalent to fd->setCS(false) immediately followed by fd->setCS(true).
+ */
+INLINE void CS_TOGGLE(KFileDataflash *fd)
+{
+ fd->setCS(false);
+ fd->setCS(true);
+}
+
+/**
+ * Send a generic command to dataflash memory.
+ * This function send only 4 byte: opcode, page address and
+ * byte address.
+ */
+static void send_cmd(KFileDataflash *fd, dataflash_page_t page_addr, dataflash_offset_t byte_addr, DataFlashOpcode opcode)
+{
+
+ /*
+ * Make sure to toggle CS signal in order,
+ * and reset dataflash command decoder.
+ */
+ CS_TOGGLE(fd);
+
+
+ /*
+ * To send one command to data flash memory, we send 4 byte.
+ * First byte is opcode command, second and third byte are
+ * page address, in last byte we write a byte page address.
+ * (see datasheet for more detail).
+ *
+ * \note Generaly a defaul memory page size is more than 256 byte.
+ * In this case we need for addressing a byte in one page more than
+ * 8 bit, so we put in fourth byte low part of address byte, and
+ * hight part of address byte in third byte togheter low par of page
+ * address.
+ *
+ */
+
+ /*
+ * Send opcode.
+ */
+ kfile_putc(opcode, fd->channel);
+
+ /*
+ * Send page address.
+ */
+ kfile_putc((uint8_t)(page_addr >> (16 - mem_info[fd->dev].page_bits)), fd->channel);
+ kfile_putc((uint8_t)((page_addr << (mem_info[fd->dev].page_bits - 8)) + (byte_addr >> 8)), fd->channel);
+
+ /*
+ * Send byte page address.
+ */
+ kfile_putc((uint8_t)byte_addr, fd->channel);
+}
+
+/**
+ * Reset dataflash memory function.
+ *
+ * If \a fd->setReset function is not NULL,
+ * this function resets data flash memory
+ * with one pulse reset long about 10usec.
+ *
+ */
+static void dataflash_reset(KFileDataflash *fd)
+{
+ fd->setCS(false);
+
+ if (fd->setReset)
+ {
+ fd->setReset(true);
+ timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH));
+ fd->setReset(false);
+ timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH));
+ }
+}
+
+
+/**
+ * Read status register of dataflah memory.
+ */
+static uint8_t dataflash_stat(KFileDataflash *fd)
+{
+ /*
+ * Make sure to toggle CS signal
+ * and reset dataflash command decoder.
+ */
+ CS_TOGGLE(fd);
+
+ kfile_putc(DFO_READ_STATUS, fd->channel);
+
+ return kfile_getc(fd->channel);
+}
+
+
+/**
+ * Send one command to data flash memory, and
+ * return status register value.
+ *
+ */
+static uint8_t dataflash_cmd(KFileDataflash *fd, dataflash_page_t page_addr, dataflash_offset_t byte_addr, DataFlashOpcode opcode)
+{
+ uint8_t stat;
+
+ send_cmd(fd, page_addr, byte_addr, opcode);
+
+ CS_TOGGLE(fd);
+
+ /*
+ * We chech data flash memory state, and wait until busy-flag
+ * is high.
+ */
+ while (!(dataflash_stat(fd) & BUSY_BIT))
+ {
+ #if CONFIG_KERNEL
+ proc_switch();
+ #endif
+ }
+
+ stat = dataflash_stat(fd);
+
+ kfile_flush(fd->channel); // Flush channel
+ /*
+ * Data flash has completed a bus cycle, so disable CS.
+ */
+ fd->setCS(false);
+
+ return stat;
+}
+
+/**
+ * Read \a len bytes from main data flash memory or buffer data
+ * flash memory, and put it in \a *block.
+ */
+static void dataflash_readBlock(KFileDataflash *fd, dataflash_page_t page_addr, dataflash_offset_t byte_addr, DataFlashOpcode opcode, uint8_t *block, dataflash_size_t len)
+{
+ send_cmd(fd, page_addr, byte_addr, opcode);
+
+ if (opcode == DFO_READ_FLASH_MEM_BYTE_B)
+ {
+ /*
+ * Send 24 don't care bits.
+ */
+ uint8_t dummy[] = { 0, 0, 0 };
+ kfile_write(fd->channel, dummy, sizeof(dummy));
+ }
+
+ kfile_putc(0, fd->channel); //Send 8 don't care bit.
+ kfile_read(fd->channel, block, len); //Read len bytes ad put in block buffer.
+ kfile_flush(fd->channel); // Flush channel
+ fd->setCS(false);
+}
+
+
+/**
+ * Write \a len bytes in dataflash memory buffer.
+ *
+ * \note Is not possible to write directly in dataflash main memory.
+ * To perform a write in main memory you must first write in dataflash buffer
+ * memory and then send a command to write the page in main memory.
+ */
+static void dataflash_writeBlock(KFileDataflash *fd, dataflash_offset_t offset, DataFlashOpcode opcode, const uint8_t *block, dataflash_size_t len)
+{
+ ASSERT(offset + len <= mem_info[fd->dev].page_size);
+
+ send_cmd(fd, 0x00, offset, opcode);
+
+ kfile_write(fd->channel, block, len); //Write len bytes.
+ kfile_flush(fd->channel); // Flush channel
+
+ fd->setCS(false);
+}
+
+
+/**
+ * Load selct page from dataflash memory to buffer.
+ */
+static void dataflash_loadPage(KFileDataflash *fd, dataflash_page_t page_addr)
+{
+ dataflash_cmd(fd, page_addr, 0x00, DFO_MOV_MEM_TO_BUFF1);
+}
+
+/**
+ * Flush select page (stored in buffer) in data flash main memory page.
+ */
+static int dataflash_flush(KFile *_fd)
+{
+ KFileDataflash *fd = KFILEDATAFLASH(_fd);
+ if (fd->page_dirty)
+ {
+ dataflash_cmd(fd, fd->current_page, 0x00, DFO_WRITE_BUFF1_TO_MEM_E);
+
+ fd->page_dirty = false;
+
+ kprintf("Flushing page <%ld>\n", fd->current_page);
+ }
+ return 0;
+}
+
+/* Kfile interface section */
+
+/**
+ * Close file \a fd.
+ */
+static int dataflash_close(struct KFile *_fd)
+{
+ dataflash_flush(_fd);
+ TRACE;
+ return 0;
+}
+
+/**
+ * Reopen dataflash file \a fd.
+ */
+static KFile *dataflash_reopen(KFile *_fd)
+{
+ KFileDataflash *fd = KFILEDATAFLASH(_fd);
+ dataflash_close(_fd);
+
+ fd->current_page = 0;
+ fd->fd.seek_pos = 0;
+
+ /* Load selected page from dataflash memory */
+ dataflash_loadPage(fd, fd->current_page);
+
+ TRACE;
+ return &fd->fd;
+}
+
+
+/**
+ * Read in \a buf \a size bytes from dataflash memmory.
+ *
+ * \note For reading data flash memory, we
+ * check flag page_dirty, if is true (that mean
+ * we have written a byte in buffer memory) we
+ * flush current page in main memory and
+ * then read from memory, else we read byte
+ * directly from data flash main memory.
+ *
+ * \return the number of bytes read.
+ */
+static size_t dataflash_read(struct KFile *_fd, void *buf, size_t size)
+{
+ KFileDataflash *fd = KFILEDATAFLASH(_fd);
+
+ dataflash_offset_t byte_addr;
+ dataflash_page_t page_addr;
+ uint8_t *data = (uint8_t *)buf;
+
+
+ ASSERT(fd->fd.seek_pos + size <= fd->fd.size);
+ size = MIN((uint32_t)size, fd->fd.size - fd->fd.seek_pos);
+
+ kprintf("Reading at pos[%lu]\n", fd->fd.seek_pos);
+
+ /*
+ * We select page and offest from absolute address.
+ */
+ page_addr = fd->fd.seek_pos / mem_info[fd->dev].page_size;
+ byte_addr = fd->fd.seek_pos % mem_info[fd->dev].page_size;
+
+ kprintf("[page-<%ld>, byte-<%ld>]", page_addr, byte_addr);
+
+ /*
+ * Flush current page in main memory if
+ * we had been written a byte in memory
+ */
+ dataflash_flush(&fd->fd);
+
+ /*
+ * Read byte in main page data flash memory.
+ */
+ dataflash_readBlock(fd, page_addr, byte_addr, mem_info[fd->dev].read_cmd, data, size);
+
+ fd->fd.seek_pos += size;
+ kprintf("Read %ld bytes\n", size);
+
+ return size;
+}
+
+/**
+ * Write \a _buf in dataflash memory
+ *
+ * \note For writing \a _buf in dataflash memory, we must
+ * first write in buffer data flash memory. At the end of write,
+ * we can put page in dataflash main memory.
+ * If we write in two contiguous pages, we put in main memory current
+ * page and then reload the page which we want to write.
+ *
+ * \return the number of bytes write.
+ */
+static size_t dataflash_write(struct KFile *_fd, const void *_buf, size_t size)
+{
+ KFileDataflash *fd = KFILEDATAFLASH(_fd);
+
+ dataflash_offset_t offset;
+ dataflash_page_t new_page;
+ size_t total_write = 0;
+
+ const uint8_t *data = (const uint8_t *) _buf;
+
+ ASSERT(fd->fd.seek_pos + size <= fd->fd.size);
+ size = MIN((uint32_t)size, fd->fd.size - fd->fd.seek_pos);
+
+ kprintf("Writing at pos[%lu]\n", fd->fd.seek_pos);
+
+ while (size)
+ {
+ /*
+ * We select page and offest from absolute address.
+ */
+ new_page = fd->fd.seek_pos / mem_info[fd->dev].page_size;
+ offset = fd->fd.seek_pos % mem_info[fd->dev].page_size;
+
+
+ size_t wr_len = MIN(size, mem_info[fd->dev].page_size - offset);
+
+ kprintf(" [page-<%ld>, byte-<%ld>]",new_page, offset);
+
+ if (new_page != fd->current_page)
+ {
+ /* Flush current page in main memory*/
+ dataflash_flush(&fd->fd);
+ /* Load select page memory from data flash memory*/
+ dataflash_loadPage(fd, new_page);
+
+ fd->current_page = new_page;
+ kprintf(" >> Load page: <%ld> ", new_page);
+ }
+ /*
+ * Write byte in current page, and set true
+ * page_dirty flag.
+ */
+ dataflash_writeBlock(fd, offset, DFO_WRITE_BUFF1, data, wr_len);
+ fd->page_dirty = true;
+
+ data += wr_len;
+ fd->fd.seek_pos += wr_len;
+ size -= wr_len;
+ total_write += wr_len;
+ }
+
+ kprintf("written %lu bytes\n", total_write);
+ return total_write;
+}
+
+MOD_DEFINE(dataflash);
+
+/**
+ * Dataflash init function.
+ * This function initialize \a fd with SPI channel \a ch and test if data flash memory
+ * density is the same specified by device \a dev.
+ * \a setCS is a callback used to set/reset CS line.
+ * \a setReset is a callback used to set/reset the dataflash (can be NULL if reset is unconnected)
+ * \return true if ok, false if memory density read from dataflash is not compliant with the
+ * configured one.
+ */
+bool dataflash_init(KFileDataflash *fd, KFile *ch, DataflashType dev, dataflash_setCS_t *setCS, dataflash_setReset_t *setReset)
+{
+ uint8_t stat;
+
+ MOD_CHECK(dataflash_hw);
+
+ ASSERT(fd);
+ ASSERT(ch);
+ ASSERT(setCS);
+ ASSERT(dev < DFT_CNT);
+
+ memset(fd, 0, sizeof(*fd));
+ DB(fd->fd._type = KFT_DATAFLASH);
+ fd->dev = dev;
+ fd->channel = ch;
+ fd->setReset = setReset;
+ fd->setCS = setCS;
+
+ // Setup data flash programming functions.
+ fd->fd.reopen = dataflash_reopen;
+ fd->fd.close = dataflash_close;
+ fd->fd.read = dataflash_read;
+ fd->fd.write = dataflash_write;
+ fd->fd.seek = kfile_genericSeek;
+ fd->fd.flush = dataflash_flush;
+
+ dataflash_reset(fd);
+
+ stat = dataflash_stat(fd);
+
+ /*
+ * 2,3,4,5 bits of 1 byte status register
+ * indicate a device density of dataflash memory
+ * (see datasheet for more detail.)
+ */
+ if (GET_ID_DESITY_DEVICE(stat) != mem_info[fd->dev].density_id)
+ return false;
+
+ fd->current_page = 0;
+ fd->fd.seek_pos = 0;
+ fd->fd.size = mem_info[fd->dev].page_size * mem_info[fd->dev].page_cnt;
+
+ /* Load selected page from dataflash memory */
+ dataflash_loadPage(fd, fd->current_page);
+ MOD_INIT(dataflash);
+ return true;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Function library for AT45DB081D Flash memory.
+ *
+ *
+ * \version $Id: dataflash.h 20677 2008-02-19 14:29:52Z batt $
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+
+#ifndef DRV_DATAFLASH_H
+#define DRV_DATAFLASH_H
+
+#include <kern/kfile.h>
+#include <cfg/compiler.h>
+
+#include <appconfig.h>
+
+
+/**
+ * Type definitions for dflash memory.
+ * \{
+ */
+typedef uint32_t dataflash_page_t;
+typedef uint32_t dataflash_offset_t;
+typedef uint32_t dataflash_size_t;
+/*\}*/
+
+/**
+ *
+ */
+typedef void (dataflash_setReset_t)(bool);
+typedef void (dataflash_setCS_t)(bool);
+
+/**
+ * Memory definitions.
+ *
+ * List of supported memory devices by this drive.
+ * Every time we call dataflash_init() we check device id to
+ * ensure we choose the right memory configuration.
+ * (see dataflash.c for more details).
+ */
+typedef enum DataflashType
+{
+ DFT_AT45DB041B,
+ DFT_AT45DB081D,
+ DFT_AT45DB161D,
+ DFT_CNT
+} DataflashType;
+
+
+/**
+ * Dataflash KFile context structure.
+ */
+typedef struct KFileDataflash
+{
+ KFile fd; ///< File descriptor.
+ KFile *channel; ///< Dataflash comm channel (usually SPI).
+ DataflashType dev; ///< Memory device type;
+ dataflash_page_t current_page; ///< Current loaded dataflash page.
+ bool page_dirty; ///< True if current_page is dirty (needs to be flushed).
+ dataflash_setReset_t *setReset; ///< Callback used to set reset pin of dataflash.
+ dataflash_setCS_t *setCS; ///< Callback used to set CS pin of dataflash.
+} KFileDataflash;
+
+/**
+ * ID for dataflash.
+ */
+#define KFT_DATAFLASH MAKE_ID('D', 'F', 'L', 'H')
+
+/**
+ * Convert + ASSERT from generic KFile to KFileDataflash.
+ */
+INLINE KFileDataflash * KFILEDATAFLASH(KFile *fd)
+{
+ ASSERT(fd->_type == KFT_DATAFLASH);
+ return (KFileDataflash *)fd;
+}
+
+#define RESET_PULSE_WIDTH 10 ///< Width of reset pulse in usec.
+#define BUSY_BIT 0x80 ///< Select a busy bit in status register.
+#define CMP_BIT 0x40 ///< Select a compare bit in status register.
+
+/**
+ * Select bits 2-5 of status register. These
+ * bits indicate device density (see datasheet for
+ * more details).
+ */
+#define GET_ID_DESITY_DEVICE(reg_stat) (((reg_stat) & 0x3C) >> 2)
+
+/**
+ * Data flash opcode commands.
+ */
+typedef enum DataFlashOpcode {
+ /**
+ * Dataflash read commands.
+ * \{
+ */
+ DFO_READ_FLASH_MEM_BYTE_D = 0x0B, ///< Continuos array read for D type memories.
+ DFO_READ_FLASH_MEM_BYTE_B = 0xE8, ///< Continuos array read for B type memories.
+
+ DFO_READ_FLASH_MEM = 0xD2, ///< Main memory page read.
+ DFO_READ_BUFF1 = 0xD4, ///< SRAM buffer 1 read.
+ DFO_READ_BUFF2 = 0xD6, ///< SRAM buffer 2 read.
+ /* \}*/
+
+ /**
+ * Program and erase commands data flash.
+ * \{
+ */
+ DFO_WRITE_BUFF1 = 0x84, ///< SRAM buffer 1 write.
+ DFO_WRITE_BUFF2 = 0x87, ///< SRAM buffer 2 write.
+ DFO_WRITE_BUFF1_TO_MEM_E = 0x83, ///< Buffer 1 to main memory page program with built-in erase.
+ DFO_WRITE_BUFF2_TO_MEM_E = 0x86, ///< Buffer 2 to main memory page program with built-in erase.
+ DFO_WRITE_BUFF1_TO_MEM = 0x88, ///< Buffer 1 to main memory page program without built-in erase.
+ DFO_WRITE_BUFF2_TO_MEM = 0x89, ///< Buffer 2 to main memory page program without built-in erase.
+ DFO_ERASE_PAGE = 0x81, ///< Erase page.
+ DFO_ERASE_BLOCK = 0x50, ///< Erase block.
+ DFO_ERASE_SECTOR = 0x7C, ///< Erase sector.
+ DFO_WRITE_MEM_TR_BUFF1 = 0x82, ///< Write main memory page through buffer 1.
+ DFO_WRITE_MEM_TR_BUFF2 = 0x85, ///< Write main memory page through buffer 2.
+ /* \}*/
+
+ /**
+ * Additional dataflash commands.
+ * \{
+ */
+ DFO_MOV_MEM_TO_BUFF1 = 0x53, ///< Transfer main mmemory to buffer 1.
+ DFO_MOV_MEM_TO_BUFF2 = 0x55, ///< Transfer main mmemory to buffer 2.
+ DFO_CMP_MEM_TO_BUFF1 = 0x60, ///< Compare main mmemory with buffer 1.
+ DFO_CMP_MEM_TO_BUFF2 = 0x61, ///< Compare main mmemory with buffer 2.
+ DFO_ARW_MEM_TR_BUFF1 = 0x58, ///< Auto page rewrite through buffer 1.
+ DFO_ARW_MEM_TR_BUFF2 = 0x59, ///< Auto page rewrite through buffer 2
+ DFO_PWR_DOWN = 0xB9, ///< Deep power-down.
+ DFO_RESUME_PWR_DOWN = 0xAB, ///< Resume from deep power-down.
+ DFO_READ_STATUS = 0xD7, ///< Read status register.
+ DFO_ID_DEV = 0x9F ///< Read manufacturer and device ID.
+ /* \}*/
+} DataFlashOpcode;
+
+
+/**
+ * Structure used to describe a dataflash memory.
+ */
+typedef struct DataflashInfo
+{
+ uint8_t density_id; ///< Density id, used to check memory type.
+ dataflash_size_t page_size; ///< Page size, in bytes.
+ uint8_t page_bits; ///< Number of bits needed to access a page.
+ uint16_t page_cnt; ///< Number of pages on memory.
+ DataFlashOpcode read_cmd; ///< Command to be used to perform a continuous array.
+} DataflashInfo;
+
+
+bool dataflash_init(KFileDataflash *fd, KFile *ch, DataflashType type, dataflash_setCS_t *setCS, dataflash_setReset_t *setReset);
+
+#endif /* DRV_DATAFLASH_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Driver for the 24xx16 and 24xx256 I2C EEPROMS (implementation)
+ *
+ * \note This implementation is AVR specific.
+ *
+ * \version $Id$
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "eeprom.h"
+
+#include <cfg/debug.h>
+#include <appconfig.h> // CONFIG_EEPROM_VERIFY
+#include <cfg/macros.h> // MIN()
+#include <cpu/attr.h>
+#include CPU_HEADER(twi)
+#include <drv/wdt.h>
+#include <mware/byteorder.h> // cpu_to_be16()
+
+#include <string.h> // memset()
+
+
+// Configuration sanity checks
+#if !defined(CONFIG_EEPROM_VERIFY) || (CONFIG_EEPROM_VERIFY != 0 && CONFIG_EEPROM_VERIFY != 1)
+ #error CONFIG_EEPROM_VERIFY must be defined to either 0 or 1
+#endif
+
+/**
+ * EEPROM ID code
+ */
+#define EEPROM_ID 0xA0
+
+/**
+ * This macros form the correct slave address for EEPROMs
+ */
+#define EEPROM_ADDR(x) (EEPROM_ID | (((uint8_t)(x)) << 1))
+
+
+
+
+/**
+ * Copy \c count bytes from buffer \c buf to
+ * eeprom at address \c addr.
+ */
+static bool eeprom_writeRaw(e2addr_t addr, const void *buf, size_t count)
+{
+ bool result = true;
+ ASSERT(addr + count <= EEPROM_SIZE);
+
+ while (count && result)
+ {
+ /*
+ * Split write in multiple sequential mode operations that
+ * don't cross page boundaries.
+ */
+ size_t size =
+ MIN(count, (size_t)(EEPROM_BLKSIZE - (addr & (EEPROM_BLKSIZE - 1))));
+
+ #if CONFIG_EEPROM_TYPE == EEPROM_24XX16
+ /*
+ * The 24LC16 uses the slave address as a 3-bit
+ * block address.
+ */
+ uint8_t blk_addr = (uint8_t)((addr >> 8) & 0x07);
+ uint8_t blk_offs = (uint8_t)addr;
+
+ result =
+ twi_start_w(EEPROM_ADDR(blk_addr))
+ && twi_send(&blk_offs, sizeof blk_offs)
+ && twi_send(buf, size);
+
+ #elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
+
+ // 24LC256 wants big-endian addresses
+ uint16_t addr_be = cpu_to_be16(addr);
+
+ result =
+ twi_start_w(EEPROM_ID)
+ && twi_send((uint8_t *)&addr_be, sizeof addr_be)
+ && twi_send(buf, size);
+
+ #else
+ #error Unknown device type
+ #endif
+
+ twi_stop();
+
+ // DEBUG
+ //kprintf("addr=%d, count=%d, size=%d, *#?=%d\n",
+ // addr, count, size,
+ // (EEPROM_BLKSIZE - (addr & (EEPROM_BLKSIZE - 1)))
+ //);
+
+ /* Update count and addr for next operation */
+ count -= size;
+ addr += size;
+ buf = ((const char *)buf) + size;
+ }
+
+ if (!result)
+ TRACEMSG("Write error!");
+ return result;
+}
+
+
+#if CONFIG_EEPROM_VERIFY
+/**
+ * Check that the contents of an EEPROM range
+ * match with a provided data buffer.
+ *
+ * \return true on success.
+ */
+static bool eeprom_verify(e2addr_t addr, const void *buf, size_t count)
+{
+ uint8_t verify_buf[16];
+ bool result = true;
+
+ while (count && result)
+ {
+ /* Split read in smaller pieces */
+ size_t size = MIN(count, sizeof verify_buf);
+
+ /* Read back buffer */
+ if (eeprom_read(addr, verify_buf, size))
+ {
+ if (memcmp(buf, verify_buf, size) != 0)
+ {
+ TRACEMSG("Data mismatch!");
+ result = false;
+ }
+ }
+ else
+ {
+ TRACEMSG("Read error!");
+ result = false;
+ }
+
+ /* Update count and addr for next operation */
+ count -= size;
+ addr += size;
+ buf = ((const char *)buf) + size;
+ }
+
+ return result;
+}
+#endif /* CONFIG_EEPROM_VERIFY */
+
+
+bool eeprom_write(e2addr_t addr, const void *buf, size_t count)
+{
+#if CONFIG_EEPROM_VERIFY
+ int retries = 5;
+
+ while (retries--)
+ if (eeprom_writeRaw(addr, buf, count)
+ && eeprom_verify(addr, buf, count))
+ return true;
+
+ return false;
+
+#else /* !CONFIG_EEPROM_VERIFY */
+ return eeprom_writeRaw(addr, buf, count);
+#endif /* !CONFIG_EEPROM_VERIFY */
+}
+
+
+/**
+ * Copy \c count bytes at address \c addr
+ * from eeprom to RAM to buffer \c buf.
+ *
+ * \return true on success.
+ */
+bool eeprom_read(e2addr_t addr, void *buf, size_t count)
+{
+ ASSERT(addr + count <= EEPROM_SIZE);
+
+#if CONFIG_EEPROM_TYPE == EEPROM_24XX16
+ /*
+ * The 24LC16 uses the slave address as a 3-bit
+ * block address.
+ */
+ uint8_t blk_addr = (uint8_t)((addr >> 8) & 0x07);
+ uint8_t blk_offs = (uint8_t)addr;
+
+ bool res =
+ twi_start_w(EEPROM_ADDR(blk_addr))
+ && twi_send(&blk_offs, sizeof blk_offs)
+ && twi_start_r(EEPROM_ADDR(blk_addr))
+ && twi_recv(buf, count);
+
+#elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
+
+ // 24LC256 wants big-endian addresses
+ addr = cpu_to_be16(addr);
+
+ bool res =
+ twi_start_w(EEPROM_ID)
+ && twi_send((uint8_t *)&addr, sizeof(addr))
+ && twi_start_r(EEPROM_ID)
+ && twi_recv(buf, count);
+#else
+ #error Unknown device type
+#endif
+
+ twi_stop();
+
+ if (!res)
+ TRACEMSG("Read error!");
+ return res;
+}
+
+
+/**
+ * Write a single character \a c at address \a addr.
+ */
+bool eeprom_write_char(e2addr_t addr, char c)
+{
+ return eeprom_write(addr, &c, 1);
+}
+
+
+/**
+ * Read a single character at address \a addr.
+ *
+ * \return the requested character or -1 in case of failure.
+ */
+int eeprom_read_char(e2addr_t addr)
+{
+ char c;
+
+ if (eeprom_read(addr, &c, 1))
+ return c;
+ else
+ return -1;
+}
+
+
+/**
+ * Erase specified part of eeprom, writing 0xFF.
+ *
+ * \param addr starting address
+ * \param count length of block to erase
+ */
+void eeprom_erase(e2addr_t addr, size_t count)
+{
+ uint8_t buf[EEPROM_BLKSIZE];
+ memset(buf, 0xFF, sizeof buf);
+
+ // Clear all but struct hw_info at start of eeprom
+ while (count)
+ {
+ // Long operation, reset watchdog
+ wdt_reset();
+
+ size_t size = MIN(count, sizeof buf);
+ eeprom_write(addr, buf, size);
+ addr += size;
+ count -= size;
+ }
+}
+
+
+/**
+ * Initialize TWI module.
+ */
+void eeprom_init(void)
+{
+ twi_init();
+}
+
+
+#ifdef _DEBUG
+
+#include <string.h>
+
+void eeprom_test(void)
+{
+ static const char magic[14] = "Humpty Dumpty";
+ char buf[sizeof magic];
+ size_t i;
+
+ // Write something to EEPROM using unaligned sequential writes
+ for (i = 0; i < 42; ++i)
+ {
+ wdt_reset();
+ eeprom_write(i * sizeof magic, magic, sizeof magic);
+ }
+
+ // Read back with single-byte reads
+ for (i = 0; i < 42 * sizeof magic; ++i)
+ {
+ wdt_reset();
+ eeprom_read(i, buf, 1);
+ kprintf("EEPROM byte read: %c (%d)\n", buf[0], buf[0]);
+ ASSERT(buf[0] == magic[i % sizeof magic]);
+ }
+
+ // Read back again using sequential reads
+ for (i = 0; i < 42; ++i)
+ {
+ wdt_reset();
+ memset(buf, 0, sizeof buf);
+ eeprom_read(i * sizeof magic, buf, sizeof magic);
+ kprintf("EEPROM seq read @ 0x%x: '%s'\n", i * sizeof magic, buf);
+ ASSERT(memcmp(buf, magic, sizeof magic) == 0);
+ }
+}
+
+#endif // _DEBUG
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Driver for the 24xx16 and 24xx256 I2C EEPROMS (interface)
+ */
+
+#ifndef DRV_EEPROM_H
+#define DRV_EEPROM_H
+
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+/**
+ * \name Values for CONFIG_EEPROM_TYPE
+ * \{
+ */
+#define EEPROM_24XX16 1
+#define EEPROM_24XX256 2
+/*\}*/
+
+#if CONFIG_EEPROM_TYPE == EEPROM_24XX16
+ #define EEPROM_BLKSIZE 0x10 ///< Eeprom block size (16byte)
+ #define EEPROM_SIZE 0x800 ///< Eeprom total size (2kB)
+#elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
+ #define EEPROM_BLKSIZE 0x40 ///< Eeprom block size (64byte)
+ #define EEPROM_SIZE 0x8000 ///< Eeprom total size (32kB)
+#else
+ #error Unsupported EEPROM type.
+#endif
+
+/// Type for EEPROM addresses
+typedef uint16_t e2addr_t;
+
+/**
+ * Macro for E2Layout offset calculation
+ *
+ * \note We can't just use offsetof() here because we could use
+ * non-constant expressions to access array elements.
+ *
+ * \note 'type' is the structure type holding eeprom layout
+ * and must be defined in user files.
+ */
+#define e2addr(type, field) ((e2addr_t)&(((type *)0)->field))
+
+
+bool eeprom_write(e2addr_t addr, const void *buf, size_t count);
+bool eeprom_read(e2addr_t addr, void *buf, size_t count);
+bool eeprom_write_char(e2addr_t addr, char c);
+int eeprom_read_char(e2addr_t addr);
+void eeprom_erase(e2addr_t addr, size_t count);
+void eeprom_init(void);
+void eeprom_test(void);
+
+#endif /* DRV_EEPROM_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Function library for serial Flash memory.
+ *
+ * Module provide a kfile interface, that ensure an abstraction
+ * from comunication channel and give a standard interface.
+ * Typicaly this kind of memory use an SPI bus, but you should
+ * use another comunication channel you have defined.
+ *
+ * \version $Id$
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+#include <avr/io.h>
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+#include <drv/timer.h>
+#include <drv/flash25.h>
+
+#if CONFIG_KERNEL
+#include <kern/proc.h>
+#endif
+
+/*
+ * We use a spi bus, thus include hardware specific definition.
+ * If you use another channel you must redefine this macros.
+ */
+#include "hw_spi.h"
+
+#include <appconfig.h>
+
+/**
+ * Global definition of channel handler (usually SPI).
+ */
+static KFile *channel;
+
+/**
+ * Wait until flash memory is ready.
+ */
+static void flash25_waitReady(void)
+{
+ uint8_t stat;
+
+ while (1)
+ {
+ CS_ENABLE();
+
+ kfile_putc(FLASH25_RDSR, channel);
+ stat = kfile_getc(channel);
+
+ CS_DISABLE();
+
+ if (!(stat & RDY_BIT))
+ break;
+ #if CONFIG_KERNEL
+ else
+ proc_switch();
+ #endif
+ }
+}
+
+/**
+ * Send a single command to serial flash memory.
+ */
+static void flash25_sendCmd(Flash25Opcode cmd)
+{
+ CS_ENABLE();
+
+ kfile_putc(cmd, channel);
+
+ CS_DISABLE();
+}
+
+/**
+ * flash25 init function.
+ * This function init a comunication channel and
+ * try to read manufacturer id of serial memory,
+ * then check if is equal to selected type.
+ */
+static bool flash25_pin_init(void)
+{
+ uint8_t device_id;
+ uint8_t manufacturer;
+
+ SPI_HW_INIT();
+
+ CS_ENABLE();
+ /*
+ * Send read id productor opcode on
+ * comunication channel
+ * TODO:controllare se ha senso
+ */
+ kfile_putc(FLASH25_RDID, channel);
+
+ manufacturer = kfile_getc(channel);
+ device_id = kfile_getc(channel);
+
+ CS_DISABLE();
+
+ if((FLASH25_MANUFACTURER_ID == manufacturer) &&
+ (FLASH25_DEVICE_ID == device_id))
+ return true;
+ else
+ return false;
+}
+
+/**
+ * Reopen a serial memory interface.
+ *
+ * For serial memory this function reinit only
+ * the size and seek_pos in kfile stucture.
+ * Return a kfile pointer, after assert check.
+ */
+static KFile * flash25_reopen(struct KFile *fd)
+{
+ KFILE_ASSERT_GENERIC(fd);
+
+ fd->seek_pos = 0;
+ fd->size = FLASH25_MEM_SIZE;
+
+ kprintf("flash25 file opened\n");
+ return fd;
+}
+
+/**
+ * Close a serial memory interface.
+ *
+ * For serial memory this funtion do nothing,
+ * and return always 0.
+ */
+static int flash25_close(UNUSED_ARG(struct KFile *,fd))
+{
+ kprintf("flash25 file closed\n");
+ return 0;
+}
+
+/**
+ * Read \a _buf lenght \a size byte from serial flash memmory.
+ *
+ * For read in serial flash memory we
+ * enble cs pin and send one byte of read opcode,
+ * and then 3 byte of address of memory cell we
+ * want to read. After the last byte of address we
+ * can read data from so pin.
+ *
+ * \return the number of bytes read.
+ */
+static size_t flash25_read(struct KFile *fd, void *buf, size_t size)
+{
+ uint8_t *data = (uint8_t *)buf;
+
+ KFILE_ASSERT_GENERIC(fd);
+
+ ASSERT(fd->seek_pos + size <= fd->size);
+ size = MIN((uint32_t)size, fd->size - fd->seek_pos);
+
+ //kprintf("Reading at addr[%lu], size[%d]\n", fd->seek_pos, size);
+ CS_ENABLE();
+
+ kfile_putc(FLASH25_READ, channel);
+
+
+ /*
+ * Address that we want to read.
+ */
+ kfile_putc((fd->seek_pos >> 16) & 0xFF, channel);
+ kfile_putc((fd->seek_pos >> 8) & 0xFF, channel);
+ kfile_putc(fd->seek_pos & 0xFF, channel);
+
+ kfile_read(channel, data, size);
+
+ CS_DISABLE();
+
+ fd->seek_pos += size;
+
+ return size;
+}
+
+/**
+ * Write \a _buf in serial flash memory
+ *
+ * Before to write data into flash we must enable
+ * memory writing. To do this we send a WRE command opcode.
+ * After this command the flash is ready to be write, and so
+ * we send a PROGRAM opcode followed to 3 byte of
+ * address memory, at the end of last address byte
+ * we can send the data.
+ * When we finish to send all data, we disable cs
+ * and flash write received data bytes on its memory.
+ *
+ * \note: WARNING: you could write only on erased memory section!
+ * Each write time you could write max a memory page size,
+ * because if you write more than memory page size the
+ * address roll over to first byte of page.
+ *
+ * \return the number of bytes write.
+ */
+static size_t flash25_write(struct KFile *fd, const void *_buf, size_t size)
+{
+ flash25Offset_t offset;
+ flash25Size_t total_write = 0;
+ flash25Size_t wr_len;
+ const uint8_t *data = (const uint8_t *) _buf;
+
+ KFILE_ASSERT_GENERIC(fd);
+ ASSERT(fd->seek_pos + size <= fd->size);
+
+ size = MIN((flash25Size_t)size, fd->size - fd->seek_pos);
+
+ while (size)
+ {
+ offset = fd->seek_pos % (flash25Size_t)FLASH25_PAGE_SIZE;
+ wr_len = MIN((flash25Size_t)size, FLASH25_PAGE_SIZE - (flash25Size_t)offset);
+
+ kprintf("[seek_pos-<%lu>, offset-<%d>]\n", fd->seek_pos, offset);
+
+ /*
+ * We check serial flash memory state, and wait until ready-flag
+ * is high.
+ */
+ flash25_waitReady();
+
+ /*
+ * Start write cycle.
+ * We could write only data not more long than one
+ * page size.
+ *
+ * To write on serial flash memory we must first
+ * enable write with a WREN opcode command, before
+ * the PROGRAM opcode.
+ *
+ * \note: the same byte cannot be reprogrammed without
+ * erasing the whole sector first.
+ */
+ flash25_sendCmd(FLASH25_WREN);
+
+ CS_ENABLE();
+ kfile_putc(FLASH25_PROGRAM, channel);
+
+ /*
+ * Address that we want to write.
+ */
+ kfile_putc((fd->seek_pos >> 16) & 0xFF, channel);
+ kfile_putc((fd->seek_pos >> 8) & 0xFF, channel);
+ kfile_putc(fd->seek_pos & 0xFF, channel);
+
+ kfile_write(channel, data, wr_len);
+
+ CS_DISABLE();
+
+ data += wr_len;
+ fd->seek_pos += wr_len;
+ size -= wr_len;
+ total_write += wr_len;
+ }
+
+ kprintf("written %u bytes\n", total_write);
+ return total_write;
+}
+
+/**
+ * Sector erase function.
+ *
+ * Erase a select \p sector of serial flash memory.
+ *
+ * \note A sector size is FLASH25_SECTOR_SIZE.
+ * This operation could take a while.
+ */
+void flash25_sectorErase(Flash25Sector sector)
+{
+
+ /*
+ * Erase a sector could take a while,
+ * for debug we measure that time
+ * see datasheet to compare this time.
+ */
+ DB(ticks_t start_time = timer_clock());
+
+ CS_ENABLE();
+
+ /*
+ * To erase a sector of serial flash memory we must first
+ * enable write with a WREN opcode command, before
+ * the SECTOR_ERASE opcode. Sector is automatically
+ * determinate if any address within the sector
+ * is selected.
+ */
+ kfile_putc(FLASH25_WREN, channel);
+ kfile_putc(FLASH25_SECTORE_ERASE, channel);
+
+ /*
+ * Address inside the sector that we want to
+ * erase.
+ */
+ kfile_putc(sector, channel);
+
+ CS_DISABLE();
+
+ /*
+ * We check serial flash memory state, and wait until ready-flag
+ * is hight.
+ */
+ flash25_waitReady();
+
+ DB(kprintf("Erased sector [%d] in %d ms\n", sector, ticks_to_ms(timer_clock() - start_time)));
+
+}
+
+/**
+ * Chip erase function.
+ *
+ * Erase all sector of serial flash memory.
+ *
+ * \note This operation could take a while.
+ */
+void flash25_chipErase(void)
+{
+ /*
+ * Erase all chip could take a while,
+ * for debug we measure that time
+ * see datasheet to compare this time.
+ */
+ DB(ticks_t start_time = timer_clock());
+
+ /*
+ * To erase serial flash memory we must first
+ * enable write with a WREN opcode command, before
+ * the CHIP_ERASE opcode.
+ */
+ flash25_sendCmd(FLASH25_WREN);
+ flash25_sendCmd(FLASH25_CHIP_ERASE);
+
+ /*
+ * We check serial flash memory state, and wait until ready-flag
+ * is high.
+ */
+ flash25_waitReady();
+
+ DB(kprintf("Erased all memory in %d ms\n", ticks_to_ms(timer_clock() - start_time)));
+
+}
+
+/**
+ * Init data flash memory interface.
+ */
+void flash25_init(struct KFile *fd, struct KFile *_channel)
+{
+ //Set kfile struct type as a generic kfile structure.
+ DB(fd->_type = KFT_GENERIC);
+
+ // Set up data flash programming functions.
+ fd->reopen = flash25_reopen;
+ fd->close = flash25_close;
+ fd->read = flash25_read;
+ fd->write = flash25_write;
+ fd->seek = kfile_genericSeek;
+
+ /*
+ * Init a local channel structure and flash kfile interface.
+ */
+ channel = _channel;
+ flash25_reopen(fd);
+
+ /*
+ * Init data flash memory and micro pin.
+ */
+ if (!flash25_pin_init())
+ ASSERT(0);
+}
+
+#if CONFIG_TEST
+
+/**
+ * Test function for flash25.
+ *
+ * \note: This implentation use a SPI channel.
+ */
+bool flash25_test(KFile *channel)
+{
+ KFile fd;
+ uint8_t test_buf[256];
+
+ /*
+ * Init a spi kfile interface and
+ * flash driver.
+ */
+ flash25_init(&fd, channel);
+
+ kprintf("Init serial flash\n");
+
+ flash25_chipErase();
+
+ flash25_sectorErase(FLASH25_SECT1);
+ flash25_sectorErase(FLASH25_SECT2);
+ flash25_sectorErase(FLASH25_SECT3);
+ flash25_sectorErase(FLASH25_SECT4);
+
+ /*
+ * Launche a kfile test interface.
+ */
+ kprintf("Kfile test start..\n");
+ if (!kfile_test(&fd, test_buf, NULL, sizeof(test_buf)))
+ return false;
+
+ return true;
+}
+#endif /* CONFIG_TEST */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Function library for serial Flash memory.
+ *
+ *
+ * \version $Id$
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+
+#ifndef DRV_FLASH25_H
+#define DRV_FLASH25_H
+
+#include <kern/kfile.h>
+#include <cfg/compiler.h>
+
+
+#include <appconfig.h>
+
+/**
+ * Type definition for serial flash memory.
+ */
+typedef uint32_t flash25Addr_t;
+typedef uint32_t flash25Size_t;
+typedef uint8_t flash25Offset_t;
+
+
+/**
+ * Memory definition.
+ *
+ * \note Below are defined valid serial flash memory support to
+ * this drive. Every time we call flash25_init() function we check
+ * if memory defined are right (see flash25.c form more detail).
+ * \{
+ */
+#define FLASH25_AT25F2048 1
+
+#if CONFIG_FLASH25 == FLASH25_AT25F2048
+ #define FLASH25_MANUFACTURER_ID 0x1F // ATMEL
+ #define FLASH25_DEVICE_ID 0x63 // Device ID
+ #define FLASH25_PAGE_SIZE 256 // Page size in byte
+ #define FLASH25_NUM_SECTOR 4 // Number of section in serial memory
+ #define FLASH25_SECTOR_SIZE 65536UL // Section size in byte
+ #define FLASH25_MEM_SIZE FLASH25_NUM_SECTOR * FLASH25_SECTOR_SIZE
+ #define FLASH25_NUM_PAGE FLASH25_MEM_SIZE / FLASH25_PAGE_SIZE
+#elif
+ #error Nothing memory defined in CONFIG_FLASH25 are support.
+#endif
+
+#define RDY_BIT 0x1 // Statuts of write cycle
+/* \} */
+
+/**
+ * Serial flash opcode commands.
+ */
+typedef enum {
+ FLASH25_WREN = 0x6, ///< Set write enable latch
+ FLASH25_WRDI = 0x4, ///< Reset enable write latch
+ FLASH25_RDSR = 0x5, ///< Read status register
+ FLASH25_WRSR = 0x1, ///< Write status register
+ FLASH25_READ = 0x3, ///< Read data from memory array
+ FLASH25_PROGRAM = 0x2, ///< Program data into memory array
+ FLASH25_SECTORE_ERASE = 0x52, ///< Erase one sector in memory array
+ FLASH25_CHIP_ERASE = 0x62, ///< Erase all sector in memory array
+ FLASH25_RDID = 0x15 ///< Read Manufacturer and product ID
+} Flash25Opcode;
+
+/**
+ * Serial flash sector memory address.
+ */
+#if CONFIG_FLASH25 != FLASH25_AT25F2048
+ #error Nothing memory defined in CONFIG_FLASH25 are support.
+#endif
+
+typedef enum {
+ FLASH25_SECT1 = 0x0, ///< Sector 1 (0x0 -0xFFFF)
+ FLASH25_SECT2 = 0x10000, ///< Sector 2 (0x10000 -0x1FFFF)
+ FLASH25_SECT3 = 0x20000, ///< Sector 3 (0x20000 -0x2FFFF)
+ FLASH25_SECT4 = 0x30000, ///< Sector 4 (0x30000 -0x3FFFF)
+} Flash25Sector;
+
+void flash25_init(struct KFile *fd, struct KFile *_channel);
+void flash25_chipErase(void);
+void flash25_sectorErase(Flash25Sector sector);
+bool flash25_test(KFile *channel);
+
+#endif /* DRV_FLASH25_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2003 Bernardo Innocenti
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief Keyboard driver (implementation)
+ */
+
+#include <hw_kbd.h>
+
+#include <drv/timer.h>
+#include <drv/kbd.h>
+
+#include <cfg/debug.h>
+#include <cfg/module.h>
+#include <appconfig.h>
+
+/* Configuration sanity checks */
+#if !defined(CONFIG_KBD_POLL) || (CONFIG_KBD_POLL != KBD_POLL_SOFTINT && CONFIG_KBD_POLL != CONFIG_POLL_FREERTOS)
+ #error CONFIG_KBD_POLL must be defined to either KBD_POLL_SOFTINT or CONFIG_POLL_FREERTOS
+#endif
+#if !defined(CONFIG_KBD_BEEP) || (CONFIG_KBD_BEEP != 0 && CONFIG_KBD_BEEP != 1)
+ #error CONFIG_KBD_BEEP must be defined to either 0 or 1
+#endif
+#if !defined(CONFIG_KBD_OBSERVER) || (CONFIG_KBD_OBSERVER != 0 && CONFIG_KBD_OBSERVER != 1)
+ #error CONFIG_KBD_OBSERVER must be defined to either 0 or 1
+#endif
+#if !defined(CONFIG_KBD_LONGPRESS) || (CONFIG_KBD_LONGPRESS != 0 && CONFIG_KBD_LONGPRESS != 1)
+ #error CONFIG_KBD_LONGPRESS must be defined to either 0 or 1
+#endif
+
+#if CONFIG_KBD_BEEP
+ #include <drv/buzzer.h>
+#endif
+
+#define KBD_CHECK_INTERVAL 10 /**< (ms) Timing for kbd softint */
+#define KBD_DEBOUNCE_TIME 30 /**< (ms) Debounce time */
+#define KBD_BEEP_TIME 5 /**< (ms) Duration of keybeep */
+
+#define KBD_REPEAT_DELAY 400 /**< (ms) Keyboard repeat delay for first character */
+#define KBD_REPEAT_RATE 100 /**< (ms) Initial interchar delay for keyboard repeat */
+#define KBD_REPEAT_MAXRATE 20 /**< (ms) Minimum delay for keyboard repeat */
+#define KBD_REPEAT_ACCEL 5 /**< (ms) Keyboard repeat speed increase */
+
+#define KBD_LNG_DELAY 1000 /**< (ms) Keyboard long pression keys delay */
+
+
+/** Status for keyboard repeat state machine */
+static enum { KS_IDLE, KS_REPDELAY, KS_REPEAT } kbd_rptStatus;
+
+
+static volatile keymask_t kbd_buf; /**< Single entry keyboard buffer */
+static volatile keymask_t kbd_cnt; /**< Number of keypress events in \c kbd_buf */
+static keymask_t kbd_rpt_mask; /**< Mask of repeatable keys. */
+
+#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
+static Timer kbd_timer; /**< Keyboard softtimer */
+#endif
+
+static List kbd_rawHandlers; /**< Raw keyboard handlers */
+static List kbd_handlers; /**< Cooked keyboard handlers */
+
+static KbdHandler kbd_defHandler; /**< The default keyboard handler */
+static KbdHandler kbd_debHandler; /**< The debounce keyboard handler */
+static KbdHandler kbd_rptHandler; /**< Auto-repeat keyboard handler */
+
+#if CONFIG_KBD_LONGPRESS
+static KbdHandler kbd_lngHandler; /**< Long pression keys handler */
+#endif
+
+#if CONFIG_KBD_OBSERVER
+ #include <mware/observer.h>
+ Subject kbd_subject;
+#endif
+
+
+/**
+ * Poll keyboard and dispatch keys to handlers.
+ *
+ * Read the key states and invoke all keyboard
+ * handlers to process the new state.
+ *
+ * Call this function periodically using a software
+ * timer, an interrupt or a process.
+ */
+static void kbd_poll(void)
+{
+ /** Currently depressed key */
+ static keymask_t current_key;
+
+ struct KbdHandler *handler;
+ keymask_t key = kbd_readkeys();
+
+ /* Call raw input handlers */
+ FOREACH_NODE(handler, &kbd_rawHandlers)
+ key = handler->hook(key);
+
+ /* If this key was not previously pressed */
+ if (key != current_key)
+ {
+ /* Remember last key */
+ current_key = key;
+
+ /* Call cooked input handlers */
+ FOREACH_NODE(handler, &kbd_handlers)
+ key = handler->hook(key);
+ }
+}
+
+#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
+
+/**
+ * Keyboard soft-irq handler.
+ */
+static void kbd_softint(UNUSED_ARG(iptr_t, arg))
+{
+ kbd_poll();
+ timer_add(&kbd_timer);
+}
+
+#elif CONFIG_KBD_POLL == CONFIG_POLL_FREERTOS
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+static portTASK_FUNCTION(kbd_task, arg)
+{
+ for (;;)
+ {
+ kbd_poll();
+ timer_delay(KBD_CHECK_INTERVAL);
+ }
+}
+
+#endif /* CONFIG_KBD_POLL */
+
+/**
+ * \brief Read a key from the keyboard buffer.
+ *
+ * When a key is kept depressed between calls of this function a value
+ * is returned only after the time specified with KBD_REPAT_DELAY to
+ * avoid too fast keyboard repeat.
+ *
+ * \note Calls \c schedule() internally.
+ *
+ * \note This function is \b not interrupt safe!
+ *
+ * \return The mask of depressed keys or 0 if no keys are depressed.
+ *
+ */
+keymask_t kbd_peek(void)
+{
+ keymask_t key = 0;
+
+// FIXME: make it optional
+ /* Let other tasks run for a while */
+ extern void schedule(void);
+ schedule();
+
+ /* Extract an event from the keyboard buffer */
+ IRQ_DISABLE;
+ if (kbd_cnt)
+ {
+ --kbd_cnt;
+ key = kbd_buf;
+ }
+ IRQ_ENABLE;
+
+ return key;
+}
+
+/**
+ * Wait for a keypress and return the mask of depressed keys.
+ *
+ * \note This function is \b not interrupt safe!
+ */
+keymask_t kbd_get(void)
+{
+ keymask_t key;
+
+ while (!(key = kbd_peek())) {}
+
+ return key;
+}
+
+
+/**
+ * Wait up to \c timeout ms for a keypress
+ * and return the mask of depressed keys, or K_TIMEOUT
+ * if the timeout was reacked.
+ */
+keymask_t kbd_get_timeout(mtime_t timeout)
+{
+ keymask_t key;
+
+ ticks_t start = timer_clock();
+ ticks_t stop = ms_to_ticks(timeout);
+ do
+ {
+ if ((key = kbd_peek()))
+ return key;
+ }
+ while (timer_clock() - start < stop);
+
+ return K_TIMEOUT;
+}
+
+
+void kbd_addHandler(struct KbdHandler *handler)
+{
+ KbdHandler *node;
+ List *list;
+
+ cpuflags_t flags;
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Choose between raw and coocked handlers list */
+ list = (handler->flags & KHF_RAWKEYS) ?
+ &kbd_rawHandlers : &kbd_handlers;
+
+ /*
+ * Search for the first node whose priority
+ * is lower than the timer we want to add.
+ */
+ FOREACH_NODE(node,list)
+ if (node->pri < handler->pri)
+ break;
+
+ /* Enqueue handler in the handlers chain */
+ INSERT_BEFORE(&handler->link, &node->link);
+
+ IRQ_RESTORE(flags);
+}
+
+
+void kbd_remHandler(struct KbdHandler *handler)
+{
+ /* Remove the handler */
+ ATOMIC(REMOVE(&handler->link));
+}
+
+
+/**
+ * This is the default key handler, called after
+ * all other handlers have had their chance to
+ * do their special processing. This handler
+ * pushes all input in the keyboard FIFO buffer.
+ */
+static keymask_t kbd_defHandlerFunc(keymask_t key)
+{
+ if (key)
+ {
+ /* Force a single event in kbd buffer */
+ kbd_buf = key;
+ kbd_cnt = 1;
+
+ #if CONFIG_KBD_OBSERVER
+ observer_notify(&kbd_subject, KBD_EVENT_KEY, &key);
+ #endif
+
+ #if CONFIG_KBD_BEEP
+ if (!(key & K_REPEAT))
+ buz_beep(KBD_BEEP_TIME);
+ #endif
+ }
+
+ /* Eat all input */
+ return 0;
+}
+
+/**
+ * Handle keyboard debounce
+ */
+static keymask_t kbd_debHandlerFunc(keymask_t key)
+{
+ /** Buffer for debounce */
+ static keymask_t debounce_key;
+
+ /** Timer for keyboard debounce */
+ static ticks_t debounce_time;
+
+ /** Key aquired after debounce */
+ static keymask_t new_key;
+
+
+ ticks_t now = timer_clock();
+
+ if (key != debounce_key)
+ {
+ /* Reset debounce timer */
+ debounce_key = key;
+ debounce_time = now;
+ }
+ else if ((new_key != debounce_key)
+ && (now - debounce_time > ms_to_ticks(KBD_DEBOUNCE_TIME)))
+ {
+ new_key = debounce_key;
+ debounce_time = now;
+ }
+
+ return new_key;
+}
+
+#if CONFIG_KBD_LONGPRESS
+/**
+ * Handle long pression keys.
+ */
+static keymask_t kbd_lngHandlerFunc(keymask_t key)
+{
+ static ticks_t start;
+ ticks_t now = timer_clock();
+
+ if (key & K_LNG_MASK)
+ {
+ if (now - start > ms_to_ticks(KBD_LNG_DELAY))
+ key |= K_LONG;
+ }
+ else
+ start = now;
+ return key;
+}
+#endif
+
+/**
+ * Set current mask of repeatable keys.
+ */
+keymask_t kbd_setRepeatMask(keymask_t mask)
+{
+ keymask_t oldmask = kbd_rpt_mask;
+ ATOMIC(kbd_rpt_mask = mask);
+ return oldmask;
+}
+
+/**
+ * Handle keyboard repeat
+ */
+static keymask_t kbd_rptHandlerFunc(keymask_t key)
+{
+ /* Timer for keyboard repeat events. */
+ static ticks_t repeat_time;
+
+ /* Current repeat rate (for acceleration). */
+ static ticks_t repeat_rate; /** Current repeat rate (for acceleration) */
+
+ ticks_t now = timer_clock();
+
+ switch (kbd_rptStatus)
+ {
+ case KS_IDLE:
+ if (key & kbd_rpt_mask)
+ {
+ repeat_time = now;
+ kbd_rptStatus = KS_REPDELAY;
+ }
+ break;
+
+ case KS_REPDELAY:
+ if (key & kbd_rpt_mask)
+ {
+ if (now - repeat_time > ms_to_ticks(KBD_REPEAT_DELAY))
+ {
+ key = (key & kbd_rpt_mask) | K_REPEAT;
+ repeat_time = now;
+ repeat_rate = ms_to_ticks(KBD_REPEAT_RATE);
+ kbd_rptStatus = KS_REPEAT;
+ }
+ else
+ key = 0;
+ }
+ else
+ kbd_rptStatus = KS_IDLE;
+ break;
+
+ case KS_REPEAT:
+ if (key & kbd_rpt_mask)
+ {
+ if (now - repeat_time > repeat_rate)
+ {
+ /* Enqueue a new event in the buffer */
+ key = (key & kbd_rpt_mask) | K_REPEAT;
+ repeat_time = now;
+
+ /* Repeat rate acceleration */
+ if (repeat_rate > ms_to_ticks(KBD_REPEAT_MAXRATE))
+ repeat_rate -= ms_to_ticks(KBD_REPEAT_ACCEL);
+ }
+ else
+ key = 0;
+ }
+ else
+ kbd_rptStatus = KS_IDLE;
+
+ break;
+ }
+
+ return key;
+}
+
+
+MOD_DEFINE(kbd)
+
+/**
+ * Initialize keyboard ports and softtimer
+ */
+void kbd_init(void)
+{
+#if CONFIG_KBD_BEEP
+ MOD_CHECK(buzzer);
+#endif
+
+ KBD_HW_INIT;
+
+ /* Init handlers lists */
+ LIST_INIT(&kbd_handlers);
+ LIST_INIT(&kbd_rawHandlers);
+
+ /* Add debounce keyboard handler */
+ kbd_debHandler.hook = kbd_debHandlerFunc;
+ kbd_debHandler.pri = 100; /* high priority */
+ kbd_debHandler.flags = KHF_RAWKEYS;
+ kbd_addHandler(&kbd_debHandler);
+
+ #if CONFIG_KBD_LONGPRESS
+ /* Add long pression keyboard handler */
+ kbd_lngHandler.hook = kbd_lngHandlerFunc;
+ kbd_lngHandler.pri = 90; /* high priority */
+ kbd_lngHandler.flags = KHF_RAWKEYS;
+ kbd_addHandler(&kbd_lngHandler);
+ #endif
+
+ /* Add repeat keyboard handler */
+ kbd_rptHandler.hook = kbd_rptHandlerFunc;
+ kbd_rptHandler.pri = 80; /* high priority */
+ kbd_rptHandler.flags = KHF_RAWKEYS;
+ kbd_addHandler(&kbd_rptHandler);
+
+ /* Add default keyboard handler */
+ kbd_defHandler.hook = kbd_defHandlerFunc;
+ kbd_defHandler.pri = -128; /* lowest priority */
+ kbd_addHandler(&kbd_defHandler);
+
+#if CONFIG_KBD_OBSERVER
+ observer_InitSubject(&kbd_subject);
+#endif
+
+#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
+
+ MOD_CHECK(timer);
+
+ /* Add kbd handler to soft timers list */
+ event_initSoftInt(&kbd_timer.expire, kbd_softint, NULL);
+ timer_setDelay(&kbd_timer, ms_to_ticks(KBD_CHECK_INTERVAL));
+ timer_add(&kbd_timer);
+
+#elif CONFIG_KBD_POLL == CONFIG_POLL_FREERTOS
+
+ /* Create a timer specific thread */
+ xTaskCreate(kbd_task, "kbd", CONFIG_STACK_KBD,
+ NULL, CONFIG_PRI_KBD, NULL);
+
+#else
+ #error "Define keyboard poll method"
+#endif
+
+ MOD_INIT(kbd);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2003 Bernardo Innocenti
+ *
+ * -->
+ *
+ * \brief Keyboard driver (interface)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef DRV_KBD_H
+#define DRV_KBD_H
+
+#include <kbd_map.h>
+#include <cfg/compiler.h>
+#include <mware/list.h>
+#include <appconfig.h> // CONFIG_KBD_OBSERVER
+
+/**
+ * \name Keyboard polling modes.
+ *
+ * Define CONFIG_KBD_POLL to one of these.
+ *
+ * \{
+ */
+#define KBD_POLL_SOFTINT 1
+#define KBD_POLL_FREERTOS 2
+/* \} */
+
+/**
+ * Keyboard handler descriptor
+ */
+typedef struct KbdHandler
+{
+ Node link;
+ keymask_t (*hook)(keymask_t); /**< Hook function */
+ int8_t pri; /**< Priority in input queue */
+ uint8_t flags; /**< See below for definitions */
+} KbdHandler;
+
+#define KHF_RAWKEYS BV(0) /**< Handler gets raw key events */
+
+
+void kbd_init(void);
+keymask_t kbd_peek(void);
+keymask_t kbd_get(void);
+keymask_t kbd_get_timeout(mtime_t timeout);
+void kbd_addHandler(struct KbdHandler *handler);
+void kbd_remHandler(struct KbdHandler *handler);
+keymask_t kbd_setRepeatMask(keymask_t mask);
+
+#if CONFIG_KBD_OBSERVER
+ struct Subject;
+
+ /** Subject structure for keyboard observers. */
+ extern struct Subject kbd_subject;
+
+ enum
+ {
+ /* Event for key presses. */
+ KBD_EVENT_KEY = 0x100
+ };
+#endif
+
+#endif /* DRV_KBD_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000, 2001, 2002 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \brief General pourpose debug support for embedded systems (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#include <cpu/irq.h>
+#include <cpu/attr.h>
+#include <cpu/types.h>
+
+#include <cfg/macros.h> /* for BV() */
+#include <cfg/debug.h>
+
+#include <appconfig.h>
+#warning what about these?
+//#include <hw_cpu.h> /* for CLOCK_FREQ */
+//#include <hw_ser.h> /* Required for bus macros overrides */
+
+#include <mware/formatwr.h> /* for _formatted_write() */
+#include <mware/pgm.h>
+
+#ifdef _DEBUG
+
+#if CPU_HARVARD && !defined(_PROGMEM)
+ #error This module build correctly only in program memory!
+#endif
+
+
+#if OS_HOSTED
+ #include <stdio.h>
+ #define KDBG_WAIT_READY() do { /*nop*/ } while(0)
+ #define KDBG_WRITE_CHAR(c) putc((c), stderr)
+ #define KDBG_MASK_IRQ(old) do { (void)(old); } while(0)
+ #define KDBG_RESTORE_IRQ(old) do { /*nop*/ } while(0)
+ typedef char kdbg_irqsave_t; /* unused */
+
+ #define kdbg_hw_init() do {} while (0) ///< Not needed
+
+ #if CONFIG_KDEBUG_PORT == 666
+ #error BITBANG debug console missing for this platform
+ #endif
+#else
+ #include CPU_CSOURCE(kdebug)
+#endif
+
+
+void kdbg_init(void)
+{
+ /* Init debug hw */
+ kdbg_hw_init();
+ kputs("\n\n*** BeRTOS DBG START ***\n");
+}
+
+
+/**
+ * Output one character to the debug console
+ */
+static void __kputchar(char c, UNUSED_ARG(void *, unused))
+{
+ /* Poll while serial buffer is still busy */
+ KDBG_WAIT_READY();
+
+ /* Send '\n' as '\r\n' for dumb terminals */
+ if (c == '\n')
+ {
+ KDBG_WRITE_CHAR('\r');
+ KDBG_WAIT_READY();
+ }
+
+ KDBG_WRITE_CHAR(c);
+}
+
+
+void kputchar(char c)
+{
+ /* Mask serial TX intr */
+ kdbg_irqsave_t irqsave;
+ KDBG_MASK_IRQ(irqsave);
+
+ __kputchar(c, 0);
+
+ /* Restore serial TX intr */
+ KDBG_RESTORE_IRQ(irqsave);
+}
+
+
+static void PGM_FUNC(kvprintf)(const char * PGM_ATTR fmt, va_list ap)
+{
+#if CONFIG_PRINTF
+ /* Mask serial TX intr */
+ kdbg_irqsave_t irqsave;
+ KDBG_MASK_IRQ(irqsave);
+
+ PGM_FUNC(_formatted_write)(fmt, __kputchar, 0, ap);
+
+ /* Restore serial TX intr */
+ KDBG_RESTORE_IRQ(irqsave);
+#else
+ /* A better than nothing printf() surrogate. */
+ PGM_FUNC(kputs)(fmt);
+#endif /* CONFIG_PRINTF */
+}
+
+void PGM_FUNC(kprintf)(const char * PGM_ATTR fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ PGM_FUNC(kvprintf)(fmt, ap);
+ va_end(ap);
+}
+
+void PGM_FUNC(kputs)(const char * PGM_ATTR str)
+{
+ char c;
+
+ /* Mask serial TX intr */
+ kdbg_irqsave_t irqsave;
+ KDBG_MASK_IRQ(irqsave);
+
+ while ((c = PGM_READ_CHAR(str++)))
+ __kputchar(c, 0);
+
+ KDBG_RESTORE_IRQ(irqsave);
+}
+
+
+/**
+ * Cheap function to print small integers without using printf().
+ */
+int kputnum(int num)
+{
+ int output_len = 0;
+ int divisor = 10000;
+ int digit;
+
+ do
+ {
+ digit = num / divisor;
+ num %= divisor;
+
+ if (digit || output_len || divisor == 1)
+ {
+ kputchar(digit + '0');
+ ++output_len;
+ }
+ }
+ while (divisor /= 10);
+
+ return output_len;
+}
+
+
+static void klocation(const char * PGM_ATTR file, int line)
+{
+ PGM_FUNC(kputs)(file);
+ kputchar(':');
+ kputnum(line);
+ PGM_FUNC(kputs)(PGM_STR(": "));
+}
+
+int PGM_FUNC(__assert)(const char * PGM_ATTR cond, const char * PGM_ATTR file, int line)
+{
+ klocation(file, line);
+ PGM_FUNC(kputs)(PGM_STR("Assertion failed: "));
+ PGM_FUNC(kputs)(cond);
+ kputchar('\n');
+ BREAKPOINT;
+ return 1;
+}
+
+/*
+ * Unfortunately, there's no way to get __func__ in
+ * program memory, so we waste quite a lot of RAM in
+ * AVR and other Harvard processors.
+ */
+void PGM_FUNC(__trace)(const char *name)
+{
+ PGM_FUNC(kprintf)(PGM_STR("%s()\n"), name);
+}
+
+void PGM_FUNC(__tracemsg)(const char *name, const char * PGM_ATTR fmt, ...)
+{
+ va_list ap;
+
+ PGM_FUNC(kprintf)(PGM_STR("%s(): "), name);
+ va_start(ap, fmt);
+ PGM_FUNC(kvprintf)(fmt, ap);
+ va_end(ap);
+ kputchar('\n');
+}
+
+int PGM_FUNC(__invalid_ptr)(void *value, const char * PGM_ATTR name, const char * PGM_ATTR file, int line)
+{
+ klocation(file, line);
+ PGM_FUNC(kputs)(PGM_STR("Invalid ptr: "));
+ PGM_FUNC(kputs)(name);
+ #if CONFIG_PRINTF
+ PGM_FUNC(kprintf)(PGM_STR(" = 0x%p\n"), value);
+ #else
+ (void)value;
+ kputchar('\n');
+ #endif
+ return 1;
+}
+
+
+void __init_wall(long *wall, int size)
+{
+ while(size--)
+ *wall++ = WALL_VALUE;
+}
+
+
+int PGM_FUNC(__check_wall)(long *wall, int size, const char * PGM_ATTR name, const char * PGM_ATTR file, int line)
+{
+ int i, fail = 0;
+
+ for (i = 0; i < size; i++)
+ {
+ if (wall[i] != WALL_VALUE)
+ {
+ klocation(file, line);
+ PGM_FUNC(kputs)(PGM_STR("Wall broken: "));
+ PGM_FUNC(kputs)(name);
+ #if CONFIG_PRINTF
+ PGM_FUNC(kprintf)(PGM_STR("[%d] (0x%p) = 0x%lx\n"), i, wall + i, wall[i]);
+ #else
+ kputchar('\n');
+ #endif
+ fail = 1;
+ }
+ }
+
+ return fail;
+}
+
+
+#if CONFIG_PRINTF
+
+/**
+ * Dump binary data in hex
+ */
+void kdump(const void *_buf, size_t len)
+{
+ const unsigned char *buf = (const unsigned char *)_buf;
+
+ while (len--)
+ kprintf("%02X", *buf++);
+ kputchar('\n');
+}
+
+#endif /* CONFIG_PRINTF */
+
+#endif /* _DEBUG */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id: lcd_gfx.h,v 1.6 2006/07/19 12:56:25 bernie Exp $
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Displaytech 32122A LCD driver
+ */
+#ifndef LCD_GFX_H
+#define LCD_GFX_H
+
+/* Predefined LCD PWM contrast values */
+#define LCD_DEF_PWM 145
+#define LCD_MAX_PWM 505
+#define LCD_MIN_PWM 130
+
+/* Display bitmap dims */
+#define LCD_WIDTH 128
+#define LCD_HEIGHT 64
+
+/* fwd decl */
+struct Bitmap;
+
+extern struct Bitmap lcd_bitmap;
+
+void lcd_init(void);
+void lcd_setPwm(int duty);
+void lcd_blitBitmap(struct Bitmap *bm);
+
+#endif /* LCD_GFX_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom control for graphics LCD emulation (interface)
+ */
+
+#include "lcd_gfx_qt.h"
+#include <emul/emul.h>
+#include <cfg/debug.h>
+#include <gfx/gfx.h> // CONFIG_BITMAP_FMT
+
+#include <QtGui/QPainter>
+#include <QtGui/QImage>
+#include <QtGui/QSizePolicy>
+#include <QtCore/QSize>
+
+// Display colors
+#define LCD_FG_COLOR 0x0, 0x0, 0x0
+#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
+
+
+EmulLCD::EmulLCD(QWidget *parent, const char *name) :
+ QFrame(parent, name, Qt::WRepaintNoErase | Qt::WResizeNoErase),
+ fg_color(LCD_FG_COLOR),
+ bg_color(LCD_BG_COLOR)
+{
+ // initialize bitmap
+ memset(raster, 0xAA, sizeof(raster));
+
+ // set widget frame
+ setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ frame_width = frameWidth();
+}
+
+
+EmulLCD::~EmulLCD()
+{
+ // nop
+}
+
+
+QSizePolicy EmulLCD::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
+}
+
+
+QSize EmulLCD::sizeHint() const
+{
+ return QSize(
+ WIDTH + frame_width * 2,
+ HEIGHT + frame_width * 2);
+}
+
+
+void EmulLCD::paintEvent(QPaintEvent * /*event*/)
+{
+ QPainter p(this);
+ QImage img(raster, WIDTH, HEIGHT, 1, NULL, 0, QImage::BigEndian);
+
+ p.setBackgroundMode(Qt::OpaqueMode);
+ p.setPen(fg_color);
+ p.setBackgroundColor(bg_color);
+ p.drawImage(frame_width, frame_width, img);
+}
+
+void EmulLCD::writeRaster(uint8_t *new_raster)
+{
+#if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
+
+ /* Straight copy */
+ memcpy(raster, new_raster, sizeof(raster));
+
+#elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
+
+ /* Rotation */
+ for (int y = 0; y < HEIGHT; ++y)
+ {
+ for (int xbyte = 0; xbyte < WIDTH/8; ++xbyte)
+ {
+ uint8_t v = 0;
+ for (int xbit = 0; xbit < 8; ++xbit)
+ v |= (new_raster[(xbyte * 8 + xbit) + (y / 8) * WIDTH] & (1 << (y%8)) )
+ ? 0 : (1 << (7 - xbit));
+
+ raster[y * ((WIDTH + 7) / 8) + xbyte] = v;
+ }
+ }
+
+#else
+ #error Unsupported bitmap format
+#endif
+
+ repaint();
+}
+
+
+
+#include <gfx/gfx.h>
+#include <cfg/debug.h>
+
+DECLARE_WALL(wall_before_raster, WALL_SIZE)
+/**
+ * Raster buffer to draw into.
+ *
+ * Bits in the bitmap bytes have vertical orientation,
+ * as required by the LCD driver.
+ */
+static uint8_t lcd_raster[RAST_SIZE(EmulLCD::WIDTH, EmulLCD::HEIGHT)];
+DECLARE_WALL(wall_after_raster, WALL_SIZE)
+
+/** Default LCD bitmap */
+struct Bitmap lcd_bitmap;
+
+/*extern "C"*/ void lcd_init(void)
+{
+ //FIXME INIT_WALL(wall_before_raster);
+ //FIXME INIT_WALL(wall_after_raster);
+ gfx_bitmapInit(&lcd_bitmap, lcd_raster, EmulLCD::WIDTH, EmulLCD::HEIGHT);
+ gfx_bitmapClear(&lcd_bitmap);
+}
+
+/*extern "C"*/ void lcd_blitBitmap(Bitmap *bm)
+{
+ //FIXME CHECK_WALL(wall_before_raster);
+ //FIXME CHECK_WALL(wall_after_raster);
+ emul->emulLCD->writeRaster(bm->raster);
+}
+
+#include "lcd_gfx_qt_moc.cpp"
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom control for graphics LCD emulation (interface)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.5 2006/05/28 12:17:57 bernie
+ *#* Drop almost all the Qt3 cruft.
+ *#*
+ *#* Revision 1.4 2006/02/20 02:00:40 bernie
+ *#* Port to Qt 4.1.
+ *#*
+ *#* Revision 1.3 2006/02/15 09:13:16 bernie
+ *#* Switch to BITMAP_FMT_PLANAR_V_LSB.
+ *#*
+ *#* Revision 1.2 2006/02/10 12:33:51 bernie
+ *#* Make emulator display a bit larger.
+ *#*
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#ifndef DRV_LCD_GFX_QT_H
+#define DRV_LCD_GFX_QT_H
+
+#include <QtGui/QColor>
+#include <QtGui/QFrame>
+
+// fwd decls
+class QSizePolicy;
+class QPaintEvent;
+class QResizeEvent;
+
+
+class EmulLCD : public QFrame
+{
+ Q_OBJECT
+
+public:
+// Attributes
+ enum { WIDTH = 128, HEIGHT = 64 };
+
+// Construction
+ EmulLCD(QWidget *parent = 0, const char *name = 0);
+ virtual ~EmulLCD();
+
+// Base class overrides
+protected:
+ virtual QSizePolicy sizePolicy() const;
+ virtual QSize sizeHint() const;
+ virtual void paintEvent(QPaintEvent *event);
+
+// Operations
+public:
+ void writeRaster(uint8_t *raster);
+
+// Implementation
+protected:
+ /// Frame thickness
+ int frame_width;
+
+ /// LCD colors
+ QColor fg_color, bg_color;
+
+ /// Pixel storage
+ unsigned char raster[(WIDTH * HEIGHT) / 8];
+};
+
+#endif // DRV_LCD_GFX_QT_H
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief dot-matrix LCD test.
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.3 2006/01/17 23:00:26 bernie
+ *#* Don't use hardcoded coordinates.
+ *#*
+ *#* Revision 1.2 2006/01/17 02:31:57 bernie
+ *#* Test gfx with the usual pentagons.
+ *#*
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#include <emul/emul.h>
+#include <drv/lcd_gfx.h>
+#include <gfx/gfx.h>
+
+static void magic(struct Bitmap *bitmap, coord_t x, coord_t y)
+{
+ static const coord_t coords[] = { 120, 34, 90, 90, 30, 90, 0, 34, 60, 0, 90, 90, 0, 34, 120, 34, 30, 90, 60, 0 };
+ unsigned int i;
+
+ gfx_moveTo(bitmap, coords[countof(coords)-2]/2 + x, coords[countof(coords)-1]/3 + y);
+ for (i = 0; i < countof(coords); i += 2)
+ gfx_lineTo(bitmap, coords[i]/2 + x, coords[i+1]/3 + y);
+}
+
+int main(int argc, char *argv[])
+{
+ emul_init(&argc, argv);
+ lcd_init();
+
+ coord_t x = 0, y = LCD_WIDTH / 2;
+ coord_t xdir = +1, ydir = -1;
+ Bitmap *bm = &lcd_bitmap;
+
+ for(;;)
+ {
+ gfx_bitmapClear(bm);
+ gfx_setClipRect(bm, 0, 0, bm->width, bm->height);
+ gfx_rectDraw(bm, 10, 10, bm->width-10, bm->height-10);
+ gfx_setClipRect(bm, 11, 11, bm->width-11, bm->height-11);
+ magic(bm, x, y);
+
+ x += xdir;
+ y += ydir;
+ if (x >= bm->width) xdir = -1;
+ if (x <= -50) xdir = +1;
+ if (y >= bm->height) ydir = -1;
+ if (y <= -50) ydir = +1;
+
+ lcd_blit_bitmap(bm);
+ emul_idle();
+ usleep(10000);
+ }
+
+ emul_cleanup();
+ return 0;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief LM044L type LCD hardware module (impl.)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#include "lcd_hd44.h"
+#include "hw_lcd.h"
+#include <cfg/arch_config.h>
+#include <drv/timer.h>
+
+#if defined(LCD_READ_H) && defined(LCD_READ_L) && defined(LCD_WRITE_H) && defined(LCD_WRITE_L)
+ #define CONFIG_LCD_4BIT 1
+#elif defined(LCD_READ) && defined(LCD_WRITE)
+ #define CONFIG_LCD_4BIT 0
+#else
+ #error Incomplete or missing LCD_READ/LCD_WRITE macros
+#endif
+
+/** Flag di stato del display */
+#define LCDF_BUSY BV(7)
+
+#if CONFIG_LCD_ADDRESS_FAST == 1
+#define lcd_address(x) lcd_address[x]
+/**
+ * Addresses of LCD display character positions, expanded
+ * for faster access (DB7 = 1).
+ */
+static const uint8_t lcd_address[] =
+{
+ /* row 0 */
+ 0x80, 0x81, 0x82, 0x83,
+ 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8A, 0x8B,
+ 0x8C, 0x8D, 0x8E, 0x8F,
+#if LCD_COLS > 16
+ 0x90, 0x91, 0x92, 0x93,
+#endif
+
+ /* row 1 */
+ 0xC0, 0xC1, 0xC2, 0xC3,
+ 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xCA, 0xCB,
+ 0xCC, 0xCD, 0xCE, 0xCF,
+#if LCD_COLS > 16
+ 0xD0, 0xD1, 0xD2, 0xD3,
+#endif
+
+#if LCD_ROWS > 2
+ /* row 2 */
+ 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9A, 0x9B,
+ 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3,
+#if LCD_COLS > 16
+ 0xA4, 0xA5, 0xA6, 0xA7,
+#endif
+
+ /* row 3 */
+ 0xD4, 0xD5, 0xD6, 0xD7,
+ 0xD8, 0xD9, 0xDA, 0xDB,
+ 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3,
+#if LCD_COLS > 16
+ 0xE4, 0xE5, 0xE6, 0xE7,
+#endif
+
+#endif /* LCD_ROWS > 2 */
+};
+
+STATIC_ASSERT(countof(lcd_address) == LCD_ROWS * LCD_COLS);
+#else /* CONFIG_LCD_ADDRESS_FAST == 0 */
+
+static const uint8_t col_address[] =
+{
+ 0x80,
+ 0xC0,
+#if LCD_ROWS > 2
+ 0x94,
+ 0xD4
+#endif
+};
+STATIC_ASSERT(countof(col_address) == LCD_ROWS);
+/**
+ * Addresses of LCD display character positions, calculated runtime to save RAM
+ */
+static uint8_t lcd_address(uint8_t addr)
+{
+ return col_address[addr / LCD_COLS] + addr % LCD_COLS;
+}
+#endif /* CONFIG_LCD_ADDRESS_FAST */
+
+/**
+ * Current display position. We remember this to optimize
+ * LCD output by avoiding to set the address every time.
+ */
+static lcdpos_t lcd_current_addr;
+
+
+#if !defined(ARCH_EMUL) || !(ARCH & ARCH_EMUL)
+/* __________________
+ * RS
+ *
+ * R/W __________________
+ * _______
+ * ENA _____/ \____
+ *
+ * DATA -<================
+ */
+INLINE void lcd_dataWrite(uint8_t data)
+{
+#if CONFIG_LCD_4BIT
+ /* Write high nibble */
+ LCD_WRITE_H(data);
+ LCD_SET_E;
+ LCD_DELAY_WRITE;
+ LCD_CLR_E;
+ LCD_DELAY_WRITE;
+
+ /* Write low nibble */
+ LCD_WRITE_L(data);
+ LCD_SET_E;
+ LCD_DELAY_WRITE;
+ LCD_CLR_E;
+ LCD_DELAY_WRITE;
+
+#else /* !CONFIG_LCD_4BIT */
+
+ /* Write data */
+ LCD_WRITE(data);
+ LCD_SET_E;
+ LCD_DELAY_WRITE;
+ LCD_CLR_E;
+ LCD_DELAY_WRITE;
+
+#endif /* !CONFIG_LCD_4BIT */
+}
+
+/* __________________
+ * RS
+ * ____________
+ * R/W __/ \__
+ * _______
+ * ENA _____/ \____
+ * ______ ____
+ * DATA X/ \====/
+ */
+INLINE uint8_t lcd_dataRead(void)
+{
+ uint8_t data;
+
+ LCD_SET_RD;
+ LCD_DB_IN; /* Set bus as input! */
+ LCD_DELAY_READ;
+
+#if CONFIG_LCD_4BIT
+
+ /* Read high nibble */
+ LCD_SET_E;
+ LCD_DELAY_READ;
+ data = LCD_READ_H;
+ LCD_CLR_E;
+ LCD_DELAY_READ;
+
+ /* Read low nibble */
+ LCD_SET_E;
+ LCD_DELAY_READ;
+ data |= LCD_READ_L;
+ LCD_CLR_E;
+ LCD_DELAY_READ;
+
+#else /* !CONFIG_LCD_4BIT */
+
+ /* Read data */
+ LCD_SET_E;
+ LCD_DELAY_READ;
+ data = LCD_READ;
+ LCD_CLR_E;
+ LCD_DELAY_READ;
+
+#endif /* !CONFIG_LCD_4BIT */
+
+ LCD_CLR_RD;
+ LCD_DB_OUT; /* Reset bus as output! */
+
+ return data;
+}
+
+/* ___ __
+ * RS \___________/
+ *
+ * READ __________________
+ * _______
+ * ENA _____/ \____
+ *
+ * DATA --<===============
+ */
+INLINE void lcd_regWrite(uint8_t data)
+{
+ LCD_CLR_RS;
+ lcd_dataWrite(data);
+ LCD_SET_RS;
+}
+
+/* __ _
+ * RS \_____________/
+ * ___________
+ * READ ___/ \__
+ * _______
+ * ENA _____/ \____
+ * ______ ____
+ * DATA X/ \====/
+ */
+INLINE uint8_t lcd_regRead(void)
+{
+ uint8_t data;
+
+ LCD_CLR_RS;
+ data = lcd_dataRead();
+ LCD_SET_RS;
+ return data;
+}
+
+#if CONFIG_LCD_4BIT
+
+INLINE void lcd_mode4Bit(void)
+{
+ LCD_CLR_RS;
+
+ LCD_WRITE_H(LCD_CMD_SETFUNC);
+ LCD_SET_E;
+ LCD_DELAY_WRITE;
+ LCD_CLR_E;
+ LCD_DELAY_WRITE;
+
+ LCD_SET_RS;
+}
+
+#endif /* CONFIG_LCD_4BIT */
+
+#else /* ARCH_EMUL */
+
+extern void Emul_LCDWriteReg(uint8_t d);
+extern uint8_t Emul_LCDReadReg(void);
+extern void Emul_LCDWriteData(uint8_t d);
+extern uint8_t Emul_LCDReadData(void);
+
+#define lcd_regWrite(d) Emul_LCDWriteReg(d)
+#define lcd_regRead(d) Emul_LCDReadReg()
+#define lcd_dataWrite(d) Emul_LCDWriteData(d)
+#define lcd_dataRead(d) Emul_LCDReadData()
+
+#endif /* ARCH_EMUL */
+
+
+/**
+ * Wait until the LCD busy flag clears.
+ */
+void lcd_waitBusy(void)
+{
+ for (;;)
+ {
+ uint8_t val = lcd_regRead();
+ if (!(val & LCDF_BUSY))
+ break;
+ }
+}
+
+
+/**
+ * Move the cursor to \a addr, only if not already there.
+ */
+void lcd_moveTo(uint8_t addr)
+{
+ if (addr != lcd_current_addr)
+ {
+ lcd_waitBusy();
+ lcd_regWrite(lcd_address(addr));
+ lcd_current_addr = addr;
+ }
+}
+
+
+/**
+ * Write a value in LCD data register, waiting for the busy flag.
+ */
+void lcd_setReg(uint8_t val)
+{
+ lcd_waitBusy();
+ lcd_regWrite(val);
+}
+
+#include <cfg/debug.h>
+/**
+ * Write the character \a c on display address \a addr.
+ *
+ * NOTE: argh, the HD44 lcd type is a bad beast: our
+ * move/write -> write optimization requires this mess
+ * because display lines are interleaved!
+ */
+void lcd_putc(uint8_t addr, uint8_t c)
+{
+ if (addr != lcd_current_addr)
+ lcd_setReg(lcd_address(addr));
+
+ lcd_waitBusy();
+ lcd_dataWrite(c);
+ lcd_current_addr = addr + 1;
+
+ /* If we are at end of display wrap the address to 0 */
+ if (lcd_current_addr == LCD_COLS * LCD_ROWS)
+ lcd_current_addr = 0;
+
+ /* If we are at the end of a row put the cursor at the beginning of the next */
+ if (!(lcd_current_addr % LCD_COLS))
+ lcd_setReg(lcd_address(lcd_current_addr));
+}
+
+
+/**
+ * Remap the glyph of a character.
+ *
+ * glyph - bitmap of 8x8 bits.
+ * code - must be 0-7 for the Hitachi LCD-II controller.
+ */
+void lcd_remapChar(const char *glyph, char code)
+{
+ int i;
+
+ /* Set CG RAM address */
+ lcd_setReg((uint8_t)((1<<6) | (code << 3)));
+
+ /* Write bitmap data */
+ for (i = 0; i < 8; i++)
+ {
+ lcd_waitBusy();
+ lcd_dataWrite(glyph[i]);
+ }
+
+ /* Move back to original address */
+ lcd_setReg(lcd_address(lcd_current_addr));
+}
+
+
+#if 0 /* unused */
+void lcd_remapfont(void)
+{
+ static const char lcd_glyphs[8] =
+ {
+ 0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x04, 0x00 /* up arrow */
+ };
+ int i;
+
+ for (i = 0; i < 15; i++)
+ lcd_remapChar(i, bernie_char);
+
+
+ lcd_setAddr(lcd_DefLayer, 0);
+ for (i = 0; i < 80; i++)
+ lcd_putCharUnlocked(i);
+}
+#endif /* unused */
+
+void lcd_hw_init(void)
+{
+ lcd_bus_init();
+
+ timer_delay(50);
+
+#if CONFIG_LCD_4BIT
+ lcd_mode4Bit();
+ timer_delay(2);
+#endif /* CONFIG_LCD_4BIT */
+
+ lcd_regWrite(LCD_CMD_SETFUNC);
+ timer_delay(2);
+
+ lcd_regWrite(LCD_CMD_DISPLAY_ON);
+ timer_delay(2);
+
+ lcd_regWrite(LCD_CMD_CLEAR);
+ timer_delay(2);
+
+#if !CONFIG_LCD_4BIT
+ lcd_regWrite(LCD_CMD_RESET_DDRAM); // 4 bit mode doesn't allow char reprogramming
+#endif
+ lcd_regWrite(LCD_CMD_DISPLAYMODE);
+ timer_delay(2);
+}
+
+#if CONFIG_TEST
+
+void lcd_hw_test(void)
+{
+ lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 3);
+ timer_delay(1);
+ kprintf("3 -> %02X\n", lcd_regRead());
+ timer_delay(1);
+
+ for (int i = 0; i < 10; i++)
+ {
+ lcd_dataWrite('c');
+ timer_delay(1);
+ kprintf("addr = %02X\n", lcd_regRead());
+ timer_delay(1);
+ }
+
+ lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 0x4a);
+ timer_delay(1);
+ kprintf("4A -> %02X\n", lcd_regRead());
+ timer_delay(1);
+
+ lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 0x52);
+ timer_delay(1);
+ kprintf("52 -> %02X\n", lcd_regRead());
+ timer_delay(1);
+
+ lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 0x1F);
+ timer_delay(1);
+ kprintf("1F -> %02X\n", lcd_regRead());
+ timer_delay(1);
+}
+
+#endif /* CONFIG_TEST */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Hitachi HD44780 and clones LCD module (interface)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#ifndef DRV_LCD_HD44_H
+#define DRV_LCD_HD44_H
+
+#include <appconfig.h>
+#include <cfg/compiler.h> /* For stdint types */
+
+/**
+ * \name Display dimensions (in chars)
+ * \{
+ */
+#define LCD_ROWS 2
+#define LCD_COLS 16
+/* \} */
+
+/**
+ * \name Hitachi HD44 commands.
+ * \{
+ */
+#define LCD_CMD_DISPLAY_INI 0x30
+
+#if CONFIG_LCD_4BIT
+ #define LCD_CMD_SETFUNC 0x28 /**< 4 bits, 2 lines, 5x7 dots */
+#else
+ #define LCD_CMD_SETFUNC 0x38 /**< 8 bits, 2 lines, 5x7 dots */
+#endif
+
+#define LCD_CMD_DISPLAY_ON 0x0F /**< Switch on display */
+#define LCD_CMD_DISPLAY_OFF 0x08 /**< Switch off display */
+#define LCD_CMD_CLEAR 0x01 /**< Clear display */
+#define LCD_CMD_CURSOR_BLOCK 0x0D /**< Show cursor (block) */
+#define LCD_CMD_CURSOR_LINE 0x0F /**< Show cursor (line) */
+#define LCD_CMD_CURSOR_OFF 0x0C /**< Hide cursor */
+#define LCD_CMD_DISPLAYMODE 0x06
+#define LCD_CMD_SET_CGRAMADDR 0x40
+#define LCD_CMD_RESET_DDRAM 0x80
+#define LCD_CMD_SET_DDRAMADDR 0x80
+#define LCD_CMD_DISPLAY_SHIFT 0x18
+#define LCD_CMD_MOVESHIFT_LEFT 0x00
+#define LCD_CMD_MOVESHIFT_RIGHT 0x04
+/*\}*/
+
+/** Type for combined LCD cursor position (x,y). */
+typedef uint8_t lcdpos_t;
+
+void lcd_waitBusy(void);
+void lcd_moveTo(uint8_t addr);
+void lcd_setReg(uint8_t val);
+void lcd_putc(uint8_t a, uint8_t c);
+void lcd_remapChar(const char *glyph, char code);
+void lcd_hw_init(void);
+void lcd_hw_test(void);
+
+#endif /* DRV_LCD_HD44_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#include <qpainter.h>
+#include <qfont.h>
+#include <qsizepolicy.h>
+#include <qsize.h>
+#include "EmulLCD.h"
+#include "Emul.h"
+
+
+// Display colors
+#define LCD_FG_COLOR 0x0, 0x0, 0x0
+#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
+
+
+EmulLCD::EmulLCD(QWidget *parent, const char *name) :
+ QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
+ lcd_font("courier", 18),
+ fg_color(LCD_FG_COLOR),
+ bg_color(LCD_BG_COLOR),
+ cr_row(0),
+ cr_col(0),
+ cgramaddr(-1),
+ show_cursor(true)
+{
+ // initialize DDRAM
+ memcpy(ddram,
+ "01234567890123456789"
+ "abcdefghijhlmnopqrst"
+ "ABCDEFGHIJKLMNOPQRST"
+ "!@#$%^&*()_+|{}':?><",
+ sizeof(ddram));
+
+ // setup font
+ lcd_font.setFixedPitch(true);
+ setFont(lcd_font);
+
+ // get exact font size
+ QFontMetrics fm(lcd_font);
+ font_width = fm.width(QChar(' '));
+ font_height = fm.height();
+
+ // set widget frame
+ setFrameStyle(QFrame::Panel | QFrame::Sunken);
+// setLineWidth(2);
+ frame_width = frameWidth();
+}
+
+
+EmulLCD::~EmulLCD()
+{
+ // nop
+}
+
+
+QSizePolicy EmulLCD::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
+}
+
+
+QSize EmulLCD::sizeHint() const
+{
+ return QSize(
+ font_width * COLS + frame_width * 2,
+ font_height * ROWS + frame_width * 2);
+}
+
+
+void EmulLCD::drawContents(QPainter *p)
+{
+ RedrawText(*p);
+}
+
+
+void EmulLCD::SetPainter(QPainter & p)
+{
+ p.setBackgroundMode(OpaqueMode);
+ p.setPen(fg_color);
+ p.setBackgroundColor(bg_color);
+}
+
+
+void EmulLCD::RedrawText(QPainter & p)
+{
+ int r, c;
+
+ SetPainter(p);
+
+ for (r = 0; r < ROWS; r++)
+ for (c = 0; c < COLS; c++)
+ PrintChar(p, r, c);
+}
+
+
+void EmulLCD::PrintChar(QPainter & p, int row, int col)
+{
+ // Fetch char from DD RAM
+ unsigned char c = ddram[row][col];
+
+ // Map some Hitachi characters to ISO Latin1
+ switch(c)
+ {
+ case 0xDF:
+ c = 0xBA; // "degrees" glyph
+ break;
+
+ case 0xE4:
+ c = 0xB5; // "micro" glyph
+ break;
+
+ default: // all others
+ break;
+ }
+
+ // Draw char on display
+ int x = col * font_width + frame_width;
+ int y = row * font_height + frame_width;
+ bool restore_colors = false;
+
+ if (show_cursor && (row == cr_row) && (col == cr_col))
+ {
+ // Exchange FG/BG colors
+ p.setPen(bg_color);
+ p.setBackgroundColor(fg_color);
+ restore_colors = true;
+ }
+
+ p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/,
+ QString(QChar(c)), 1);
+
+ if (restore_colors)
+ {
+ // Restore FG/BG colors
+ p.setPen(fg_color);
+ p.setBackgroundColor(bg_color);
+ }
+}
+
+
+void EmulLCD::MoveCursor(int r, int c)
+{
+ // Save old cursor position
+ int old_row = cr_row;
+ int old_col = cr_col;
+
+ // Move the cursor
+ cgramaddr = -1;
+ cr_row = r;
+ cr_col = c;
+
+ if (show_cursor && (old_col != cr_col || old_row != cr_row))
+ {
+ QPainter p(this);
+ SetPainter(p);
+
+ // Draw new cursor
+ PrintChar(p, cr_row, cr_col);
+
+ // Erase old cursor
+ PrintChar(p, old_row, old_col);
+ }
+}
+
+
+void EmulLCD::ShowCursor(bool show)
+{
+ show_cursor = show;
+
+ // Draw (or erase) cursor
+ QPainter p(this);
+ SetPainter(p);
+ PrintChar(p, cr_row, cr_col);
+}
+
+
+void EmulLCD::AdvanceCursor()
+{
+ // Move the cursor
+ if (cr_col == COLS - 1)
+ {
+ if (cr_row == ROWS - 1)
+ MoveCursor(0, 0);
+ else
+ MoveCursor(cr_row + 1, 0);
+ }
+ else
+ MoveCursor(cr_row, cr_col + 1);
+}
+
+
+void EmulLCD::PutChar(unsigned char c)
+{
+ if (cgramaddr != -1)
+ {
+ // Write data in CGRAM
+ cgram[cgramaddr] = c;
+
+ // Auto increment CGRAM address
+ cgramaddr = (cgramaddr + 1) & 0x3F;
+ }
+ else
+ {
+ // Writing in DDRAM
+ ddram[cr_row][cr_col] = c;
+
+ // Update display
+ {
+ QPainter p(this);
+ SetPainter(p);
+ PrintChar(p, cr_row, cr_col);
+ }
+ AdvanceCursor();
+ }
+}
+
+
+char EmulLCD::GetChar()
+{
+ char c = ddram[cr_row][cr_col];
+ AdvanceCursor();
+ return c;
+}
+
+
+void EmulLCD::Clear()
+{
+ memset(ddram, ' ', sizeof(ddram));
+ cr_row = cr_col = 0;
+
+ QPainter p(this);
+ RedrawText(p);
+}
+
+
+void EmulLCD::SetCGRamAddr(unsigned char addr)
+{
+ cgramaddr = addr & (sizeof(cgram) - 1);
+}
+
+
+// Hitachi LM044L register-level emulation
+
+#define INI_DISPLAY 0x30
+#define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */
+#define ON_DISPLAY 0x0F /* Switch on display */
+#define OFF_DISPLAY 0x08 /* Switch off display */
+#define CLR_DISPLAY 0x01 /* Clear display */
+#define CURSOR_BLOCK 0x0D /* Show cursor (block) */
+#define CURSOR_LINE 0x0F /* Show cursor (line) */
+#define CURSOR_OFF 0x0C /* Hide cursor */
+#define MODE_DISPL 0x06
+#define SHIFT_DISPLAY 0x18
+#define MOVESHIFT_LEFT 0x00
+#define MOVESHIFT_RIGHT 0x04
+#define LCD_CGRAMADDR (1<<6)
+#define LCD_DDRAMADDR (1<<7)
+
+
+extern "C" void Emul_LCDWriteReg(unsigned char d)
+{
+ static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 };
+
+ switch(d)
+ {
+ case CLR_DISPLAY:
+ emul->emulLCD->Clear();
+ break;
+
+ case CURSOR_BLOCK:
+ case CURSOR_LINE:
+ emul->emulLCD->ShowCursor(true);
+ break;
+
+ case CURSOR_OFF:
+ emul->emulLCD->ShowCursor(false);
+ break;
+
+ default:
+ // Set DDRAM address?
+ if (d & LCD_DDRAMADDR)
+ {
+ for (int i = 0; i < EmulLCD::ROWS; i++)
+ {
+ if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS))
+ {
+ emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]);
+ break;
+ }
+ }
+ }
+ else if (d & LCD_CGRAMADDR)
+ emul->emulLCD->SetCGRamAddr(d);
+ break;
+ }
+}
+
+
+extern "C" unsigned char Emul_LCDReadReg(void)
+{
+ return 0; /* This LCD model is never busy ;-) */
+}
+
+
+extern "C" void Emul_LCDWriteData(unsigned char d)
+{
+ emul->emulLCD->PutChar(d);
+}
+
+
+extern "C" unsigned char Emul_LCDReadData(void)
+{
+ return emul->emulLCD->GetChar();
+}
+
+#include "EmulLCD.moc"
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#ifndef EMULLCD_H
+#define EMULLCD_H
+
+#include <qframe.h>
+#include <qfont.h>
+#include <qcolor.h>
+
+// fwd decls
+class QSizePolicy;
+class QPaintEvent;
+class QResizeEvent;
+
+/**
+ * Qt widget to emulate a dot-matrix LCD display.
+ */
+class EmulLCD : public QFrame
+{
+ Q_OBJECT
+
+public:
+// Attributes
+ enum { COLS = 20, ROWS = 4 };
+
+// Construction
+ EmulLCD(QWidget *parent = 0, const char *name = 0);
+ virtual ~EmulLCD();
+
+// Base class overrides
+protected:
+ virtual QSizePolicy sizePolicy() const;
+ virtual QSize sizeHint() const;
+ virtual void drawContents(QPainter *p);
+
+// Operations
+public:
+ void MoveCursor (int col, int row);
+ void ShowCursor (bool show = true);
+ void PutChar (unsigned char c);
+ char GetChar ();
+ void Clear ();
+ void SetCGRamAddr (unsigned char addr);
+
+// Implementation
+protected:
+ void SetPainter(QPainter & p);
+ void RedrawText(QPainter & p);
+ void PrintChar(QPainter & p, int row, int col);
+ void AdvanceCursor();
+
+ QFont lcd_font; ///< Display character font
+ QColor fg_color, bg_color; ///< LCD colors
+ int font_width, font_height; ///< Font dimensions
+ int frame_width; ///< Frame width (and height)
+ int cr_row, cr_col; ///< Cursor position
+ int cgramaddr; ///< CGRAM Address (-1 disabled)
+ unsigned char ddram[ROWS][COLS];///< Display data RAM
+ unsigned char cgram[8*8]; ///< CGRAM
+ bool show_cursor; ///< Cursor enabled?
+};
+
+#endif // !defined(EMULLCD_H)
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Generic text LCD driver (impl.).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/09/20 20:02:43 marco
+ *#* Replaced ISLISTEMPTY with LIST_EMPTY
+ *#*
+ *#* Revision 1.3 2006/07/19 12:56:25 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.2 2006/02/24 00:27:14 bernie
+ *#* Use new naming convention for list macros.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:00:42 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.11 2005/06/14 14:43:43 bernie
+ *#* Add DevLib headers.
+ *#*
+ *#* Revision 1.10 2005/06/06 17:41:57 batt
+ *#* Add lcd_layerSet function.
+ *#*
+ *#* Revision 1.9 2005/06/01 16:40:07 batt
+ *#* Remove debug string.
+ *#*
+ *#* Revision 1.8 2005/06/01 16:38:04 batt
+ *#* Adapt to changes in mware/list.h.
+ *#*
+ *#* Revision 1.7 2005/06/01 10:45:22 batt
+ *#* lcd_setAddr(): Bugfix boundary condition; Misc cleanup.
+ *#*
+ *#* Revision 1.6 2005/06/01 10:36:23 batt
+ *#* Layer: Rename member variables and Doxygenize.
+ *#*
+ *#* Revision 1.5 2005/05/27 11:05:58 batt
+ *#* Do not write on lcd if layer is hidden.
+ *#*/
+
+#include "lcd_text.h"
+#include "lcd_hd44.h"
+#include <drv/timer.h> // timer_delay()
+#include <mware/formatwr.h> // _formatted_write()
+#include <mware/list.h> // LIST_EMPTY()
+#include <cfg/macros.h> // BV()
+#include <cfg/debug.h>
+
+#include <string.h> // strlen()
+
+
+/** Maximum number of layers. */
+#define LCD_LAYERS 6
+
+#if CONFIG_KERNEL
+ /** Semaphore to arbitrate access to the display. */
+ static struct Semaphore lcd_semaphore;
+ #define LOCK_LCD sem_obtain(&lcd_semaphore)
+ #define UNLOCK_LCD sem_release(&lcd_semaphore)
+#else /* !CONFIG_KERNEL */
+ #define LOCK_LCD do {} while (0)
+ #define UNLOCK_LCD do {} while (0)
+#endif /* !CONFIG_KERNEL */
+
+DECLARE_LIST_TYPE(Layer);
+
+Layer *lcd_DefLayer;
+static Layer lcd_LayersPool[LCD_LAYERS];
+static LIST_TYPE(Layer) lcd_Layers;
+static LIST_TYPE(Layer) lcd_FreeLayers;
+
+/**
+ * Current cursor status.
+ *
+ * One of LCD_CMD_CURSOR_OFF, LCD_CMD_CURSOR_BLOCK or LCD_CMD_CURSOR_LINE.
+ */
+static uint8_t lcd_CursorStatus;
+
+/** Current cursor position, encoded as a Cursor position and status. */
+static lcdpos_t lcd_CursorAddr;
+
+
+void lcd_setAddr(Layer *layer, lcdpos_t addr)
+{
+ /* Sanity check: wrap around to display limits */
+ while (addr >= LCD_ROWS * LCD_COLS)
+ addr -= LCD_ROWS * LCD_COLS;
+
+ layer->addr = addr;
+}
+
+#if CONFIG_KERNEL
+
+void lcd_lock(void)
+{
+ LOCK_LCD;
+}
+
+
+void lcd_unlock(void)
+{
+ UNLOCK_LCD;
+}
+
+#endif /* CONFIG_KERNEL */
+
+
+/**
+ * Write one character to the display at the current
+ * cursor prosition, then move the cursor right. The
+ * cursor is wrapped to the next line when it moves
+ * beyond the end of the current line.
+ *
+ * \note Does _NOT_ lock the display semaphore.
+ */
+static void lcd_putCharUnlocked(char c, Layer *layer)
+{
+ Layer *l2;
+ lcdpos_t addr = layer->addr;
+
+ /* Store character in layer buffer */
+ layer->buf[addr] = c;
+
+ /* Move to next character */
+ if (++layer->addr >= LCD_COLS * LCD_ROWS)
+ layer->addr = 0;
+
+ /* Do not write on LCD if layer is hidden. */
+ if (layer->pri == LAYER_HIDDEN)
+ return;
+
+ /*
+ * Check if this location is obscured by
+ * other layers above us.
+ */
+ for (l2 = layer->pred; l2->pred; l2 = l2->pred)
+ {
+ if (l2->buf[addr])
+ {
+ /* DB(kprintf("layer %04x obs %04x at %d\n", l2, layer, addr);) */
+ return;
+ }
+ }
+
+ /* Write character */
+ if (c)
+ lcd_putc(addr, c);
+ else
+ /* FIXME: should look for layers beneath! */
+ lcd_putc(addr, ' ');
+}
+
+
+void lcd_putChar(char c, Layer *layer)
+{
+ LOCK_LCD;
+ lcd_putCharUnlocked(c, layer);
+ UNLOCK_LCD;
+}
+
+void lcd_layerSet(Layer *layer, char c)
+{
+ int i;
+
+ LOCK_LCD;
+ lcd_setAddr(layer, 0);
+ for (i = 0; i < LCD_COLS * LCD_ROWS; i++)
+ lcd_putCharUnlocked(c, layer);
+ UNLOCK_LCD;
+}
+
+
+void lcd_clear(Layer *layer)
+{
+ lcd_layerSet(layer, 0);
+}
+
+
+void lcd_clearLine(Layer *layer, int y)
+{
+ int i;
+
+ LOCK_LCD;
+ lcd_setAddr(layer, LCD_POS(0, y));
+ for (i = 0; i < LCD_COLS; i++)
+ lcd_putCharUnlocked(0, layer);
+ UNLOCK_LCD;
+}
+
+
+void lcd_moveCursor(lcdpos_t addr)
+{
+ LOCK_LCD;
+ lcd_moveTo(addr);
+ UNLOCK_LCD;
+}
+
+
+char lcd_setCursor(char mode)
+{
+ static const char cursor_cmd[3] =
+ {
+ LCD_CMD_CURSOR_OFF, LCD_CMD_CURSOR_BLOCK, LCD_CMD_CURSOR_LINE
+ };
+ char oldmode = lcd_CursorStatus;
+
+ LOCK_LCD;
+ lcd_CursorStatus = mode;
+ lcd_setReg(cursor_cmd[(int)mode]);
+ if (mode)
+ lcd_moveCursor(lcd_CursorAddr);
+ UNLOCK_LCD;
+
+ return oldmode;
+}
+
+
+int lcd_vprintf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, va_list ap)
+{
+ int len;
+
+ LOCK_LCD;
+
+ /*
+ * Se il cursore era acceso, spegnilo durante
+ * l'output per evitare che salti alla posizione
+ * in cui si scrive.
+ */
+ if (lcd_CursorStatus)
+ lcd_setReg(LCD_CMD_CURSOR_OFF);
+
+ /* Spostamento del cursore */
+ lcd_setAddr(layer, addr);
+
+ if (mode & LCD_CENTER)
+ {
+ int pad;
+
+ /*
+ * NOTE: calculating the string lenght BEFORE it gets
+ * printf()-formatted. Real lenght may differ.
+ */
+ pad = (LCD_COLS - strlen(format)) / 2;
+ while (pad--)
+ lcd_putCharUnlocked(' ', layer);
+ }
+
+ len = _formatted_write(format, (void (*)(char, void *))lcd_putCharUnlocked, layer, ap);
+
+ if (mode & (LCD_FILL | LCD_CENTER))
+ while (layer->addr % LCD_COLS)
+ lcd_putCharUnlocked(' ', layer);
+
+ /*
+ * Riaccendi il cursore e riportalo alla
+ * vecchia posizione
+ */
+ if (lcd_CursorStatus)
+ lcd_setCursor(lcd_CursorStatus);
+
+ UNLOCK_LCD;
+
+ return len;
+}
+
+
+int lcd_printf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, ...)
+{
+ int len;
+ va_list ap;
+
+ va_start(ap, format);
+ len = lcd_vprintf(layer, addr, mode, format, ap);
+ va_end(ap);
+
+ return len;
+}
+
+
+/**
+ * Internal function to move a layer between two positions.
+ *
+ * \note The layer must be *already* enqueued in some list.
+ * \note The display must be already locked!
+ */
+static void lcd_enqueueLayer(Layer *layer, char pri)
+{
+ Layer *l2;
+
+ /* Remove layer from whatever list it was in before */
+ REMOVE(layer);
+
+ layer->pri = pri;
+
+ /*
+ * Search for the first layer whose priority
+ * is less or equal to the layer we are adding.
+ */
+ FOREACH_NODE(l2, &lcd_Layers)
+ if (l2->pri <= pri)
+ break;
+
+ /* Enqueue layer */
+ INSERT_BEFORE(layer, l2);
+}
+
+Layer *lcd_newLayer(char pri)
+{
+ Layer *layer;
+
+ LOCK_LCD;
+
+ if (LIST_EMPTY(&lcd_FreeLayers))
+ {
+ UNLOCK_LCD;
+ //ASSERT(false);
+ return NULL;
+ }
+
+ layer = (Layer *)LIST_HEAD(&lcd_FreeLayers);
+ layer->addr = 0;
+ memset(layer->buf, 0, LCD_ROWS * LCD_COLS);
+
+ lcd_enqueueLayer(layer, pri);
+
+ UNLOCK_LCD;
+ return layer;
+}
+
+/**
+ * Redraw the display (internal).
+ *
+ * \note The display must be already locked.
+ */
+static void lcd_refresh(void)
+{
+ lcdpos_t addr;
+ Layer *l;
+
+ for (addr = 0; addr < LCD_ROWS * LCD_COLS; ++addr)
+ {
+ FOREACH_NODE(l, &lcd_Layers)
+ {
+ //kprintf("%d %x %p\n", addr, l->buf[0], l);
+ if (l->pri == LAYER_HIDDEN)
+ break;
+
+ if (l->buf[addr])
+ {
+ /* Refresh location */
+ lcd_putc(addr, l->buf[addr]);
+ goto done;
+ }
+ }
+
+ /* Draw background */
+ lcd_putc(addr, ' ');
+ done:
+ ;
+ }
+}
+
+/**
+ * Rearrange layer depth and refresh display accordingly.
+ *
+ * \note Setting a priority of LAYER_HIDDEN makes the layer invisible.
+ */
+void lcd_setLayerDepth(Layer *layer, char pri)
+{
+ if (pri != layer->pri)
+ {
+ LOCK_LCD;
+ lcd_enqueueLayer(layer, pri);
+ /* Vile but simple */
+ lcd_refresh();
+ UNLOCK_LCD;
+ }
+}
+
+void lcd_deleteLayer(Layer *layer)
+{
+ LOCK_LCD;
+
+/* We use lcd_refresh() instead. Much simpler than this mess, but slower. */
+#if 0
+ Layer *l2;
+ lcdpos_t addr;
+
+ /* Repair damage on underlaying layers */
+ for (addr = 0; addr < LCD_ROWS * LCD_COLS; ++addr)
+ {
+ /* If location was covered by us */
+ if (layer->buf[addr])
+ {
+ /* ...and it wasn't covered by others above us... */
+ for (l2 = layer->pred; l2->pred; l2 = l2->pred)
+ if (l2->buf[addr])
+ /* can't just break here! */
+ goto not_visible;
+
+ /* ...scan underlaying layers to repair damage */
+ for (l2 = layer->succ; l2->succ; l2 = l2->succ)
+ if (l2->buf[addr])
+ {
+ /* Refresh character */
+ lcd_putc(addr, l2->buf[addr]);
+
+ /* No need to search on deeper layers */
+ break;
+ }
+
+ not_visible:
+ ;
+ }
+ }
+#endif
+
+ // Remove layer from lcd_Layers list.
+ REMOVE(layer);
+
+ /* Put layer back into free list */
+ ADDHEAD(&lcd_FreeLayers, layer);
+
+ lcd_refresh();
+
+ UNLOCK_LCD;
+}
+
+
+static void lcd_setDefLayer(Layer *layer)
+{
+ lcd_DefLayer = layer;
+}
+
+#include <cfg/debug.h>
+void lcd_init(void)
+{
+ int i;
+
+ LIST_INIT(&lcd_Layers);
+ LIST_INIT(&lcd_FreeLayers);
+ for (i = 0; i < LCD_LAYERS; ++i)
+ ADDHEAD(&lcd_FreeLayers, &lcd_LayersPool[i]);
+
+ lcd_setDefLayer(lcd_newLayer(0));
+
+ lcd_hw_init();
+
+ lcd_setCursor(0);
+}
+
+#if CONFIG_TEST
+void lcd_test(void)
+{
+ int i;
+
+ for (i = 0; i < LCD_ROWS * LCD_COLS; ++i)
+ {
+ lcd_putCharUnlocked('0' + (i % 10), lcd_DefLayer);
+ timer_delay(100);
+ }
+}
+#endif /* CONFIG_TEST */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Generic text LCD driver (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.3 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.2 2006/02/23 10:59:14 bernie
+ *#* Documentation fixes.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:00:42 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.5 2005/06/14 14:43:43 bernie
+ *#* Add DevLib headers.
+ *#*
+ *#* Revision 1.4 2005/06/06 17:41:57 batt
+ *#* Add lcd_layerSet function.
+ *#*
+ *#* Revision 1.3 2005/06/01 10:36:23 batt
+ *#* Layer: Rename member variables and Doxygenize.
+ *#*
+ *#* Revision 1.2 2005/05/26 08:31:23 batt
+ *#* Add layer hiding/showing.
+ *#*
+ *#* Revision 1.1 2005/05/24 09:17:58 batt
+ *#* Move drivers to top-level.
+ *#*/
+
+#ifndef DRV_LCD_H
+#define DRV_LCD_H
+
+#include "lcd_hd44.h"
+
+#include <cfg/macros.h>
+#include <cfg/compiler.h>
+#include <mware/list.h>
+
+#include <stdarg.h> // vprintf()
+
+
+/* flags for lcd_printf() */
+#define LCD_NORMAL 0 /* Scrittura normale */
+#define LCD_FILL BV(0) /* Fill rest of line with spaces */
+#define LCD_CENTER BV(1) /* Center string in line */
+#define LCD_NOCURSOR BV(2) /* Scrittura senza spostamento cursore */
+
+/** Special priority value for lcd_setLayerDepth(). */
+#define LAYER_HIDDEN -128
+
+/* Compute LCD address from x/y coordinates */
+#define LCD_POS(x,y) ((lcdpos_t)((uint8_t)(x) + (uint8_t)(y) * (uint8_t)LCD_COLS))
+#define LCD_ROW0 (LCD_COLS * 0)
+#define LCD_ROW1 (LCD_COLS * 1)
+#define LCD_ROW2 (LCD_COLS * 2)
+#define LCD_ROW3 (LCD_COLS * 3)
+
+/**
+ * Overwrapping layer context.
+ */
+typedef struct _Layer
+{
+ /**
+ * Active layers are linked together in a list
+ * sorted in top to bottom order.
+ */
+ DECLARE_NODE_ANON(struct _Layer)
+
+ /** Current XY address into this layer, for write operations. */
+ lcdpos_t addr;
+
+ /** Priority of this layer (greater in front of lesser). */
+ char pri;
+
+ /**
+ * Layer backing store buffer.
+ *
+ * All writes through the layer are copied into this buffer.
+ * Characters cells with value 0 are transparent with respect
+ * to other layers in the background.
+ */
+ char buf[LCD_COLS * LCD_ROWS];
+} Layer;
+
+
+/* Global variables */
+extern Layer *lcd_DefLayer;
+
+/* Function prototypes */
+extern void lcd_init(void);
+extern void lcd_test(void);
+
+extern void lcd_moveCursor(lcdpos_t addr);
+extern char lcd_setCursor(char state);
+
+extern void lcd_setAddr(Layer *layer, lcdpos_t addr);
+extern void lcd_putChar(char c, Layer *layer);
+extern int lcd_vprintf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, va_list ap) FORMAT(printf, 4, 0);
+extern int lcd_printf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, ...) FORMAT(printf, 4, 5);
+extern void lcd_clear(Layer *layer);
+extern void lcd_layerSet(Layer *layer, char c);
+extern void lcd_clearLine(Layer *layer, int y);
+
+extern void lcd_setLayerDepth(Layer *layer, char pri);
+extern Layer *lcd_newLayer(char pri);
+extern void lcd_deleteLayer(Layer *layer);
+extern void lcd_lock(void);
+extern void lcd_unlock(void);
+
+#endif /* DRV_LCD_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief MCP41xxx digital potentiomenter driver (implementation)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#include <drv/timer.h>
+
+#include <cfg/macros.h>
+#include <cfg/compiler.h>
+
+#include <hw_mcp41.h>
+#include <drv/mcp41.h>
+#include <drv/ser.h>
+
+static Serial *spi_ser;
+
+/**
+ * Set resitance for digital pot \a dev
+ */
+void mcp41_setResistance(Mcp41Dev dev, mcp41_res_t res)
+{
+ MCP41_ON(dev);
+ /* send command byte */
+ ser_putchar(MCP41_WRITE_DATA, spi_ser);
+ ser_putchar(((MCP41_HW_MAX * (uint32_t)res) + (MCP41_MAX / 2)) / MCP41_MAX, spi_ser);
+ ser_drain(spi_ser);
+
+ MCP41_OFF(dev);
+}
+
+
+/**
+ * Initialize mcp41 potentiometer driver
+ */
+void mcp41_init(Serial *spi_port)
+{
+ Mcp41Dev dev;
+
+ /* Init all potentiometer ports */
+ for (dev = 0; dev < MCP41_CNT; dev++)
+ {
+ SET_MCP41_DDR(dev);
+ MCP41_OFF(dev);
+ }
+
+ spi_ser = spi_port;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief MCP41xxx digital potentiomenter driver (interface)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef DRV_MCP41_H
+#define DRV_MCP41_H
+
+#include <hw/mcp41_map.h>
+#include <cfg/compiler.h>
+#include <drv/ser.h>
+
+#define MCP41_WRITE_DATA 0x11
+#define MCP41_HW_MAX 255
+#define MCP41_MAX 999
+
+/**
+ * Type for digital potentiometer resistance.
+ */
+typedef uint16_t mcp41_res_t;
+
+void mcp41_setResistance(Mcp41Dev dev, mcp41_res_t res);
+void mcp41_init(Serial *spi_port);
+
+#endif /* DRV_MCP41_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005 Develer S.r.l. (http://www.de+veler.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Driver for NTC (reads a temperature through an ADC)
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ *
+ * This module handles an external NTC bound to an AD converter. As usual,
+ * it relies on a low-level API (ntc_hw_*) (see below):
+ *
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 17:59:47 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.1 2005/05/24 09:17:58 batt
+ *#* Move drivers to top-level.
+ *#*/
+
+#include <drv/ntc.h>
+#include <hw_ntc.h>
+#include <ntc_map.h>
+
+#include <cfg/debug.h>
+
+DB(bool ntc_initialized;)
+
+/**
+ * Find in a table of values \a orig_table of size \a size, the index which
+ * value is less or equal to \a val.
+ *
+ * \retval 0 When \a val is higher than the first table entry.
+ * \retval size When \a val is lower than the last table entry.
+ * \retval 1..size-1 When \a val is within the table.
+ */
+static size_t upper_bound(const res_t *orig_table, size_t size, res_t val)
+{
+ const res_t *table = orig_table;
+
+ while (size)
+ {
+ size_t pos = size / 2;
+ if (val > table[pos])
+ size = pos;
+ else
+ {
+ table += pos+1;
+ size -= pos+1;
+ }
+ }
+
+ return table - orig_table;
+}
+
+
+/**
+ * Read the temperature for the NTC channel \a dev.
+ * First read the resistence of the NTC through ntc_hw_read(), then,
+ * for the conversion from resistance to temperature, since the formula
+ * varies from device to device, we implemented a generic system using
+ * a table of data which maps temperature (index) to resistance (data).
+ * The range of the table (min/max temperature) and the step
+ * (temperature difference between two consecutive elements of the table)
+ * is variable and can be specified. Notice that values inbetween the
+ * table elements are still possible as the library does a linear
+ * interpolation using the actual calculated resistance to find out
+ * the exact temperature.
+ *
+ * The low-level API provides a function to get access to a description
+ * of the NTC (ntc_hw_getInfo()), including the resistance table.
+ *
+ */
+deg_t ntc_read(NtcDev dev)
+{
+ const NtcHwInfo* hw = ntc_hw_getInfo(dev);
+ const res_t* r = hw->resistances;
+
+ float rx;
+ size_t i;
+ deg_t degrees;
+
+ rx = ntc_hw_read(dev);
+
+
+ i = upper_bound(r, hw->num_resistances, rx);
+ ASSERT(i <= hw->num_resistances);
+
+ if (i >= hw->num_resistances)
+ return NTC_SHORT_CIRCUIT;
+ else if (i == 0)
+ return NTC_OPEN_CIRCUIT;
+
+ /*
+ * Interpolated value in 0.1 degrees multiplied by 10:
+ * delta t step t
+ * ---------- = ----------------
+ * (rx - r[i]) (r[i-1] - r [i])
+ */
+ float tmp;
+ tmp = 10 * hw->degrees_step * (rx - r[i]) / (r[i - 1] - r[i]);
+
+ /*
+ * degrees = integer part corresponding to the superior index
+ * in the table multiplied by 10
+ * - decimal part interpolated (already multiplied by 10)
+ */
+ degrees = (i * hw->degrees_step + hw->degrees_min) * 10 - (int)(tmp);
+
+ //kprintf("dev= %d, I=%d, degrees = %d\n", dev, i , degrees);
+
+ return degrees;
+}
+
+
+/**
+ * Init NTC hardware.
+ */
+void ntc_init(void)
+{
+ NTC_HW_INIT;
+ DB(ntc_initialized = true;)
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Driver for NTC (reads a temperature through an ADC)
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 17:59:47 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/10 08:56:47 batt
+ *#* Avoid calling DEG_T_TO_DEG().
+ *#*
+ *#* Revision 1.2 2005/06/10 08:54:58 batt
+ *#* Rename deg_t conversion macros to accomplish coding standard.
+ *#*
+ *#* Revision 1.1 2005/05/24 09:17:58 batt
+ *#* Move drivers to top-level.
+ *#*/
+
+#ifndef DRV_NTC_H
+#define DRV_NTC_H
+
+#include <ntc_map.h>
+#include <cfg/debug.h>
+#include <cfg/compiler.h>
+
+#define NTC_OPEN_CIRCUIT -32768
+#define NTC_SHORT_CIRCUIT 32767
+
+typedef int16_t deg_t; /** type for celsius degrees deg_t = °C * 10 */
+
+/** Macro for converting from deg to deg_t type */
+#define DEG_TO_DEG_T(x) ((deg_t)((x) * 10))
+
+/** Macro for converting from deg_t to celsius degrees (returns only the integer part) */
+#define DEG_T_TO_INTDEG(x) ((x) / 10)
+
+/** Macro for converting from deg_t to celsius degrees (returns only the decimal part) */
+#define DEG_T_TO_DECIMALDEG(x) ((x) % 10)
+
+/** Macro for converting from deg_t to celsius degrees (returns type is float) */
+#define DEG_T_TO_FLOATDEG(x) ((x) / 10.0)
+
+
+typedef uint32_t res_t; /** type for resistor res_t = Ohm * 100 */
+typedef float amp_t; /** type for defining amplifications amp_t = A, where A is a pure number */
+
+DB(extern bool ntc_initialized;)
+
+
+/** Describe a NTC chip */
+typedef struct NtcHwInfo
+{
+ const res_t *resistances; ///< resistances of the NTC (ohms * 100)
+ size_t num_resistances; ///< number of resistances
+ deg_t degrees_min; ///< degrees corresponding to the first entry in the table (celsius * 10)
+ deg_t degrees_step; ///< difference in degrees between two consecutive elements in the table (celsius * 10)
+} NtcHwInfo;
+
+/** Initialize the NTC module */
+void ntc_init(void);
+
+/** Read a single temperature value from the NTC */
+deg_t ntc_read(NtcDev dev);
+
+#endif /* DRV_NTC_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Phase control driver (implementation)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#include <drv/timer.h>
+
+
+#include <cfg/macros.h>
+#include <cpu/irq.h>
+#include <cpu/types.h>
+#include <cfg/compiler.h>
+
+
+#include <hw_phase.h>
+#include <drv/phase.h>
+
+#include <math.h>
+
+/** Array of triacs */
+static Triac triacs[TRIAC_CNT];
+
+DB(bool phase_initialized;)
+
+/**
+ * Zerocross interrupt, call when 220V cross zero.
+ *
+ * This function turn off all triacs that have duty < 100%
+ * and arm the triac timers for phase control.
+ * This function is frequency adaptive so can work both at 50 or 60Hz.
+ */
+DEFINE_ZEROCROSS_ISR()
+{
+ ticks_t period, now;
+ static ticks_t prev_time;
+ TriacDev dev;
+
+ now = timer_clock_unlocked();
+ period = now - prev_time;
+
+ for (dev = 0; dev < TRIAC_CNT; dev++)
+ {
+ /* Only turn off triac if duty is != 100% */
+ if (triacs[dev].duty != TRIAC_MAX_DUTY)
+ TRIAC_OFF(dev);
+ /* Compute delay from duty */
+ timer_setDelay(&triacs[dev].timer, DIV_ROUND(period * (TRIAC_MAX_DUTY - triacs[dev].duty), TRIAC_MAX_DUTY));
+
+ /* This check avoids inserting the same timer twice
+ * in case of an intempestive zerocross or spike */
+ if (triacs[dev].running)
+ {
+ timer_abort(&triacs[dev].timer);
+ //kprintf("[%lu]\n", timer_clock());
+ }
+
+ triacs[dev].running = true;
+ timer_add(&triacs[dev].timer);
+ }
+ prev_time = now;
+}
+
+
+
+/**
+ * Set duty of the triac channel \a dev (interrupt safe).
+ */
+void phase_setDuty(TriacDev dev, triac_duty_t duty)
+{
+ cpuflags_t flags;
+ IRQ_SAVE_DISABLE(flags);
+
+ phase_setDutyUnlock(dev,duty);
+
+ IRQ_RESTORE(flags);
+}
+
+
+
+/**
+ * Set duty of the triac channel \a dev (NOT INTERRUPT SAFE).
+ */
+void phase_setDutyUnlock(TriacDev dev, triac_duty_t duty)
+{
+ triacs[dev].duty = MIN(duty, (triac_duty_t)TRIAC_MAX_DUTY);
+}
+
+
+
+/**
+ * Set power of the triac channel \a dev (interrupt safe).
+ *
+ * This function approsimate the sine wave to a triangular wave to compute
+ * RMS power.
+ */
+void phase_setPower(TriacDev dev, triac_power_t power)
+{
+ bool greater_fifty = false;
+ triac_duty_t duty;
+
+ power = MIN(power, (triac_power_t)TRIAC_MAX_POWER);
+
+ if (power > TRIAC_MAX_POWER / 2)
+ {
+ greater_fifty = true;
+ power = TRIAC_MAX_POWER - power;
+ }
+
+ duty = TRIAC_POWER_K * sqrt(power);
+
+ if (greater_fifty)
+ duty = TRIAC_MAX_DUTY - duty;
+ phase_setDuty(dev, duty);
+}
+
+
+
+/**
+ * Soft int for each \a _dev triac.
+ *
+ * The triacs are turned on at different time to achieve phase control.
+ */
+static void phase_softint(void *_dev)
+{
+ TriacDev dev = (TriacDev)_dev;
+
+ /* Only turn on if duty is !=0 */
+ if (triacs[dev].duty)
+ TRIAC_ON(dev);
+ triacs[dev].running = false;
+}
+
+
+
+/**
+ * Initialize phase control driver
+ */
+void phase_init(void)
+{
+ cpuflags_t flags;
+ TriacDev dev;
+
+ /* Init timers and ensure that all triac are off */
+ for (dev = 0; dev < TRIAC_CNT; dev++)
+ {
+ triacs[dev].duty = 0;
+ triacs[dev].running = false;
+ SET_TRIAC_DDR(dev);
+ TRIAC_OFF(dev);
+ timer_set_event_softint(&triacs[dev].timer, (Hook)phase_softint, (void *)dev);
+ }
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Init zero cross interrupt */
+ PHASE_HW_INIT;
+ DB(phase_initialized = true;)
+ IRQ_RESTORE(flags);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Phase control driver (interface)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:06:44 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.1 2005/05/24 09:17:58 batt
+ *#* Move drivers to top-level.
+ *#*
+ *#* Revision 1.9 2005/05/09 16:34:14 batt
+ *#* Change some function names to accomplish coding standard; Add debug phase_initialized; Change duty_t and power_t to uint16_t.
+ *#*
+ *#* Revision 1.8 2005/05/02 12:37:33 batt
+ *#* Split hw triac map in phase_map.h.
+ *#*
+ *#* Revision 1.7 2005/05/02 09:05:03 batt
+ *#* Rename duty_t and power_t in triac_duty_t and triac_power_t
+ *#*
+ *#* Revision 1.6 2005/04/28 15:10:11 batt
+ *#* Use timer API to add and set events.
+ *#*
+ *#* Revision 1.5 2005/04/28 12:04:46 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.4 2005/04/28 10:35:45 batt
+ *#* Complete phase_setpower.
+ *#*
+ *#* Revision 1.3 2005/04/27 19:23:40 batt
+ *#* Reformat.
+ *#*
+ *#* Revision 1.1 2005/04/27 17:13:56 batt
+ *#* Add triac phase control driver.
+ *#*
+ *#*/
+
+
+#ifndef DRV_PHASE_H
+#define DRV_PHASE_H
+
+#include <drv/timer.h>
+#include <phase_map.h>
+#include <cfg/debug.h>
+
+#define TRIAC_MAX_DUTY 100
+#define TRIAC_MAX_POWER 100
+#define TRIAC_POWER_K TRIAC_MAX_DUTY * (1 / sqrt(2 * TRIAC_MAX_POWER))
+
+/**
+ * \name Types for duty and power.
+ * \{
+ */
+typedef uint16_t triac_duty_t;
+typedef uint16_t triac_power_t;
+/* \} */
+
+
+DB(extern bool phase_initialized;)
+
+/**
+ * \name Type for triac control.
+ * \{
+ */
+typedef struct Triac
+{
+ Timer timer; /**< Timer for phase control. */
+ triac_duty_t duty; /**< Duty cycle of the channel. */
+ bool running; /**< True when the timer is active. */
+} Triac;
+/* \} */
+
+void phase_setDutyUnlock(TriacDev dev, triac_duty_t duty);
+void phase_setDuty(TriacDev dev, triac_duty_t duty);
+void phase_setPower(TriacDev dev, triac_power_t power);
+
+void phase_init(void);
+
+
+#endif /* DRV_PHASE_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ *
+ * \brief PWM driver (implementation)
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+#include <cpu/types.h>
+#include <cpu/irq.h>
+
+#include <drv/pwm.h>
+#include <drv/pwm_at91.h>
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+
+/**
+ * Set duty of pwm channel \p dev.
+ */
+void pwm_setDuty(PwmDev dev, pwm_duty_t duty)
+{
+ pwm_period_t period = 0;
+ pwm_duty_t real_duty = 0;
+
+ duty = MIN(duty, (pwm_duty_t)PWM_MAX_DUTY);
+
+ period = pwm_hw_getPeriod(dev);
+
+ real_duty = (uint64_t)(duty * period) >> (uint64_t)PWM_MAX_PERIOD_LOG2;
+
+// kprintf("real_duty[%d] duty[%d], period[%d]\n", real_duty, duty, period);
+ pwm_hw_setDutyUnlock(dev, real_duty);
+}
+
+/**
+ * Set frequency of pwm channel \p dev at \p freq in Hz.
+ */
+void pwm_setFrequency(PwmDev dev, pwm_freq_t freq)
+{
+ pwm_hw_setFrequency(dev, freq);
+}
+
+/**
+ * Set duty of pwm channel \p dev.
+ */
+void pwm_enable(PwmDev dev, bool state)
+{
+ if (state)
+ pwm_hw_enable(dev);
+ else
+ pwm_hw_disable(dev);
+}
+
+/**
+ * Initialize PWM hw.
+ */
+void pwm_init(void)
+{
+ cpuflags_t flags;
+ PwmDev dev;
+
+ IRQ_SAVE_DISABLE(flags);
+
+ /* set all pwm to 0 */
+ for (dev = 0; dev < PWM_CNT; dev++)
+ pwm_setDuty(dev, 0);
+
+ pwm_hw_init();
+
+ IRQ_RESTORE(flags);
+}
+
+
+
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief PWM driver (interface)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef DRV_PWM_H
+#define DRV_PWM_H
+
+#include <pwm_map.h>
+#include <cfg/compiler.h>
+
+typedef uint16_t pwm_duty_t;
+
+void pwm_setDuty(PwmDev dev, pwm_duty_t duty);
+void pwm_init(void);
+
+#define PWM_MAX_DUTY 100
+
+#endif /* DRV_PWM_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ *
+ * \brief Test for PWM driver (implementation)
+ *
+ * \version $Id$
+ *
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+#include <cpu/types.h>
+#include <cpu/irq.h>
+
+#include <drv/pwm.h>
+#include <drv/pwm_at91.h>
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+/*
+ * Esample of value for duty cycle"
+ *
+ * - 100% => 0xFFFFFFFF
+ * - 80% => 0xCCCCCCCC
+ * - 75% => 0xBFFFFFFF
+ * - 50% => 0x7FFFFFFF
+ * - 25% => 0x3FFFFFFF
+ * - 33% => 0x55555555
+ * - 16% => 0x2AAAAAAA
+ */
+
+#define PWM_TEST_CH0 0
+#define PWM_TEST_CH0_FREQ 100UL // 100Hz
+#define PWM_TEST_CH0_DUTY 0xCCCC // 80%
+
+#define PWM_TEST_CH1 1
+#define PWM_TEST_CH1_FREQ 1000UL // 1000Hz
+#define PWM_TEST_CH1_DUTY 0xBFFF // 75%
+
+#define PWM_TEST_CH2 2
+#define PWM_TEST_CH2_FREQ 12356 // 12356Hz
+#define PWM_TEST_CH2_DUTY 0x7FFF // 50%
+
+#define PWM_TEST_CH3 3
+#define PWM_TEST_CH3_FREQ 100000UL // 100KHz
+#define PWM_TEST_CH3_DUTY 0x5555 // 33%
+
+#define PWM_TEST_CH_SET(index) \
+ do { \
+ pwm_setFrequency(PWM_TEST_CH##index , PWM_TEST_CH##index##_FREQ); \
+ pwm_setDuty(PWM_TEST_CH##index, PWM_TEST_CH##index##_DUTY); \
+ pwm_enable(PWM_TEST_CH##index, true); \
+ } while (0)
+
+/**
+ * Test suit for genation of pwm waveform.
+ *
+ */
+void pwm_test(void)
+{
+
+ pwm_init();
+ kputs("Init pwm..\n");
+
+ PWM_TEST_CH_SET(0);
+ kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH0, PWM_TEST_CH0_FREQ, PWM_TEST_CH0_DUTY);
+ PWM_TEST_CH_SET(1);
+ kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH1, PWM_TEST_CH1_FREQ, PWM_TEST_CH1_DUTY);
+ PWM_TEST_CH_SET(2);
+ kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH2, PWM_TEST_CH2_FREQ, PWM_TEST_CH2_DUTY);
+ PWM_TEST_CH_SET(3);
+ kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH3, PWM_TEST_CH3_FREQ, PWM_TEST_CH3_DUTY);
+}
+
+
+
+
+
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \brief Buffered serial I/O driver
+ *
+ * The serial rx interrupt buffers incoming data in a software FIFO
+ * to decouple the higher level protocols from the line speed.
+ * Outgoing data is buffered as well for better performance.
+ * This driver is not optimized for best performance, but it
+ * has proved to be fast enough to handle transfer rates up to
+ * 38400bps on a 16MHz 80196.
+ *
+ * MODULE CONFIGURATION
+ *
+ * \li \c CONFIG_SER_HWHANDSHAKE - set to 1 to enable RTS/CTS handshake.
+ * Support is incomplete/untested.
+ * \li \c CONFIG_SER_TXTIMEOUT - Enable software serial transmission timeouts
+ *
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "ser.h"
+#include "wdt.h"
+#include "ser_p.h"
+#include <mware/formatwr.h>
+#include <cfg/debug.h>
+#include <appconfig.h>
+
+#include <string.h> /* memset */
+
+/*
+ * Sanity check for config parameters required by this module.
+ */
+#if !defined(CONFIG_KERNEL) || ((CONFIG_KERNEL != 0) && CONFIG_KERNEL != 1)
+ #error CONFIG_KERNEL must be set to either 0 or 1 in config.h
+#endif
+#if !defined(CONFIG_SER_RXTIMEOUT)
+ #error CONFIG_SER_TXTIMEOUT missing in config.h
+#endif
+#if !defined(CONFIG_SER_RXTIMEOUT)
+ #error CONFIG_SER_RXTIMEOUT missing in config.h
+#endif
+#if !defined(CONFIG_SER_DEFBAUDRATE)
+ #error CONFIG_SER_DEFBAUDRATE missing in config.h
+#endif
+
+#if CONFIG_KERNEL
+ #include <kern/proc.h>
+#endif
+
+#if CONFIG_SER_TXTIMEOUT != -1 || CONFIG_SER_RXTIMEOUT != -1
+ #include <drv/timer.h>
+#endif
+
+
+struct Serial ser_handles[SER_CNT];
+
+/**
+ * Insert \a c in tx FIFO buffer.
+ * \note This function will switch out the calling process
+ * if the tx buffer is full. If the buffer is full
+ * and \a port->txtimeout is 0 return EOF immediatly.
+ *
+ * \return EOF on error or timeout, \a c otherwise.
+ */
+static int ser_putchar(int c, struct Serial *port)
+{
+ if (fifo_isfull_locked(&port->txfifo))
+ {
+#if CONFIG_SER_TXTIMEOUT != -1
+ /* If timeout == 0 we don't want to wait */
+ if (port->txtimeout == 0)
+ return EOF;
+
+ ticks_t start_time = timer_clock();
+#endif
+
+ /* Wait while buffer is full... */
+ do
+ {
+ wdt_reset();
+#if CONFIG_KERNEL && CONFIG_KERN_SCHED
+ /* Give up timeslice to other processes. */
+ proc_switch();
+#endif
+#if CONFIG_SER_TXTIMEOUT != -1
+ if (timer_clock() - start_time >= port->txtimeout)
+ {
+ ATOMIC(port->status |= SERRF_TXTIMEOUT);
+ return EOF;
+ }
+#endif /* CONFIG_SER_TXTIMEOUT */
+ }
+ while (fifo_isfull_locked(&port->txfifo));
+ }
+
+ fifo_push_locked(&port->txfifo, (unsigned char)c);
+
+ /* (re)trigger tx interrupt */
+ port->hw->table->txStart(port->hw);
+
+ /* Avoid returning signed extended char */
+ return (int)((unsigned char)c);
+}
+
+
+/**
+ * Fetch a character from the rx FIFO buffer.
+ * \note This function will switch out the calling process
+ * if the rx buffer is empty. If the buffer is empty
+ * and \a port->rxtimeout is 0 return EOF immediatly.
+ *
+ * \return EOF on error or timeout, \a c otherwise.
+ */
+static int ser_getchar(struct Serial *port)
+{
+ if (fifo_isempty_locked(&port->rxfifo))
+ {
+#if CONFIG_SER_RXTIMEOUT != -1
+ /* If timeout == 0 we don't want to wait for chars */
+ if (port->rxtimeout == 0)
+ return EOF;
+
+ ticks_t start_time = timer_clock();
+#endif
+ /* Wait while buffer is empty */
+ do
+ {
+ wdt_reset();
+#if CONFIG_KERNEL && CONFIG_KERN_SCHED
+ /* Give up timeslice to other processes. */
+ proc_switch();
+#endif
+#if CONFIG_SER_RXTIMEOUT != -1
+ if (timer_clock() - start_time >= port->rxtimeout)
+ {
+ ATOMIC(port->status |= SERRF_RXTIMEOUT);
+ return EOF;
+ }
+#endif /* CONFIG_SER_RXTIMEOUT */
+ }
+ while (fifo_isempty_locked(&port->rxfifo) && (ser_getstatus(port) & SERRF_RX) == 0);
+ }
+
+ /*
+ * Get a byte from the FIFO (avoiding sign-extension),
+ * re-enable RTS, then return result.
+ */
+ if (ser_getstatus(port) & SERRF_RX)
+ return EOF;
+ return (int)(unsigned char)fifo_pop_locked(&port->rxfifo);
+}
+
+/**
+ * Fetch a character from the rx FIFO buffer.
+ * If the buffer is empty, ser_getchar_nowait() returns
+ * EOF immediatly.
+ * \note Deprecated, use ser_getchar with rx_timeout set to 0.
+ */
+int ser_getchar_nowait(struct KFileSerial *fd)
+{
+ if (fifo_isempty_locked(&fd->ser->rxfifo))
+ return EOF;
+
+ /* NOTE: the double cast prevents unwanted sign extension */
+ return (int)(unsigned char)fifo_pop_locked(&fd->ser->rxfifo);
+}
+
+
+
+/**
+ * Read at most \a size bytes from \a port and put them in \a buf
+ *
+ * \return number of bytes actually read.
+ */
+static size_t ser_read(struct KFile *fd, void *_buf, size_t size)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+
+ size_t i = 0;
+ char *buf = (char *)_buf;
+ int c;
+
+ while (i < size)
+ {
+ if ((c = ser_getchar(fds->ser)) == EOF)
+ break;
+ buf[i++] = c;
+ }
+
+ return i;
+}
+
+/**
+ * \brief Write a buffer to serial.
+ *
+ * \return 0 if OK, EOF in case of error.
+ *
+ * \todo Optimize with fifo_pushblock()
+ */
+static size_t ser_write(struct KFile *fd, const void *_buf, size_t size)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+ const char *buf = (const char *)_buf;
+ size_t i = 0;
+
+ while (size--)
+ {
+ if (ser_putchar(*buf++, fds->ser) == EOF)
+ break;
+ i++;
+ }
+ return i;
+}
+
+
+#if CONFIG_SER_RXTIMEOUT != -1 || CONFIG_SER_TXTIMEOUT != -1
+void ser_settimeouts(struct KFileSerial *fd, mtime_t rxtimeout, mtime_t txtimeout)
+{
+ fd->ser->rxtimeout = ms_to_ticks(rxtimeout);
+ fd->ser->txtimeout = ms_to_ticks(txtimeout);
+}
+#endif /* CONFIG_SER_RXTIMEOUT || CONFIG_SER_TXTIMEOUT */
+
+#if CONFIG_SER_RXTIMEOUT != -1
+/**
+ * Discard input to resynchronize with remote end.
+ *
+ * Discard incoming data until the port stops receiving
+ * characters for at least \a delay milliseconds.
+ *
+ * \note Serial errors are reset before and after executing the purge.
+ */
+void ser_resync(struct KFileSerial *fd, mtime_t delay)
+{
+ mtime_t old_rxtimeout = ticks_to_ms(fd->ser->rxtimeout);
+
+ ser_settimeouts(fd, delay, ticks_to_ms(fd->ser->txtimeout));
+ do
+ {
+ ser_setstatus(fd->ser, 0);
+ ser_getchar(fd->ser);
+ }
+ while (!(ser_getstatus(fd->ser) & SERRF_RXTIMEOUT));
+
+ /* Restore port to an usable status */
+ ser_setstatus(fd->ser, 0);
+ ser_settimeouts(fd, old_rxtimeout, ticks_to_ms(fd->ser->txtimeout));
+}
+#endif /* CONFIG_SER_RXTIMEOUT */
+
+
+void ser_setbaudrate(struct KFileSerial *fd, unsigned long rate)
+{
+ fd->ser->hw->table->setBaudrate(fd->ser->hw, rate);
+}
+
+
+void ser_setparity(struct KFileSerial *fd, int parity)
+{
+ fd->ser->hw->table->setParity(fd->ser->hw, parity);
+}
+
+static int ser_error(struct KFile *fd)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+ return ser_getstatus(fds->ser);
+}
+
+static void ser_clearerr(struct KFile *fd)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+ ser_setstatus(fds->ser, 0);
+}
+
+
+
+/**
+ * Flush both the RX and TX buffers.
+ */
+void ser_purge(struct KFileSerial *fd)
+{
+ ser_purgeRx(fd);
+ ser_purgeTx(fd);
+}
+
+/**
+ * Flush RX buffer.
+ */
+void ser_purgeRx(struct KFileSerial *fd)
+{
+ fifo_flush_locked(&fd->ser->rxfifo);
+}
+
+/**
+ * Flush TX buffer.
+ */
+void ser_purgeTx(struct KFileSerial *fd)
+{
+ fifo_flush_locked(&fd->ser->txfifo);
+}
+
+
+/**
+ * Wait until all pending output is completely
+ * transmitted to the other end.
+ *
+ * \note The current implementation only checks the
+ * software transmission queue. Any hardware
+ * FIFOs are ignored.
+ */
+static int ser_flush(struct KFile *fd)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+
+ /*
+ * Wait until the FIFO becomes empty, and then until the byte currently in
+ * the hardware register gets shifted out.
+ */
+ while (!fifo_isempty(&fds->ser->txfifo)
+ || fds->ser->hw->table->txSending(fds->ser->hw))
+ {
+ #if CONFIG_KERNEL && CONFIG_KERN_SCHED
+ /* Give up timeslice to other processes. */
+ proc_switch();
+ #endif
+ wdt_reset();
+ }
+ return 0;
+}
+
+
+/**
+ * Initialize a serial port.
+ *
+ * \param fd KFile Serial struct interface.
+ * \param unit Serial unit to open. Possible values are architecture dependant.
+ */
+static struct Serial *ser_open(struct KFileSerial *fd, unsigned int unit)
+{
+ struct Serial *port;
+
+ ASSERT(unit < countof(ser_handles));
+ port = &ser_handles[unit];
+
+ ASSERT(!port->is_open);
+ DB(port->is_open = true);
+
+ port->unit = unit;
+
+ port->hw = ser_hw_getdesc(unit);
+
+ /* Initialize circular buffers */
+ ASSERT(port->hw->txbuffer);
+ ASSERT(port->hw->rxbuffer);
+ fifo_init(&port->txfifo, port->hw->txbuffer, port->hw->txbuffer_size);
+ fifo_init(&port->rxfifo, port->hw->rxbuffer, port->hw->rxbuffer_size);
+
+ port->hw->table->init(port->hw, port);
+
+ fd->ser = port;
+ /* Set default values */
+#if CONFIG_SER_RXTIMEOUT != -1 || CONFIG_SER_TXTIMEOUT != -1
+ ser_settimeouts(fd, CONFIG_SER_RXTIMEOUT, CONFIG_SER_TXTIMEOUT);
+#endif
+#if CONFIG_SER_DEFBAUDRATE
+ ser_setbaudrate(fd, CONFIG_SER_DEFBAUDRATE);
+#endif
+
+ /* Clear error flags */
+ ser_setstatus(port, 0);
+
+ return port;
+}
+
+
+/**
+ * Clean up serial port, disabling the associated hardware.
+ */
+static int ser_close(struct KFile *fd)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+ Serial *port = fds->ser;
+
+ ASSERT(port->is_open);
+ DB(port->is_open = false);
+
+ // Wait until we finish sending everything
+ ser_flush(fd);
+
+ port->hw->table->cleanup(port->hw);
+ DB(port->hw = NULL);
+
+ /*
+ * We purge the FIFO buffer only after the low-level cleanup, so that
+ * we are sure that there are no more interrupts.
+ */
+ ser_purge(fds);
+ return 0;
+}
+
+/**
+ * Reopen serial port.
+ */
+static struct KFile *ser_reopen(struct KFile *fd)
+{
+ KFileSerial *fds = KFILESERIAL(fd);
+
+ ser_close(fd);
+ ser_open(fds, fds->ser->unit);
+ return (KFile *)fds;
+}
+
+/**
+ * Init serial driver for \a unit.
+ */
+void ser_init(struct KFileSerial *fds, unsigned int unit)
+{
+ memset(fds, 0, sizeof(*fds));
+
+ DB(fds->fd._type = KFT_SERIAL);
+ fds->fd.reopen = ser_reopen;
+ fds->fd.close = ser_close;
+ fds->fd.read = ser_read;
+ fds->fd.write = ser_write;
+ fds->fd.flush = ser_flush;
+ fds->fd.error = ser_error;
+ fds->fd.clearerr = ser_clearerr;
+ ser_open(fds, unit);
+}
+
+
+/**
+ * Read data from SPI bus.
+ * Since we are master, we have to trigger slave by sending
+ * fake chars on the bus.
+ */
+static size_t spimaster_read(struct KFile *fd, void *_buf, size_t size)
+{
+ KFileSerial *fd_spi = KFILESERIAL(fd);
+
+ ser_flush(&fd_spi->fd);
+ ser_purgeRx(fd_spi);
+
+ size_t total_rd = 0;
+ uint8_t *buf = (uint8_t *)_buf;
+ int c;
+
+ while (size--)
+ {
+ /*
+ * Send and receive chars 1 by 1, otherwise the rxfifo
+ * will overrun.
+ */
+ ser_putchar(0, fd_spi->ser);
+
+ if ((c = ser_getchar(fd_spi->ser)) == EOF)
+ break;
+
+ *buf++ = c;
+ total_rd++;
+ }
+ return total_rd;
+}
+
+/**
+ * Write data to SPI bus.
+ */
+static size_t spimaster_write(struct KFile *fd, const void *buf, size_t size)
+{
+ KFileSerial *fd_spi = KFILESERIAL(fd);
+
+ ser_purgeRx(fd_spi);
+
+ return ser_write(&fd_spi->fd, buf, size);
+}
+
+
+/**
+ * Init SPI serial driver \a unit in master mode.
+ *
+ * This interface implements the SPI master protocol over a serial SPI
+ * driver. This is needed because normal serial driver send/receive data
+ * at the same time. SPI slaves like memories and other peripherals
+ * first receive and *then* send response back instead.
+ * To achieve this, when we are master and we are *sending*,
+ * we have to discard all incoming data. Then, when we want to
+ * receive, we must write fake data to SPI to trigger slave devices.
+ */
+void spimaster_init(KFileSerial *fds, unsigned int unit)
+{
+ ser_init(fds, unit);
+ fds->fd.read = spimaster_read;
+ fds->fd.write = spimaster_write;
+}
+
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \brief High level serial I/O API
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef DRV_SER_H
+#define DRV_SER_H
+
+#include <kern/kfile.h>
+#include <mware/fifobuf.h>
+#include <cfg/compiler.h>
+
+#if OS_HOSTED
+ #include <cfg/macros.h> /* BV() */
+
+ typedef uint16_t serstatus_t;
+
+ /* Software errors */
+ #define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */
+ #define SERRF_RXTIMEOUT BV(1) /**< Receive timeout */
+ #define SERRF_TXTIMEOUT BV(2) /**< Transmit timeout */
+
+ /* Hardware errors */
+ #define SERRF_RXSROVERRUN 0 /**< Unsupported in emulated serial port. */
+ #define SERRF_FRAMEERROR 0 /**< Unsupported in emulated serial port. */
+ #define SERRF_PARITYERROR 0 /**< Unsupported in emulated serial port. */
+ #define SERRF_NOISEERROR 0 /**< Unsupported in emulated serial port. */
+
+ enum
+ {
+ SER_UART0,
+ SER_UART1,
+
+ SER_CNT /**< Number of serial ports */
+ };
+
+#else
+ #include CPU_HEADER(ser)
+#endif
+
+#include <appconfig.h>
+
+
+
+/**
+ * \name Masks to group TX/RX errors.
+ * \{
+ */
+#define SERRF_RX \
+ ( SERRF_RXFIFOOVERRUN \
+ | SERRF_RXTIMEOUT \
+ | SERRF_RXSROVERRUN \
+ | SERRF_PARITYERROR \
+ | SERRF_FRAMEERROR \
+ | SERRF_NOISEERROR)
+#define SERRF_TX (SERRF_TXTIMEOUT)
+/*\}*/
+
+/**
+ * \name LSB or MSB first data order for SPI driver.
+ * \{
+ */
+#define SER_MSB_FIRST 0
+#define SER_LSB_FIRST 1
+/*\}*/
+
+/**
+ * \name Parity settings for ser_setparity().
+ *
+ * \note Values are AVR-specific for performance reasons.
+ * Other processors should either decode them or
+ * redefine these macros.
+ * \{
+ */
+#define SER_PARITY_NONE 0
+#define SER_PARITY_EVEN 2
+#define SER_PARITY_ODD 3
+/*\}*/
+
+
+struct SerialHardware;
+
+/** Human-readable serial error descriptions */
+extern const char * const serial_errors[8];
+
+/** Serial handle structure */
+typedef struct Serial
+{
+ /** Physical port number */
+ unsigned int unit;
+
+#ifdef _DEBUG
+ bool is_open;
+#endif
+
+ /**
+ * \name Transmit and receive FIFOs.
+ *
+ * Declared volatile because handled asinchronously by interrupts.
+ *
+ * \{
+ */
+ FIFOBuffer txfifo;
+ FIFOBuffer rxfifo;
+ /* \} */
+
+#if CONFIG_SER_RXTIMEOUT != -1
+ ticks_t rxtimeout;
+#endif
+#if CONFIG_SER_TXTIMEOUT != -1
+ ticks_t txtimeout;
+#endif
+
+ /** Holds the flags defined above. Will be 0 when no errors have occurred. */
+ volatile serstatus_t status;
+
+ /** Low-level interface to hardware. */
+ struct SerialHardware* hw;
+} Serial;
+
+typedef struct KFileSerial
+{
+ KFile fd;
+ Serial *ser;
+} KFileSerial;
+
+/**
+ * ID for serial.
+ */
+#define KFT_SERIAL MAKE_ID('S', 'E', 'R', 'L')
+
+
+INLINE KFileSerial * KFILESERIAL(KFile *fd)
+{
+ ASSERT(fd->_type == KFT_SERIAL);
+ return (KFileSerial *)fd;
+}
+
+/* Function prototypes */
+//extern int ser_getchar_nowait(struct Serial *port);
+
+void ser_setbaudrate(struct KFileSerial *fd, unsigned long rate);
+void ser_setparity(struct KFileSerial *fd, int parity);
+void ser_settimeouts(struct KFileSerial *fd, mtime_t rxtimeout, mtime_t txtimeout);
+void ser_resync(struct KFileSerial *fd, mtime_t delay);
+int ser_getchar_nowait(struct KFileSerial *fd);
+
+void ser_purgeRx(struct KFileSerial *fd);
+void ser_purgeTx(struct KFileSerial *fd);
+void ser_purge(struct KFileSerial *fd);
+void ser_init(struct KFileSerial *fds, unsigned int unit);
+void spimaster_init(KFileSerial *fds, unsigned int unit);
+
+
+/**
+ * \name Additional functions implemented as macros
+ *
+ * \{
+ */
+#define ser_getstatus(h) ((h)->status)
+#define ser_setstatus(h, x) ((h)->status = (x))
+/* \} */
+
+#endif /* DRV_SER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Hardware dependent serial driver (interface)
+ *
+ * \version $Id$
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+
+#ifndef DRV_SER_P_H
+#define DRV_SER_P_H
+
+#include <cfg/compiler.h> /* size_t */
+
+struct SerialHardware;
+struct Serial;
+
+struct SerialHardwareVT
+{
+ void (*init)(struct SerialHardware *ctx, struct Serial *ser);
+ void (*cleanup)(struct SerialHardware *ctx);
+ void (*setBaudrate)(struct SerialHardware *ctx, unsigned long rate);
+ void (*setParity)(struct SerialHardware *ctx, int parity);
+ void (*txStart)(struct SerialHardware *ctx);
+ bool (*txSending)(struct SerialHardware *ctx);
+};
+
+struct SerialHardware
+{
+ const struct SerialHardwareVT *table;
+ unsigned char *txbuffer;
+ unsigned char *rxbuffer;
+ size_t txbuffer_size;
+ size_t rxbuffer_size;
+};
+
+struct SerialHardware *ser_hw_getdesc(int unit);
+
+#endif /* DRV_SER_P_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Serial port emulator for hosted environments.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2006/02/17 22:28:00 bernie
+ *#* Rename ser_emul.c to ser_posix.c.
+ *#*
+ *#* Revision 1.4 2006/02/17 22:23:06 bernie
+ *#* Update POSIX serial emulator.
+ *#*
+ *#* Revision 1.3 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.2 2005/04/11 19:10:27 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.1 2004/12/31 17:40:00 bernie
+ *#* Add a simple serial emulation driver.
+ *#*
+ *#*/
+
+#include "ser.h"
+#include "ser_p.h"
+
+#include <cfg/debug.h>
+#include <cfg/compiler.h>
+#include <mware/fifobuf.h>
+
+#include <appconfig.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h> /* open() */
+#include <unistd.h> /* read(), write() */
+
+
+/* From the high-level serial driver */
+extern struct Serial ser_handles[SER_CNT];
+
+/* TX and RX buffers */
+static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
+static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
+static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
+static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
+
+
+/**
+ * Internal state structure
+ */
+struct EmulSerial
+{
+ struct SerialHardware hw;
+ struct Serial *ser;
+ int fd;
+};
+
+
+/*
+ * Callbacks
+ */
+static void uart_init(struct SerialHardware *_hw, struct Serial *ser)
+{
+ struct EmulSerial *hw = (struct EmulSerial *)_hw;
+
+ hw->ser = ser;
+ hw->fd = open("/dev/ttyS0", O_RDWR);
+}
+
+static void uart_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
+{
+ struct EmulSerial *hw = (struct EmulSerial *)_hw;
+
+ close(hw->fd);
+ hw->fd = -1;
+}
+
+static void uart_txStart(struct SerialHardware * _hw)
+{
+ struct EmulSerial *hw = (struct EmulSerial *)_hw;
+
+ while(!fifo_isempty(&hw->ser->txfifo))
+ {
+ char c = fifo_pop(&hw->ser->txfifo);
+ write(hw->fd, &c, 1);
+ }
+}
+
+static bool uart_txSending(UNUSED_ARG(struct SerialHardware *, _hw))
+{
+ return false;
+}
+
+
+static void uart_setBaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
+{
+ TRACEMSG("rate=%lu", rate);
+ // TODO
+
+}
+
+static void uart_setParity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
+{
+ TRACEMSG("parity=%d", parity);
+ // TODO
+}
+
+// FIXME: move into compiler.h? Ditch?
+#if COMPILER_C99
+ #define C99INIT(name,val) .name = val
+#elif defined(__GNUC__)
+ #define C99INIT(name,val) name: val
+#else
+ #warning No designated initializers, double check your code
+ #define C99INIT(name,val) (val)
+#endif
+
+/*
+ * High-level interface data structures.
+ */
+static const struct SerialHardwareVT uart_vtable =
+{
+ C99INIT(init, uart_init),
+ C99INIT(cleanup, uart_cleanup),
+ C99INIT(setBaudrate, uart_setBaudrate),
+ C99INIT(setParity, uart_setParity),
+ C99INIT(txStart, uart_txStart),
+ C99INIT(txSending, uart_txSending),
+};
+
+static struct EmulSerial UARTDescs[SER_CNT] =
+{
+ {
+ C99INIT(hw, /**/) {
+ C99INIT(table, &uart_vtable),
+ C99INIT(txbuffer, uart0_txbuffer),
+ C99INIT(rxbuffer, uart0_rxbuffer),
+ C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
+ C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
+ },
+ C99INIT(ser, NULL),
+ C99INIT(fd, -1),
+ },
+ {
+ C99INIT(hw, /**/) {
+ C99INIT(table, &uart_vtable),
+ C99INIT(txbuffer, uart1_txbuffer),
+ C99INIT(rxbuffer, uart1_rxbuffer),
+ C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
+ C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
+ },
+ C99INIT(ser, NULL),
+ C99INIT(fd, -1),
+ },
+};
+
+struct SerialHardware *ser_hw_getdesc(int unit)
+{
+ ASSERT(unit < SER_CNT);
+ return &UARTDescs[unit].hw;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \brief Emulated SPI Master for DSP firmware download (impl.)
+ *
+ * \version $Id: spi.c 15328 2007-03-21 15:07:04Z batt $
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+
+#include <cfg/cpu.h>
+#include <cfg/module.h>
+#include <drv/spi_emu.h>
+#include "hw_spi.h"
+
+void spi_assertSS(void)
+{
+ ATOMIC(SS_ACTIVE());
+}
+
+void spi_deassertSS(void)
+{
+ ATOMIC(SS_INACTIVE());
+}
+
+/**
+ * Send byte \c c over MOSI line, CONFIG_SPI_DATAORDER first.
+ * SS pin state is left unchanged.
+ */
+uint8_t spi_sendRecv(uint8_t c)
+{
+ uint8_t data = 0;
+ uint8_t shift = SPI_DATAORDER_START;
+
+
+ ATOMIC(
+ for (int i = 0; i < 8; i++)
+ {
+ /* Shift the i-th bit to MOSI */
+ if (c & shift)
+ MOSI_HIGH();
+ else
+ MOSI_LOW();
+ /* Assert clock */
+ SCK_ACTIVE();
+ data |= IS_MISO_HIGH() ? shift : 0;
+ /* De-assert clock */
+ SCK_INACTIVE();
+ SPI_DATAORDER_SHIFT(shift);
+ }
+ );
+ return data;
+}
+
+MOD_DEFINE(spi);
+void spi_init(void)
+{
+ ATOMIC(SPI_HW_INIT());
+ MOD_INIT(spi);
+}
+
+/**
+ * Read \param len from spi, and put it in \param _buff .
+ */
+void spi_read(void *_buff, size_t len)
+{
+ uint8_t *buff = (uint8_t *)_buff;
+
+ while (len--)
+ /* Read byte from spi and put it in buffer. */
+ *buff++ = spi_sendRecv(0);
+
+}
+
+/**
+ * Write \param len to spi, and take it from \param _buff .
+ */
+void spi_write(const void *_buff, size_t len)
+{
+ const uint8_t *buff = (const uint8_t *)_buff;
+
+ while (len--)
+ /* Write byte pointed at by *buff to spi */
+ spi_sendRecv(*buff++);
+
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \brief Emulated SPI Master for DSP firmware download (interface)
+ *
+ * \version $Id: spi.h 15321 2007-03-21 14:45:12Z asterix $
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+
+#ifndef DRV_SPI_EMU_H
+#define DRV_SPI_EMU_H
+
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+/**
+ * Define send and receive order bit.
+ * \{
+ */
+#define SPI_LSB_FIRST 1
+#define SPI_MSB_FIRST 2
+/* \} */
+
+#if CONFIG_SPI_DATAORDER == SPI_LSB_FIRST
+ #define SPI_DATAORDER_START 1
+ #define SPI_DATAORDER_SHIFT(i) ((i) <<= 1)
+#elif CONFIG_SPI_DATAORDER == SPI_MSB_FIRST
+ #define SPI_DATAORDER_START 0x80
+ #define SPI_DATAORDER_SHIFT(i) ((i) >>= 1)
+#endif
+
+void spi_write(const void *buf, size_t len);
+void spi_read(void *buf, size_t len);
+uint8_t spi_sendRecv(uint8_t c);
+void spi_init(void);
+void spi_assertSS(void);
+void spi_deassertSS(void);
+
+#endif /* DRV_SPI_EMU_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief TC520 ADC driver (implementation)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Marco Benelli <marco@develer.com>
+ */
+
+#include <drv/tc520.h>
+#include <drv/timer.h>
+
+#include <hw_tc520.h>
+
+#include <cfg/macros.h>
+#include <cfg/compiler.h>
+
+#include <drv/ser.h>
+
+static Serial *spi_ser;
+
+#define TC520_CONVERSION_TIMEOUT ms_to_ticks(1000)
+#define INIT_LOAD_VALUE 0x00
+
+/**
+ * Start an AD conversion and return result.
+ *
+ * To start a conversion first we must pull down CE pin.
+ * The ADC starts a convertion and keeps the DV pin high until the end.
+ * At this point, we can read the conversion value by SPI.
+ * The convertion result is yield in 3 bytes.
+ *
+ * \verbatim
+ *
+ * First byte:
+ * bit | Value
+ * ----|-------
+ * 7 | Overrange
+ * 6 | Polarity
+ * 5:0 | data bits 15:10
+ *
+ * Second byte: data 9:2
+ *
+ * Third byte:
+ * bit | Value
+ * ----|-------
+ * 7 | data bit 1
+ * 6 | data bit 0
+ * 5:0 | '0'
+ *
+ * \endverbatim
+ *
+ * So, to get the result we must shift and recompose the bits.
+ * \note Overrange bit is handled as the 17th data bit.
+ */
+tc520_data_t tc520_read(void)
+{
+ /* Start convertion and wait */
+ CE_LOW();
+ ticks_t start = timer_clock();
+ do
+ {
+ /* timeout check */
+ if (timer_clock() - start >= TC520_CONVERSION_TIMEOUT)
+ {
+ ASSERT(0);
+ CE_HIGH();
+ return TC520_MAX_VALUE;
+ }
+ }
+ while(DV_LOW());
+
+ start = timer_clock();
+ do
+ {
+ /* timeout check */
+ if (timer_clock() - start >= TC520_CONVERSION_TIMEOUT)
+ {
+ ASSERT(0);
+ CE_HIGH();
+ return TC520_MAX_VALUE;
+ }
+ }
+ while(DV_HIGH());
+
+ /* Ok, convertion finished, read result */
+ CE_HIGH();
+ READ_LOW();
+
+ /* RX buffer could be dirty...*/
+ ser_purge(spi_ser);
+
+ /* I/O buffer */
+ uint8_t buf[3] = "\x0\x0\x0";
+
+ /* Dummy write to activate recv */
+ ser_write(spi_ser, buf, sizeof(buf));
+ ser_drain(spi_ser);
+ READ_HIGH();
+
+ /* recv */
+ ASSERT(ser_read(spi_ser, buf, sizeof(buf)) == sizeof(buf));
+
+ tc520_data_t res;
+
+ /* Recompose data */
+ res = (((tc520_data_t)(buf[0] & 0x3F)) << 10) | (((tc520_data_t)buf[1]) << 2) | (((tc520_data_t)buf[2]) >> 6);
+
+ #define OVERRANGE_BIT BV(7)
+ /* Handle overrange bit as 17th bit */
+ if (buf[0] & OVERRANGE_BIT)
+ res |= BV32(16);
+
+ return res;
+}
+
+
+/**
+ * Initialize tc520 A/D converter driver
+ */
+void tc520_init(Serial *spi_port)
+{
+ spi_ser = spi_port;
+ /* init io ports */
+ TC520_HW_INIT;
+ /* Send initial load value */
+ LOAD_LOW();
+ ser_putchar(INIT_LOAD_VALUE, spi_ser);
+ ser_drain(spi_ser);
+ LOAD_HIGH();
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief TC520 ADC driver (intercace)
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Marco Benelli <marco@develer.com>
+ */
+
+#ifndef DRV_TC520_H
+#define DRV_TC520_H
+
+#include <drv/ser.h>
+#include <cfg/compiler.h>
+
+typedef uint32_t tc520_data_t;
+
+/* 17 bit max value */
+#define TC520_MAX_VALUE 0x1FFFFUL
+
+tc520_data_t tc520_read(void);
+void tc520_init(Serial *spi_port);
+
+#endif /* DRV_TC520_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Thermo-control driver
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.3 2006/09/20 20:12:41 marco
+ *#* Names convention, MOD_* macros.
+ *#*
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 17:59:47 bernie
+ *#* Import into DevLib.
+ *#*
+ *#*/
+#include <thermo_map.h>
+#include <hw_thermo.h>
+
+#include <drv/thermo.h>
+#include <drv/timer.h>
+#include <drv/ntc.h>
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+
+/** Interval at which thermo control is performed. */
+#define THERMO_INTERVAL_MS 100
+
+/** Number of different samples we interpolate over to get the hifi temperature. */
+#define THERMO_HIFI_NUM_SAMPLES 10
+
+/** Timer for thermo-regulation. */
+static Timer thermo_timer;
+
+typedef struct ThermoControlDev
+{
+ deg_t hifi_samples[THERMO_HIFI_NUM_SAMPLES];
+ deg_t cur_hifi_sample;
+ deg_t target;
+ thermostatus_t status;
+ ticks_t expire;
+} ThermoControlDev;
+
+/** Array of thermo-devices. */
+ThermoControlDev devs[THERMO_CNT];
+
+
+/**
+ * Return the status of the specific \a dev thermo-device.
+ */
+thermostatus_t thermo_status(ThermoDev dev)
+{
+ return devs[dev].status;
+}
+
+
+/**
+ * Do a single thermo control for device \a dev.
+ */
+static void thermo_do(ThermoDev index)
+{
+ ThermoControlDev* dev = &devs[index];
+ deg_t cur_temp;
+ deg_t tolerance = thermo_hw_tolerance(index);
+
+ cur_temp = thermo_hw_read(index);
+
+ // Store the sample into the hifi FIFO buffer for later interpolation
+ dev->hifi_samples[dev->cur_hifi_sample] = cur_temp;
+ if (++dev->cur_hifi_sample == THERMO_HIFI_NUM_SAMPLES)
+ dev->cur_hifi_sample = 0;
+
+ cur_temp = thermo_readTemperature(index);
+
+ if (cur_temp == NTC_SHORT_CIRCUIT || cur_temp == NTC_OPEN_CIRCUIT)
+ {
+ if (cur_temp == NTC_SHORT_CIRCUIT)
+ {
+ #ifdef _DEBUG
+ if (!(dev->status & THERMOERRF_NTCSHORT))
+ kprintf("dev[%d], thermo_do: NTC_SHORT\n",index);
+ #endif
+ dev->status |= THERMOERRF_NTCSHORT;
+ }
+ else
+ {
+ #ifdef _DEBUG
+ if (!(dev->status & THERMOERRF_NTCOPEN))
+ kprintf("dev[%d], thermo_do: NTC_OPEN\n", index);
+ #endif
+ dev->status |= THERMOERRF_NTCOPEN;
+ }
+
+ /* Reset timeout when there is an ntc error */
+ dev->expire = thermo_hw_timeout(index) + timer_clock();
+ thermo_hw_off(index);
+ return;
+ }
+ dev->status &= ~(THERMOERRF_NTCOPEN | THERMOERRF_NTCSHORT);
+
+ if ((cur_temp < dev->target - tolerance) || (cur_temp > dev->target + tolerance))
+ {
+ dev->status &= ~THERMO_TGT_REACH;
+
+ /* Check for timeout */
+ if (timer_clock() - dev->expire > 0)
+ {
+ dev->status |= THERMOERRF_TIMEOUT;
+ kprintf("dev[%d], thermo_do: TIMEOUT\n", index);
+ }
+ }
+ else /* In target */
+ {
+ /* Clear errors */
+ dev->status &= ~THERMO_ERRMASK;
+ dev->status |= THERMO_TGT_REACH;
+
+ /* Reset timeout in case we go out of target in the future */
+ dev->expire = thermo_hw_timeout(index) + timer_clock();
+ }
+
+ if (cur_temp < dev->target)
+ dev->status = (dev->status | THERMO_HEATING) & ~THERMO_FREEZING;
+ else
+ dev->status = (dev->status & ~THERMO_HEATING) | THERMO_FREEZING;
+
+ thermo_hw_set(index, dev->target, cur_temp);
+
+}
+
+
+/**
+ * Thermo soft interrupt.
+ */
+static void thermo_softint(void)
+{
+ int i;
+ for (i = 0; i < THERMO_CNT; ++i)
+ if (devs[i].status & THERMO_ACTIVE)
+ thermo_do((ThermoDev)i);
+
+ timer_add(&thermo_timer);
+}
+
+
+/**
+ * Set the target temperature \a temperature for a specific \a dev thermo-device.
+ */
+void thermo_setTarget(ThermoDev dev, deg_t temperature)
+{
+ ASSERT(dev < THERMO_CNT);
+ devs[dev].target = temperature;
+ devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
+
+ kprintf("setTarget dev[%d], T[%d.%d]\n", dev, temperature / 10, temperature % 10);
+}
+
+/**
+ * Starts a thermo-regulation for channel \a dev.
+ */
+void thermo_start(ThermoDev dev)
+{
+ int i;
+ deg_t temp;
+
+ ASSERT(dev < THERMO_CNT);
+
+ devs[dev].status |= THERMO_ACTIVE;
+
+ /* Initialize the hifi FIFO with a constant value (the current temperature) */
+ temp = thermo_hw_read(dev);
+ for (i = 0; i < THERMO_HIFI_NUM_SAMPLES; ++i)
+ devs[dev].hifi_samples[i] = temp;
+ devs[dev].cur_hifi_sample = 0;
+
+ /* Reset timeout */
+ devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
+}
+
+/**
+ * Stops a thermo-regulation for channel \a dev.
+ */
+void thermo_stop(ThermoDev dev)
+{
+ ASSERT(dev < THERMO_CNT);
+
+ devs[dev].status &= ~THERMO_ACTIVE;
+ thermo_hw_off(dev);
+}
+
+
+/**
+ * Clear errors for channel \a dev.
+ */
+void thermo_clearErrors(ThermoDev dev)
+{
+ ASSERT(dev < THERMO_CNT);
+ devs[dev].status &= ~(THERMO_ERRMASK);
+}
+
+
+/**
+ * Read the temperature of the thermo-device \a dev using mobile mean.
+ */
+deg_t thermo_readTemperature(ThermoDev dev)
+{
+ int i;
+ long accum = 0;
+
+ MOD_CHECK(thermo);
+
+ for (i = 0; i < THERMO_HIFI_NUM_SAMPLES; i++)
+ accum += devs[dev].hifi_samples[i];
+
+ return (deg_t)(accum / THERMO_HIFI_NUM_SAMPLES);
+}
+
+MOD_DEFINE(thermo)
+
+/**
+ * Init thermo-control and associated hw.
+ */
+void thermo_init(void)
+{
+ THERMO_HW_INIT;
+
+ /* Set all status to off */
+ for (int i = 0; i < THERMO_CNT; i++)
+ devs[i].status = THERMO_OFF;
+
+ MOD_INIT(thermo);
+
+ timer_setDelay(&thermo_timer, ms_to_ticks(THERMO_INTERVAL_MS));
+ timer_set_event_softint(&thermo_timer, (Hook)thermo_softint, 0);
+ timer_add(&thermo_timer);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Thermo-control driver
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * This module implements multiple thermo controls, which is the logic needed to try
+ * keeping the temperature of a device constant. For this module, a "device" is a black box
+ * whose temperature can be measured, and which has a mean to make it hotter or colder.
+ * For instance, a device could be the combination of a NTC (analog temperature reader) and
+ * a Peltier connected to the same physic block.
+ *
+ * This module relies on a low-level driver to communicate with the device (implementation
+ * of the black box). This low-level driver also controls the units in which the temperature
+ * is expressed: thermo control treats it just as a number.
+ *
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.3 2006/09/20 20:12:41 marco
+ *#* Names convention, MOD_* macros.
+ *#*
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 17:59:47 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.2 2005/06/14 10:13:36 batt
+ *#* Better thermo errors handling.
+ *#*
+ *#* Revision 1.1 2005/05/24 09:17:58 batt
+ *#* Move drivers to top-level.
+ *#*
+ *#* Revision 1.4 2005/05/10 16:55:10 batt
+ *#* Add timeout to thermo-regulator; better thermo control handling; change thermo_getStatus() to thermo_status().
+ *#*
+ *#* Revision 1.3 2005/05/10 09:26:54 batt
+ *#* Add thermo_getStatus for getting status/errors of thermo control.
+ *#*
+ *#* Revision 1.2 2005/05/09 19:18:40 batt
+ *#* Remove old logs.
+ *#*
+ *#* Revision 1.1 2005/05/09 16:40:44 batt
+ *#* Add thermo-control driver
+ *#*/
+
+
+#ifndef DRV_THERMO_H
+#define DRV_THERMO_H
+
+#include <drv/ntc.h>
+#include <thermo_map.h>
+
+void thermo_init(void);
+
+
+/**
+ * Set the target temperature at which a given device should be kept.
+ *
+ * \param dev Device
+ * \param temperature Target temperature
+ */
+void thermo_setTarget(ThermoDev dev, deg_t temperature);
+
+/** Start thermo control for a certain device \a dev */
+void thermo_start(ThermoDev dev);
+
+/** Stop thermo control for a certain device \a dev */
+void thermo_stop(ThermoDev dev);
+
+/** Clear errors for channel \a dev */
+void thermo_clearErrors(ThermoDev dev);
+
+/** Return the status of the specific \a dev thermo-device. */
+thermostatus_t thermo_status(ThermoDev dev);
+
+/**
+ * Return the current temperature of a device currently under thermo
+ * control.
+ *
+ * \param dev Device
+ * \return Current temperature (Celsius degrees * 10)
+ */
+deg_t thermo_readTemperature(ThermoDev dev);
+
+
+#endif /* DRV_THERMO_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Hardware independent timer driver (implementation)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "timer.h"
+
+#include <cpu/attr.h>
+#include <cpu/types.h>
+#include <cpu/irq.h>
+
+#include <cfg/os.h>
+#include <cfg/debug.h>
+#include <cfg/module.h>
+#include <appconfig.h>
+
+/*
+ * Include platform-specific binding code if we're hosted.
+ * Try the CPU specific one for bare-metal environments.
+ */
+#if OS_HOSTED
+ #include OS_CSOURCE(timer)
+#else
+ #include CPU_CSOURCE(timer)
+#endif
+
+/*
+ * Sanity check for config parameters required by this module.
+ */
+#if !defined(CONFIG_KERNEL) || ((CONFIG_KERNEL != 0) && CONFIG_KERNEL != 1)
+ #error CONFIG_KERNEL must be set to either 0 or 1 in config.h
+#endif
+#if !defined(CONFIG_WATCHDOG) || ((CONFIG_WATCHDOG != 0) && CONFIG_WATCHDOG != 1)
+ #error CONFIG_WATCHDOG must be set to either 0 or 1 in config.h
+#endif
+
+#if CONFIG_WATCHDOG
+ #include <drv/wdt.h>
+#endif
+
+#if CONFIG_KERNEL
+ #include <config_kern.h>
+ #if CONFIG_KERN_PREEMPTIVE
+ #include <hw/switch.h>
+ #endif
+ #if CONFIG_KERN_SIGNALS
+ #include <kern/signal.h> /* sig_wait(), sig_check() */
+ #include <kern/proc.h> /* proc_current() */
+ #include <cfg/macros.h> /* BV() */
+ #endif
+#endif
+
+
+/**
+ * \def CONFIG_TIMER_STROBE
+ *
+ * This is a debug facility that can be used to
+ * monitor timer interrupt activity on an external pin.
+ *
+ * To use strobes, redefine the macros TIMER_STROBE_ON,
+ * TIMER_STROBE_OFF and TIMER_STROBE_INIT and set
+ * CONFIG_TIMER_STROBE to 1.
+ */
+#if !defined(CONFIG_TIMER_STROBE) || !CONFIG_TIMER_STROBE
+ #define TIMER_STROBE_ON do {/*nop*/} while(0)
+ #define TIMER_STROBE_OFF do {/*nop*/} while(0)
+ #define TIMER_STROBE_INIT do {/*nop*/} while(0)
+#endif
+
+
+/// Master system clock (1 tick accuracy)
+volatile ticks_t _clock;
+
+
+#ifndef CONFIG_TIMER_DISABLE_EVENTS
+
+/**
+ * List of active asynchronous timers.
+ */
+REGISTER static List timers_queue;
+
+
+/**
+ * Add the specified timer to the software timer service queue.
+ * When the delay indicated by the timer expires, the timer
+ * device will execute the event associated with it.
+ *
+ * \note Interrupt safe
+ */
+void timer_add(Timer *timer)
+{
+ Timer *node;
+ cpuflags_t flags;
+
+
+ /* Inserting timers twice causes mayhem. */
+ ASSERT(timer->magic != TIMER_MAGIC_ACTIVE);
+ DB(timer->magic = TIMER_MAGIC_ACTIVE;)
+
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Calculate expiration time for this timer */
+ timer->tick = _clock + timer->_delay;
+
+ /*
+ * Search for the first node whose expiration time is
+ * greater than the timer we want to add.
+ */
+ node = (Timer *)LIST_HEAD(&timers_queue);
+ while (node->link.succ)
+ {
+ /*
+ * Stop just after the insertion point.
+ * (this fancy compare takes care of wrap-arounds).
+ */
+ if (node->tick - timer->tick > 0)
+ break;
+
+ /* Go to next node */
+ node = (Timer *)node->link.succ;
+ }
+
+ /* Enqueue timer request into the list */
+ INSERT_BEFORE(&timer->link, &node->link);
+
+ IRQ_RESTORE(flags);
+}
+
+
+/**
+ * Remove a timer from the timer queue before it has expired.
+ */
+Timer *timer_abort(Timer *timer)
+{
+ ATOMIC(REMOVE(&timer->link));
+ DB(timer->magic = TIMER_MAGIC_INACTIVE;)
+
+ return timer;
+}
+
+#endif /* CONFIG_TIMER_DISABLE_EVENTS */
+
+
+/**
+ * Wait for the specified amount of timer ticks.
+ */
+void timer_delayTicks(ticks_t delay)
+{
+#if defined(IRQ_ENABLED)
+ /* We shouldn't sleep with interrupts disabled */
+ ASSERT(IRQ_ENABLED());
+#endif
+
+#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
+ Timer t;
+
+ ASSERT(!sig_check(SIG_SINGLE));
+ timer_set_event_signal(&t, proc_current(), SIG_SINGLE);
+ timer_setDelay(&t, delay);
+ timer_add(&t);
+ sig_wait(SIG_SINGLE);
+
+#else /* !CONFIG_KERN_SIGNALS */
+
+ ticks_t start = timer_clock();
+
+ /* Busy wait */
+ while (timer_clock() - start < delay)
+ {
+#if CONFIG_WATCHDOG
+ wdt_reset();
+#endif
+ }
+
+#endif /* !CONFIG_KERN_SIGNALS */
+}
+
+
+#ifndef CONFIG_TIMER_DISABLE_UDELAY
+
+/**
+ * Busy wait until the specified amount of high-precision ticks have elapsed.
+ *
+ * \note This function is interrupt safe, the only
+ * requirement is a running hardware timer.
+ */
+void timer_busyWait(hptime_t delay)
+{
+ hptime_t now, prev = timer_hw_hpread();
+ hptime_t delta;
+
+ for(;;)
+ {
+ now = timer_hw_hpread();
+ /*
+ * We rely on hptime_t being unsigned here to
+ * reduce the modulo to an AND in the common
+ * case of TIMER_HW_CNT.
+ */
+ delta = (now - prev) % TIMER_HW_CNT;
+ if (delta >= delay)
+ break;
+ delay -= delta;
+ prev = now;
+ }
+}
+
+/**
+ * Wait for the specified amount of time (expressed in microseconds).
+ *
+ * \bug In AVR arch the maximum amount of time that can be used as
+ * delay could be very limited, depending on the hardware timer
+ * used. Check timer_avr.h, and what register is used as hptime_t.
+ */
+void timer_delayHp(hptime_t delay)
+{
+ if (UNLIKELY(delay > us_to_hptime(1000)))
+ {
+ timer_delayTicks(delay / (TIMER_HW_HPTICKS_PER_SEC / TIMER_TICKS_PER_SEC));
+ delay %= (TIMER_HW_HPTICKS_PER_SEC / TIMER_TICKS_PER_SEC);
+ }
+
+ timer_busyWait(delay);
+}
+#endif /* CONFIG_TIMER_DISABLE_UDELAY */
+
+
+/**
+ * Timer interrupt handler. Find soft timers expired and
+ * trigger corresponding events.
+ */
+DEFINE_TIMER_ISR
+{
+ /*
+ * With the Metrowerks compiler, the only way to force the compiler generate
+ * an interrupt service routine is to put a pragma directive within the function
+ * body.
+ */
+ #ifdef __MWERKS__
+ #pragma interrupt saveall
+ #endif
+
+#ifndef CONFIG_TIMER_DISABLE_EVENTS
+ Timer *timer;
+#endif
+ /*
+ * On systems sharing IRQ line and vector, this check is needed
+ * to ensure that IRQ is generated by timer source.
+ */
+ if (!timer_hw_triggered())
+ return;
+
+ TIMER_STROBE_ON;
+
+ /* Perform hw IRQ handling */
+ timer_hw_irq();
+
+ /* Update the master ms counter */
+ ++_clock;
+
+#ifndef CONFIG_TIMER_DISABLE_EVENTS
+ /*
+ * Check the first timer request in the list and process
+ * it when it has expired. Repeat this check until the
+ * first node has not yet expired. Since the list is sorted
+ * by expiry time, all the following requests are guaranteed
+ * to expire later.
+ */
+ while ((timer = (Timer *)LIST_HEAD(&timers_queue))->link.succ)
+ {
+ /* This request in list has not yet expired? */
+ if (_clock - timer->tick < 0)
+ break;
+
+ /* Retreat the expired timer */
+ REMOVE(&timer->link);
+ DB(timer->magic = TIMER_MAGIC_INACTIVE;)
+
+ /* Execute the associated event */
+ event_do(&timer->expire);
+ }
+#endif /* CONFIG_TIMER_DISABLE_EVENTS */
+
+ TIMER_STROBE_OFF;
+}
+
+MOD_DEFINE(timer)
+
+/**
+ * Initialize timer
+ */
+void timer_init(void)
+{
+ TIMER_STROBE_INIT;
+
+#ifndef CONFIG_TIMER_DISABLE_EVENTS
+ LIST_INIT(&timers_queue);
+#endif
+
+ _clock = 0;
+
+ timer_hw_init();
+
+ MOD_INIT(timer);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Hardware independent timer driver (interface)
+ */
+
+#ifndef DRV_TIMER_H
+#define DRV_TIMER_H
+
+#include <cfg/os.h>
+#include <cfg/macros.h>
+#include <cpu/attr.h>
+#include <cpu/irq.h>
+
+
+/*
+ * Include platform-specific binding header if we're hosted.
+ * Try the CPU specific one for bare-metal environments.
+ */
+#if OS_HOSTED
+ #include OS_HEADER(timer)
+#else
+ #include CPU_HEADER(timer)
+#endif
+
+#include <mware/list.h>
+#include <cfg/debug.h>
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+
+extern volatile ticks_t _clock;
+
+/**
+ * \brief Return the system tick counter (expressed in ticks)
+ *
+ * The result is guaranteed to increment monotonically,
+ * but client code must be tolerant with respect to overflows.
+ *
+ * The following code is safe:
+ *
+ * \code
+ * ticks_t tea_start_time = timer_clock();
+ *
+ * boil_water();
+ *
+ * if (timer_clock() - tea_start_time > TEAPOT_DELAY)
+ * printf("Your tea, Sir.\n");
+ * \endcode
+ *
+ * \note This function must disable interrupts on 8/16bit CPUs because the
+ * clock variable is larger than the processor word size and can't
+ * be copied atomically.
+ */
+INLINE ticks_t timer_clock(void)
+{
+ ticks_t result;
+
+ ATOMIC(result = _clock);
+
+ return result;
+}
+
+/**
+ * Faster version of timer_clock(), to be called only when the timer
+ * interrupt is disabled (DISABLE_INTS) or overridden by a
+ * higher-priority or non-nesting interrupt.
+ *
+ * \sa timer_clock
+ */
+INLINE ticks_t timer_clock_unlocked(void)
+{
+ return _clock;
+}
+
+/** Convert \a ms [ms] to ticks. */
+INLINE ticks_t ms_to_ticks(mtime_t ms)
+{
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return (ms * TIMER_TICKS_PER_SEC) / 1000;
+#else
+ /* Fast timer: don't overflow ticks_t. */
+ return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
+#endif
+}
+
+/** Convert \a us [us] to ticks. */
+INLINE ticks_t us_to_ticks(utime_t us)
+{
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
+#else
+ /* Fast timer: don't overflow ticks_t. */
+ return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
+#endif
+}
+
+/** Convert \a ticks [ticks] to ms. */
+INLINE mtime_t ticks_to_ms(ticks_t ticks)
+{
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return (ticks * 1000) / TIMER_TICKS_PER_SEC;
+#else
+ /* Fast timer: avoid overflowing ticks_t. */
+ return ticks / (TIMER_TICKS_PER_SEC / 1000);
+#endif
+}
+
+/** Convert \a ticks [ticks] to us. */
+INLINE utime_t ticks_to_us(ticks_t ticks)
+{
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
+#else
+ /* Fast timer: avoid overflowing ticks_t. */
+ return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
+#endif
+}
+
+/** Convert \a us [us] to hpticks */
+INLINE hptime_t us_to_hptime(utime_t us)
+{
+#if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
+ return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
+#else
+ return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
+#endif
+}
+
+/** Convert \a hpticks [hptime] to usec */
+INLINE utime_t hptime_to_us(hptime_t hpticks)
+{
+#if TIMER_HW_HPTICKS_PER_SEC < 100000UL
+ return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
+#else
+ return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
+#endif /* TIMER_HW_HPTICKS_PER_SEC < 100000UL */
+}
+
+
+void timer_init(void);
+void timer_delayTicks(ticks_t delay);
+INLINE void timer_delay(mtime_t delay)
+{
+ timer_delayTicks(ms_to_ticks(delay));
+}
+
+#if !defined(CONFIG_TIMER_DISABLE_UDELAY)
+void timer_busyWait(hptime_t delay);
+void timer_delayHp(hptime_t delay);
+INLINE void timer_udelay(utime_t delay)
+{
+ timer_delayHp(us_to_hptime(delay));
+}
+#endif
+
+#ifndef CONFIG_TIMER_DISABLE_EVENTS
+
+#include <mware/event.h>
+
+/**
+ * The timer driver supports multiple synchronous timers
+ * that can trigger an event when they expire.
+ *
+ * \sa timer_add()
+ * \sa timer_abort()
+ */
+typedef struct Timer
+{
+ Node link; /**< Link into timers queue */
+ ticks_t _delay; /**< Timer delay in ms */
+ ticks_t tick; /**< Timer will expire at this tick */
+ Event expire; /**< Event to execute when the timer expires */
+ DB(uint16_t magic;)
+} Timer;
+
+/** Timer is active when Timer.magic contains this value (for debugging purposes). */
+#define TIMER_MAGIC_ACTIVE 0xABBA
+#define TIMER_MAGIC_INACTIVE 0xBAAB
+
+extern void timer_add(Timer *timer);
+extern Timer *timer_abort(Timer *timer);
+
+/** Set the timer so that it calls an user hook when it expires */
+INLINE void timer_set_event_softint(Timer *timer, Hook func, iptr_t user_data)
+{
+ event_initSoftInt(&timer->expire, func, user_data);
+}
+
+/** Set the timer delay (the time before the event will be triggered) */
+INLINE void timer_setDelay(Timer *timer, ticks_t delay)
+{
+ timer->_delay = delay;
+}
+
+#endif /* CONFIG_TIMER_DISABLE_EVENTS */
+
+#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
+
+/** Set the timer so that it sends a signal when it expires */
+INLINE void timer_set_event_signal(Timer *timer, struct Process *proc, sigmask_t sigs)
+{
+ event_initSignal(&timer->expire, proc, sigs);
+}
+
+#endif /* CONFIG_KERN_SIGNALS */
+
+
+#endif /* DRV_TIMER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005,2008 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Low-level timer module for Qt emulator (implementation).
+ */
+#include <cfg/compiler.h> // hptime.t
+#include <os/hptime.h>
+
+#include <signal.h> // sigaction()
+#include <sys/time.h> // setitimer()
+#include <string.h> // memset()
+
+
+// Forward declaration for the user interrupt server routine.
+void timer_isr(int);
+
+/// HW dependent timer initialization.
+static void timer_hw_init(void)
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+
+ // Setup interrupt callback
+ sa.sa_handler = timer_isr;
+ sigemptyset(&sa.sa_mask);
+ sigaddset(&sa.sa_mask, SIGALRM);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGALRM, &sa, NULL);
+
+ // Setup POSIX realtime timer to interrupt every 1/TIMER_TICKS_PER_SEC.
+ static struct itimerval itv =
+ {
+ { 0, 1000000 / TIMER_TICKS_PER_SEC }, /* it_interval */
+ { 0, 1000000 / TIMER_TICKS_PER_SEC } /* it_value */
+ };
+ setitimer(ITIMER_REAL, &itv, NULL);
+}
+
+INLINE hptime_t timer_hw_hpread(void)
+{
+ return hptime_get();
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Low-level timer module for POSIX systems (interface).
+ */
+#ifndef DRV_TIMER_POSIX_H
+#define DRV_TIMER_POSIX_H
+
+// HW dependent timer initialization
+
+#define DEFINE_TIMER_ISR void timer_isr(UNUSED_ARG(int, arg))
+
+/** Most Linux kernels can't do better than this (CONFIG_HZ=250). */
+#define TIMER_TICKS_PER_SEC 250
+
+#define TIMER_HW_CNT (1<<31) /* We assume 32bit integers here */
+
+#include <os/hptime.h>
+
+/// Frequency of the hardware high-precision timer.
+#define TIMER_HW_HPTICKS_PER_SEC HPTIME_TICKS_PER_SECOND
+
+/// Not needed.
+#define timer_hw_irq() do {} while (0)
+
+#endif /* DRV_TIMER_POSIX_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Low-level timer module for Qt emulator (implementation).
+ */
+#include <cfg/compiler.h> /* hptime.t */
+
+// Qt headers
+#include <QtCore/QDateTime>
+#include <QtCore/QTimer>
+
+
+// The user interrupt server routine
+void timer_isr(void);
+
+
+/**
+ * Singleton class for Qt-based hardware timer emulation.
+ */
+class EmulTimer : public QObject
+{
+private:
+ Q_OBJECT;
+
+ /// System timer (counts ms since application startup)
+ QTime system_time;
+
+ /// The 1ms "hardware" tick counter.
+ QTimer timer;
+
+ /**
+ * We deliberately don't use RAII because the real hardware
+ * we're simulating needs to be initialized manually.
+ */
+ bool initialized;
+
+ /// Private ctor (singleton)
+ EmulTimer() : initialized(false) { }
+
+public:
+ /// Return singleton instance
+ static EmulTimer &instance()
+ {
+ static EmulTimer et;
+ return et;
+ }
+
+ /// Start timer emulator.
+ void init()
+ {
+ // Timer initialized twice?
+ ASSERT(!initialized);
+
+ // Record initial time
+ system_time.start();
+
+ // Activate timer interrupt
+ timer.connect(&timer, SIGNAL(timeout()), this, SLOT(timerInterrupt()));
+ timer.start(1000 / TIMER_TICKS_PER_SEC);
+
+ initialized = true;
+ }
+
+ /// Return current time in high-precision format.
+ hptime_t hpread()
+ {
+ ASSERT(initialized);
+ return system_time.elapsed();
+ }
+
+public slots:
+ void timerInterrupt(void)
+ {
+ // Just call user interrupt server, timer restarts automatically.
+ timer_isr();
+ }
+
+};
+
+#include "timer_qt_moc.cpp"
+
+
+/// HW dependent timer initialization.
+static void timer_hw_init(void)
+{
+ // Kick EmulTimer initialization
+ EmulTimer::instance().init();
+}
+
+INLINE hptime_t timer_hw_hpread(void)
+{
+ return EmulTimer::instance().hpread();
+}
+
+/** Not needed, timer IRQ handler called only for timer source */
+#define timer_hw_triggered() (true)
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Low-level timer module for Qt emulator (interface).
+ */
+#ifndef DRV_TIMER_QT_H
+#define DRV_TIMER_QT_H
+
+// HW dependent timer initialization
+
+#define DEFINE_TIMER_ISR void timer_isr(void)
+#define TIMER_TICKS_PER_SEC 250
+#define TIMER_HW_CNT (1<<31) /* We assume 32bit integers here */
+
+/// Type of time expressed in ticks of the hardware high-precision timer.
+typedef unsigned int hptime_t;
+
+/// Frequency of the hardware high-precision timer.
+#define TIMER_HW_HPTICKS_PER_SEC 1000
+
+/// Not needed.
+#define timer_hw_irq() do {} while (0)
+
+#endif /* DRV_TIMER_QT_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Hardware independent timer driver (implementation)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "timer.c"
+#include "mware/event.c"
+#include "os/hptime.c"
+
+static void timer_test_constants(void)
+{
+ kprintf("TIMER_HW_HPTICKS_PER_SEC=%lu\n", TIMER_HW_HPTICKS_PER_SEC);
+ #ifdef TIMER_PRESCALER
+ kprintf("TIMER_PRESCALER=%d\n", TIMER_PRESCALER);
+ #endif
+ #ifdef TIMER1_OVF_COUNT
+ kprintf("TIMER1_OVF_COUNT=%d\n", (int)TIMER1_OVF_COUNT);
+ #endif
+ kprintf("TIMER_TICKS_PER_SEC=%d\n", (int)TIMER_TICKS_PER_SEC);
+ kprintf("\n");
+ kprintf("ms_to_ticks(100)=%lu\n", ms_to_ticks(100));
+ kprintf("ms_to_ticks(10000)=%lu\n", ms_to_ticks(10000));
+ kprintf("us_to_ticks(100)=%lu\n", us_to_ticks(100));
+ kprintf("us_to_ticks(10000)=%lu\n", us_to_ticks(10000));
+ kprintf("\n");
+ kprintf("ticks_to_ms(100)=%lu\n", ticks_to_ms(100));
+ kprintf("ticks_to_ms(10000)=%lu\n", ticks_to_ms(10000));
+ kprintf("ticks_to_us(100)=%lu\n", ticks_to_us(100));
+ kprintf("ticks_to_us(10000)=%lu\n", ticks_to_us(10000));
+ kprintf("\n");
+ kprintf("hptime_to_us(100)=%lu\n", hptime_to_us(100));
+ kprintf("hptime_to_us(10000)=%lu\n", hptime_to_us(10000));
+ kprintf("us_to_hptime(100)=%lu\n", us_to_hptime(100));
+ kprintf("us_to_hptime(10000)=%lu\n", us_to_hptime(10000));
+}
+
+static void timer_test_delay(void)
+{
+ int i;
+
+ kputs("Delay test\n");
+ for (i = 0; i < 1000; i += 100)
+ {
+ kprintf("delay %d...", i);
+ timer_delay(i);
+ kputs("done\n");
+ }
+}
+
+static void timer_test_hook(iptr_t _timer)
+{
+ Timer *timer = (Timer *)(void *)_timer;
+
+ kprintf("Timer %ld expired\n", ticks_to_ms(timer->_delay));
+ timer_add(timer);
+}
+
+static void timer_test_async(void)
+{
+ static Timer test_timers[5];
+ static const mtime_t test_delays[5] = { 170, 50, 310, 1500, 310 };
+ size_t i;
+
+ for (i = 0; i < countof(test_timers); ++i)
+ {
+ Timer *timer = &test_timers[i];
+ timer_setDelay(timer, ms_to_ticks(test_delays[i]));
+ timer_set_event_softint(timer, timer_test_hook, (iptr_t)timer);
+ timer_add(timer);
+ }
+}
+
+static void timer_test_poll(void)
+{
+ int secs = 0;
+ mtime_t start_time = ticks_to_ms(timer_clock());
+ mtime_t now;
+
+ while (secs <= 10)
+ {
+ now = ticks_to_ms(timer_clock());
+ if (now - start_time >= 1000)
+ {
+ ++secs;
+ start_time += 1000;
+ kprintf("seconds = %d, ticks=%ld\n", secs, now);
+ }
+ wdt_reset();
+ }
+}
+
+int main(void)
+{
+ wdt_init(7);
+ timer_init();
+ timer_test_constants();
+ timer_test_delay();
+ timer_test_async();
+ timer_test_poll();
+ return 0;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Watchdog interface
+ */
+
+#ifndef DRV_WDT_H
+#define DRV_WDT_H
+
+#include <appconfig.h>
+#include <cfg/compiler.h> // INLINE
+#include <cfg/arch_config.h>
+
+/* Configury sanity check */
+#if !defined(CONFIG_WATCHDOG) || (CONFIG_WATCHDOG != 0 && CONFIG_WATCHDOG != 1)
+ #error CONFIG_WATCHDOG must be defined to either 0 or 1
+#endif
+
+#if CONFIG_WATCHDOG
+ #include <cpu/detect.h>
+ #include <cfg/os.h>
+
+ #if OS_QT
+ #if _QT < 4
+ #include <qapplication.h>
+ #else
+ #include <QtGui/QApplication>
+ #endif
+ #elif OS_POSIX
+ #include <sys/select.h>
+ #elif CPU_AVR
+ #include <avr/io.h>
+ #include <cfg/macros.h> // BV()
+ #if CPU_AVR_ATMEGA1281 // Name is different in atmega1281
+ #define WDTCR WDTCSR
+ #endif
+ #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
+ #include <task.h> /* taskYIELD() */
+ #else
+ #error unknown CPU
+ #endif
+#endif /* CONFIG_WATCHDOG */
+
+/**
+ * Reset the watchdog timer.
+ */
+INLINE void wdt_reset(void)
+{
+#if CONFIG_WATCHDOG
+ #if OS_QT
+ // Let Qt handle events
+ ASSERT(qApp);
+ qApp->processEvents();
+ #elif OS_POSIX
+ static struct timeval tv = { 0, 0 };
+ select(0, NULL, NULL, NULL, &tv);
+ #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
+ vTaskDelay(1);
+ #elif CPU_AVR
+ __asm__ __volatile__ ("wdr");
+ #else
+ #error unknown CPU
+ #endif
+#endif /* CONFIG_WATCHDOG */
+}
+
+/**
+ * Set watchdog timer timeout.
+ *
+ * \param timeout 0: 16.3ms, 7: 2.1s
+ */
+INLINE void wdt_init(uint8_t timeout)
+{
+#if CONFIG_WATCHDOG
+ #if OS_QT
+ // Create a dummy QApplication object
+ if (!qApp)
+ {
+ int argc;
+ new QApplication(argc, (char **)NULL);
+ }
+ (void)timeout;
+ #elif OS_POSIX
+ (void)timeout; // NOP
+ #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
+ /* nop */
+ #elif CPU_AVR
+ WDTCR |= BV(WDCE) | BV(WDE);
+ WDTCR = timeout;
+ #else
+ #error unknown CPU
+ #endif
+#else
+ (void)timeout;
+#endif /* CONFIG_WATCHDOG */
+}
+
+INLINE void wdt_start(void)
+{
+#if CONFIG_WATCHDOG
+ #if OS_QT
+ // NOP
+ #elif OS_POSIX
+ // NOP
+ #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
+ /* nop */
+ #elif CPU_AVR
+ WDTCR |= BV(WDE);
+ #else
+ #error unknown CPU
+ #endif
+#endif /* CONFIG_WATCHDOG */
+}
+
+INLINE void wdt_stop(void)
+{
+#if CONFIG_WATCHDOG
+ #if OS_QT
+ // NOP
+ #elif OS_POSIX
+ // NOP
+ #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
+ /* nop */
+ #elif CPU_AVR
+ WDTCR |= BV(WDCE) | BV(WDE);
+ WDTCR &= ~BV(WDE);
+ #else
+ #error unknown CPU
+ #endif
+#endif /* CONFIG_WATCHDOG */
+}
+
+#endif /* DRV_WDT_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Notifier obj (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.5 2005/06/09 13:49:22 batt
+ *#* Reformat; correct some comments.
+ *#*
+ *#* Revision 1.4 2005/06/09 13:23:58 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.3 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#include <cfg/debug.h>
+
+#include <dt/dtag.h>
+#include <dt/dnotifier.h>
+#include <mware/list.h>
+
+/**
+ * Default update used to notify target: notify all trasparently all
+ * targets in the list.
+ */
+static void notifier_update(DNotifier *n, dtag_t tag, dval_t val)
+{
+ dnotify_targets(n, tag, val);
+}
+
+/**
+ * Init.
+ */
+void notifier_init(DNotifier *n)
+{
+ // Init instance
+ n->update = notifier_update;
+ LIST_INIT(&n->targets);
+}
+
+/**
+ * Search in the map a tag and a val corresponding to the ones supplied.
+ * If a match is found change them to the corresponding ones in the map.
+ * If map is NULL the filter is trasparent and all messages sent to filter
+ * will be forwarded to its target.
+ */
+void filter_update(DFilter *f, dtag_t tag, dval_t val)
+{
+
+ const DFilterMap *map = f->map;
+
+ if (map)
+ {
+ while (map->src.tag != TAG_END)
+ {
+ if ((map->src.tag == tag) && (map->src.val == val))
+ {
+ tag = map->dst.tag;
+ val = map->dst.val;
+ break;
+ }
+ /* TAG_ANY matches anything */
+ if (map->src.tag == TAG_ANY)
+ break;
+ map++;
+ }
+
+ if (map->src.tag != TAG_END)
+ dnotify(f->target, tag, val);
+ }
+ else
+ dnotify(f->target, tag, val);
+}
+
+
+/**
+ * Search in the table a tag corresponding to the one supplied and a val
+ * that has at least the mask map supplied bits to one.
+ * If a match is found change them to the corresponding ones in the map.
+ * If map is NULL the filter is trasparent and all messages sent to filter
+ * will be forwarded to its target.
+ */
+void filter_mask_update(DFilter *f, dtag_t tag, dval_t val)
+{
+
+ const DFilterMap *map = f->map;
+ dfilter_mask_t mask;
+
+ if (map)
+ {
+ while (map->src.tag != TAG_END)
+ {
+ mask = (dfilter_mask_t) map->src.val;
+ if ((map->src.tag == tag) && ((mask & (dfilter_mask_t)val) == mask))
+ {
+ tag = map->dst.tag;
+ val = map->dst.val;
+ break;
+ }
+ /* TAG_ANY matches anything */
+ if (map->src.tag == TAG_ANY)
+ break;
+ map++;
+ }
+
+
+ if (map->src.tag != TAG_END)
+ dnotify(f->target, tag, val);
+ }
+ else
+ dnotify(f->target, tag, val);
+}
+
+
+#define FILTER_MAGIC_ACTIVE 0xAA
+/**
+ * Init filter.
+ * If \a masked is true, all the fields value in \a map must be interpreted as a mask of bits.
+ */
+void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target)
+{
+ // Init instance
+ if (masked)
+ f->update = (update_filter_ptr)filter_mask_update;
+ else
+ f->update = (update_filter_ptr)filter_update;
+
+ /* set filter map and target */
+ f->map = map;
+ f->target = target;
+
+ /* these ensure that the filter is not inserted in more than one list */
+ ASSERT(f->magic != FILTER_MAGIC_ACTIVE);
+ DB(f->magic = FILTER_MAGIC_ACTIVE;)
+
+ /* Add the filter to source filter list */
+ ADDTAIL(&source->targets, &f->link);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Notifier obj (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.4 2005/06/09 13:23:58 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.3 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+#ifndef DT_DNOTIFIER_H
+#define DT_DNOTIFIER_H
+
+#include <cfg/debug.h>
+#include <dt/dtag.h>
+#include <mware/list.h>
+
+//Fwd declaretion.
+struct DNotifier;
+struct DFilter;
+
+typedef void (* update_func_ptr)(struct DNotifier *, dtag_t, dval_t);
+typedef void (* update_filter_ptr)(struct DFilter *, dtag_t, dval_t);
+
+/**
+ * Base object for receive and forward messages.
+ * It contains an update function used to update itslef and a list to
+ * notify other DNotifer eventually connected.
+ */
+typedef struct DNotifier
+{
+ /// Receive new attributes from other notifiers.
+ update_func_ptr update;
+
+ /// List of target notifiers to set new attributes to.
+ List targets;
+} DNotifier;
+
+/**
+ * Map for messages.
+ * Used to translate src message to dst message.
+ */
+typedef struct DFilterMap
+{
+ DTagItem src;
+ DTagItem dst;
+} DFilterMap;
+
+
+/**
+ * A filter is an interface between two notifier.
+ * It can translate messages between them through a map (if it is not null).
+ */
+typedef struct DFilter
+{
+ /// Allow creating a list of dfilter objects.
+ Node link;
+
+ /// Target of the filter
+ DNotifier *target;
+
+ /// Update function called by the source dnotifier
+ update_filter_ptr update;
+
+ ///Map for translating messages for target
+ const DFilterMap *map;
+
+ ///Used in debug to prevent inserting this filter in more than one list
+ DB(uint8_t magic;)
+} DFilter;
+
+/// Type for filter-mask checking
+typedef uint16_t dfilter_mask_t;
+
+/// Filter init
+void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target);
+
+/// Filter update function without masking capabilities.
+void filter_update(DFilter *f, dtag_t tag, dval_t val);
+
+/// Filter update function with masking capabilities.
+void filter_mask_update(DFilter *f, dtag_t tag, dval_t val);
+
+/// Notifier init
+void notifier_init(DNotifier *n);
+
+
+/**
+ * Macro to notify the target object.
+ */
+INLINE void dnotify(DNotifier *target, dtag_t tag, dval_t val)
+{
+ if (target)
+ target->update(target, tag, val);
+}
+
+/**
+ * Macro to notify all the targets of \a target object.
+ */
+INLINE void dnotify_targets(DNotifier *target, dtag_t tag, dval_t val)
+{
+ DFilter *f;
+ if (!ISLISTEMPTY(&target->targets))
+ FOREACHNODE(f, &target->targets)
+ f->update(f, tag, val);
+}
+
+
+/**
+ * Macro that connect \a src notifier to \a tgt using \a map and passing \a opt for filtering option.
+ * It declares a static filter to achieve connection and messages translation.
+ * \note Due its static filter declaration, DCONNECT MUST NOT be used inside loops or in functions called multiple times.
+ * Failing to do so will lead to unpredictable connections between notifiers.
+ */
+#define DCONNECT(src, tgt, map, opt) \
+ do { \
+ static DFilter _filter_; /* Declare a filter */ \
+ filter_init(&(_filter_), map, opt, src, tgt); /* Init it. */ \
+ } while (0)
+
+
+#endif /* DT_DNOTIFIER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Tags interface.
+ * This module contains the base message definitions and the list of all available tags.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.8 2005/06/07 15:22:29 batt
+ *#* Add const_dval_t.
+ *#*
+ *#* Revision 1.7 2005/06/06 17:42:23 batt
+ *#* Add error tag TAG_ERROR.
+ *#*
+ *#* Revision 1.6 2005/06/06 12:45:33 batt
+ *#* Add TAG_NONE tag.
+ *#*
+ *#* Revision 1.5 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.4 2005/05/31 11:09:52 batt
+ *#* Add some tags.
+ *#*
+ *#* Revision 1.3 2005/05/26 14:55:12 batt
+ *#* Add form_processTime; change form_kbdProcess to form_processKey.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:43:33 batt
+ *#* Add new message filter interface.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#ifndef DT_DTAG_H
+#define DT_DTAG_H
+
+#include <cfg/macros.h>
+
+/** Type for values associated with tags. */
+typedef iptr_t dval_t;
+
+/** Type for constant values associated with tags. */
+typedef const_iptr_t const_dval_t;
+
+/** Type for tag */
+typedef enum dtag_t
+{
+ TAG_END = 0,
+ TAG_NONE,
+ TAG_ANY,
+ TAG_SETVALUE,
+ TAG_UP,
+ TAG_DOWN,
+ TAG_START,
+ TAG_STOP,
+ TAG_TOGGLE,
+ TAG_KEY,
+ TAG_TIME,
+ TAG_ERROR,
+} dtag_t;
+
+/** This is the basic message structure used by all dnotifiers. */
+typedef struct DTagItem
+{
+ dtag_t tag;
+ dval_t val;
+} DTagItem;
+
+/** Marker to indicate the end of a map for message filtering/translating */
+#define TAG_END_MARKER {{TAG_END, 0}, {TAG_END, 0}}
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Widget (implementation).
+ * A widget is typically a graphic object on a device.
+ * Its proproperties are the position, the size and a context on which the widget is drawn.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@ðeveler.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#include <dt/dwidget.h>
+#include <dt/dnotifier.h>
+
+/**
+ * Init the widget of \a pos and \a size on the drawing \a context.
+ */
+void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context)
+{
+ // Init superclass
+ notifier_init(&w->notifier);
+
+ // Init instance
+ w->pos = pos;
+ w->size = size;
+ w->context = context;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Widget (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#ifndef DT_DWIDGET_H
+#define DT_DWIDGET_H
+
+#include <dt/dnotifier.h>
+#include <cfg/compiler.h>
+
+/** Widget position. */
+typedef uint8_t dpos_t;
+
+/** Widget drawing context. */
+typedef iptr_t dcontext_t;
+
+/** Widget definition. */
+typedef struct DWidget
+{
+ DNotifier notifier;
+
+ dpos_t pos;
+ dpos_t size;
+ dcontext_t *context;
+} DWidget;
+
+
+void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context);
+
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Edit bool widget (implementation).
+ * This widget handles boolean editing.
+ * The boolean value will be displayed using two strings:
+ * one when the bool is false and one when it's true.
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@ðeveler.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/31 11:11:37 batt
+ *#* Edit bool: first release.
+ *#*
+ *#*/
+
+#include <mware/editbool.h>
+#include <dt/dtag.h>
+
+#include <drv/lcd_text.h>
+
+/**
+ * Init widget.
+ */
+void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *value, const char *true_string, const char *false_string)
+{
+ // Initialize superclass
+ widget_init(&e->widget, pos, size, context);
+
+ // Override superclass methods
+ e->widget.notifier.update = (update_func_ptr)editbool_update;
+
+ // Init instance
+ e->value = value;
+ e->true_string = true_string;
+ e->false_string = false_string;
+ e->draw = editbool_draw;
+}
+
+/**
+ * Handle the messages (edit the bool).
+ */
+void editbool_update(DEditBool *e, dtag_t tag, dval_t _val)
+{
+ bool changed = false;
+
+ switch (tag)
+ {
+ case TAG_SETVALUE:
+ *e->value = (bool)_val;
+ changed = true;
+ break;
+
+ case TAG_TOGGLE:
+ *e->value = !*e->value;
+ changed = true;
+ break;
+ default:
+ break;
+ }
+
+ if (changed)
+ {
+ e->draw(e);
+ dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value);
+ }
+}
+
+/**
+ * Draw the string on the context.
+ */
+void editbool_draw(DEditBool *e)
+{
+ lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL, "%*s", (int)e->widget.size , *e->value? e->true_string: e->false_string);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Edit bool widget (interface).
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/31 11:11:37 batt
+ *#* Edit bool: first release.
+ *#*
+ *#*/
+
+#ifndef DT_EDITBOOL_H
+#define DT_EDITBOOL_H
+
+#include <dt/dwidget.h>
+#include <dt/dtag.h>
+
+typedef struct DEditBool
+{
+ DWidget widget;
+ bool *value;
+ const char *true_string;
+ const char *false_string;
+ void (*draw)(struct DEditBool *);
+} DEditBool;
+
+void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *val, const char *true_str, const char *false_str);
+void editbool_update(DEditBool *e, dtag_t tag, dval_t val);
+void editbool_draw(DEditBool *e);
+
+
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Integer edit widget (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.7 2005/06/10 15:46:09 batt
+ *#* Add EDIS_WRAP style that wrap around min and max.
+ *#*
+ *#* Revision 1.6 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.5 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.4 2005/05/31 11:09:34 batt
+ *#* Fix sending pointer instead of value bug.
+ *#*
+ *#* Revision 1.3 2005/05/26 14:46:20 batt
+ *#* Use correct tag; remove warning.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#include <mware/editint.h>
+#include <dt/dwidget.h>
+#include <dt/dtag.h>
+#include <dt/dnotifier.h>
+
+#include <cfg/macros.h>
+
+#include <drv/lcd_text.h>
+
+/**
+ * Init.
+ */
+void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max)
+{
+ // Initialize superclass
+ widget_init(&e->widget, pos, size, context);
+
+ // Override superclass methods
+ e->widget.notifier.update = (update_func_ptr)editint_update;
+
+ // Init instance
+ e->value = value;
+ e->min = min;
+ e->max = max;
+ e->style = EDIS_DEFAULT;
+ e->draw = editint_draw;
+}
+
+/**
+ * Handle the messages (edit the int).
+ */
+void editint_update(DEditInt *e, dtag_t tag, dval_t _val)
+{
+ bool changed = false;
+ int val = (int)_val;
+
+ switch (tag)
+ {
+ case TAG_SETVALUE:
+ *e->value = MINMAX(e->min, val, e->max);
+ changed = true;
+ break;
+
+ /* Increments the integer by val */
+ case TAG_UP:
+ if (e->style & EDIS_WRAP)
+ {
+ if (*e->value + val > e->max)
+ *e->value = (*e->value + val - e->min) % (e->max - e->min + 1) + e->min;
+ else
+ *e->value += val;
+ }
+ else
+ *e->value = MIN(*e->value + val, e->max);
+ changed = true;
+ break;
+ /* Decrements the integer by val */
+ case TAG_DOWN:
+ if (e->style & EDIS_WRAP)
+ {
+ if (*e->value - val < e->min)
+ *e->value = e->max - (e->max - (*e->value - val)) % (e->max - e->min + 1);
+ else
+ *e->value -= val;
+ }
+ else
+ *e->value = MAX(*e->value - val, e->min);
+ changed = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (changed)
+ {
+ e->draw(e);
+ dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value);
+ }
+}
+
+/**
+ * Draw the integer on the context.
+ */
+void editint_draw(DEditInt *e)
+{
+ lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL,"%*d", (int)e->widget.size, *e->value);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Integer edit (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/10 15:46:09 batt
+ *#* Add EDIS_WRAP style that wrap around min and max.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#ifndef DT_EDITINT_H
+#define DT_EDITINT_H
+
+#include <dt/dwidget.h>
+#include <dt/dtag.h>
+#include <drv/lcd_text.h>
+
+#include <cfg/compiler.h>
+#include <cfg/macros.h>
+
+
+#define EDIS_DEFAULT 0
+#define EDIS_CURSORLEFT BV(0)
+#define EDIS_WRAP BV(1)
+
+/** Type for edit style */
+typedef uint16_t dstyle_t;
+
+typedef struct DEditInt
+{
+ DWidget widget;
+
+ int *value;
+ int min;
+ int max;
+ dstyle_t style;
+ void (*draw)(struct DEditInt *);
+
+} DEditInt;
+
+void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max);
+void editint_update(DEditInt *e, dtag_t tag, dval_t val);
+void editint_draw(DEditInt *e);
+
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Qt-based emulator framework for embedded applications (implementation)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.6 2006/05/28 12:17:57 bernie
+ *#* Drop almost all the Qt3 cruft.
+ *#*
+ *#* Revision 1.5 2006/05/27 22:30:56 bernie
+ *#* Add some delay to slow things down.
+ *#*
+ *#* Revision 1.4 2006/02/24 01:35:40 bernie
+ *#* Update for new emulator.
+ *#*
+ *#* Revision 1.3 2006/02/20 02:00:40 bernie
+ *#* Port to Qt 4.1.
+ *#*
+ *#* Revision 1.2 2006/01/16 03:51:51 bernie
+ *#* Fix boilerplate.
+ *#*
+ *#* Revision 1.1 2006/01/16 03:37:12 bernie
+ *#* Add emulator skeleton.
+ *#*
+ *#*/
+
+#include "emul.h"
+#include "emulwin.h"
+#include <cfg/module.h>
+
+#include <appconfig.h>
+#if CONFIG_KERNEL
+ #include <config_kern.h>
+#endif
+
+
+#include <cstdlib> // std::exit()
+
+#include <QtGui/qapplication.h>
+
+
+/// The global emulator instance.
+Emulator *emul;
+
+#if CONFIG_KERNEL
+ #include <mware/list.h>
+
+ /// List of process stacks
+ List StackFreeList;
+
+ // HACK: Reserve 64KB of stack space for kernel processes
+ const int NPROC = 8;
+ int stacks[NPROC][(64 * 1024) / sizeof(int)];
+#endif
+
+Emulator::Emulator(int &argc, char **argv) :
+ emulApp(new QApplication(argc, argv)),
+ emulWin(new EmulWin(this))
+{
+ emulWin->show();
+}
+
+
+Emulator::~Emulator()
+{
+ // we don't delete emulWin because it automatically
+ // deletes itself when closed
+ delete emulApp;
+}
+
+
+NORETURN void Emulator::quit()
+{
+ // WHAT A KLUDGE!
+ this->~Emulator();
+ emul = NULL;
+
+ // do we have a better way to shut down the emulation?
+ exit(0);
+}
+
+MOD_DEFINE(emul)
+
+/// Main emulator entry point.
+extern "C" void emul_init(int *argc, char *argv[])
+{
+ // setup global emulator pointer
+ emul = new Emulator(*argc, argv);
+
+#if CONFIG_KERNEL
+ LIST_INIT(&StackFreeList);
+ for (int i = 0; i < NPROC; i++)
+ ADDTAIL(&StackFreeList, (Node *)stacks[i]);
+#endif
+
+ MOD_INIT(emul);
+}
+
+extern "C" void emul_cleanup()
+{
+ MOD_CLEANUP(emul);
+
+ delete emul;
+ emul = NULL;
+}
+
+extern "C" void emul_idle()
+{
+ // We process GUI events when the application is idle.
+ emul->emulApp->processEvents();
+ usleep(1000);
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Qt-based emulator framework for embedded applications (interface)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/02/15 09:11:17 bernie
+ *#* Add keyboard emulator.
+ *#*
+ *#* Revision 1.3 2006/01/23 23:12:08 bernie
+ *#* Let Doxygen see through C++ protected section.
+ *#*
+ *#* Revision 1.2 2006/01/16 03:51:51 bernie
+ *#* Fix boilerplate.
+ *#*
+ *#* Revision 1.1 2006/01/16 03:37:12 bernie
+ *#* Add emulator skeleton.
+ *#*
+ *#*/
+
+#ifndef EMUL_EMUL_H
+#define EMUL_EMUL_H
+
+#include <cfg/compiler.h>
+
+#if defined(__cplusplus) || defined(__doxygen__)
+
+// fwd decls
+class QApplication;
+class EmulWin;
+class EmulPRT;
+class EmulLCD;
+class EmulKbd;
+class QCheckBox;
+class QSlider;
+class QLabel;
+
+class Emulator
+{
+// data members
+public:
+ QApplication *emulApp; ///< QT Application.
+ EmulWin *emulWin; ///< Main window.
+
+ EmulLCD *emulLCD; ///< Display emulator.
+ EmulKbd *emulKbd; ///< Keyboard emulator.
+
+// construction
+ Emulator(int &argc, char **argv);
+ ~Emulator();
+
+// public methods
+ void quit();
+};
+
+extern Emulator *emul;
+
+#endif /* __cplusplus */
+
+EXTERN_C void emul_init(int *argc, char *argv[]);
+EXTERN_C void emul_cleanup();
+EXTERN_C void emul_idle();
+
+#endif /* EMUL_EMUL_H */
+
--- /dev/null
+#
+# Copyright 2007 Bernardo Innocenti (http://www.codewiz.org/)
+# All rights reserved.
+#
+# Author: Bernardo Innocenti <bernie@develer.com>
+#
+# Qt configuration for devlib emulator demo. Include it from
+# your app Makefile fragment
+
+EMUL_CFLAGS = $(shell pkg-config QtCore QtGui --cflags) -DQT_CLEAN_NAMESPACE -DQT3_SUPPORT
+EMUL_LDFLAGS = $(shell pkg-config QtCore QtGui --libs)
+QT_MOC = $(shell pkg-config QtCore --variable=moc_location)
+#QT_UIC = $(shell pkg-config QtCore --variable=uic_location)
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief QT-based widget for keyboard emulation (implementation)
+ */
+
+#include "emulkbd.h"
+#include "emul.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+#include <QtGui/QSizePolicy>
+#include <QtGui/QLayout>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QEvent>
+#include <QtCore/QSize>
+#include <QtCore/QRect>
+
+
+EmulKey::EmulKey(EmulKbd *kbd, const char *label, int _keycode, int _row, int _col) :
+ QPushButton(label, kbd),
+ row(_row), col(_col),
+ keycode(_keycode)
+{
+ // don't let the widget get focus
+ setFocusPolicy(Qt::NoFocus);
+
+ // unused
+ connect(this, SIGNAL(pressed()), this, SLOT(keyPressed()));
+ connect(this, SIGNAL(released()), this, SLOT(keyReleased()));
+}
+
+
+EmulKey::~EmulKey()
+{
+ // nop
+}
+
+
+/**
+ * Override standad QButton behaviour: we must also emit the signals.
+ */
+// unused
+void EmulKey::setDown(bool enable)
+{
+ // let our superclass do everything else
+ QPushButton::setDown(enable);
+
+ if (enable)
+ emit pressed();
+ else
+ emit released();
+}
+
+
+// unused
+void EmulKey::keyPressed(void)
+{
+ static_cast<EmulKbd *>(parent())->setKey(row, col, true);
+}
+
+
+// unused
+void EmulKey::keyReleased(void)
+{
+ static_cast<EmulKbd *>(parent())->setKey(row, col, false);
+}
+
+
+EmulKbd::EmulKbd(QWidget *parent, Qt::WFlags f) :
+ QFrame(parent, f),
+ layout(new QGridLayout(this)),
+ active_row(0)
+{
+ setFrameStyle(QFrame::Box | QFrame::Sunken);
+ setLineWidth(1);
+ setFocusPolicy(Qt::StrongFocus);
+ frame_width = frameWidth();
+}
+
+
+EmulKbd::~EmulKbd()
+{
+ delete layout;
+}
+
+
+QSizePolicy EmulKbd::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+}
+
+
+void EmulKbd::resizeEvent(QResizeEvent *event)
+{
+ // Let our superclass process the event first
+ QFrame::resizeEvent(event);
+}
+
+
+// handle key presses for all keys in keyboard
+bool EmulKbd::event(QEvent *_e)
+{
+ switch (_e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ QKeyEvent *e = static_cast<QKeyEvent *>(_e);
+ int keycode = e->key();
+ EmulKey *key;
+
+ // ignore repeated keys
+ if (!e->isAutoRepeat())
+ {
+ // scan all children
+ for (QObjectList::const_iterator it(children().begin()); it != children().end(); ++it)
+ {
+ // only keys, not other children!
+ if ((*it)->metaObject() == &EmulKey::staticMetaObject)
+ // if ((key = dynamic_cast<EmulKey *>(*it)))
+ {
+ key = static_cast<EmulKey *>(*it);
+
+ // same key?
+ if (key->keycode == keycode)
+ {
+ // yes, tell key to go down (or up)
+ key->setDown(_e->type() == QEvent::KeyPress);
+ break;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ default:
+ // let superclass process this event
+ return QFrame::event(_e);
+
+ } // end switch(_e->type())
+}
+
+
+void EmulKbd::addKey(const char *label, int keycode, int row, int col, int matrix_row, int matrix_col)
+{
+ if (matrix_row == -1)
+ matrix_row = row;
+ if (matrix_col == -1)
+ matrix_col = col;
+
+ layout->addWidget(new EmulKey(this, label, keycode, matrix_row, matrix_col), row, col);
+}
+
+
+// unused
+void EmulKbd::setKey(int /*row*/, int /*col*/, bool /*on*/)
+{
+}
+
+
+void EmulKbd::setRow(int r)
+{
+ active_row = r;
+}
+
+int EmulKbd::readCols(void)
+{
+ QLayoutItem *item;
+ EmulKey *key;
+ int cols = 0;
+
+ // FIXME: QLayoutIterator is obsolete in Qt4
+ for(QLayoutIterator it(layout->iterator()); (item = it.current()); ++it)
+ {
+ key = static_cast<EmulKey *>(item->widget());
+ if (key->row == active_row)
+ {
+ if (key->isDown())
+ cols |= (1<<key->col);
+ }
+ }
+ return cols;
+}
+
+extern "C" void emul_kbdSetRows(int r)
+{
+ emul->emulKbd->setRow(r);
+}
+
+
+extern "C" int emul_kbdReadCols(void)
+{
+ return emul->emulKbd->readCols();
+}
+
+#include "emulkbd_moc.cpp"
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief QT-based widget for leyboard emulation (interface)
+ */
+
+#if !defined(EMULKBD_H)
+#define EMULKBD_H
+
+#if defined (_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <QtGui/QFrame>
+
+// fwd decl
+class QGridLayout;
+class EmulKey;
+
+class EmulKbd : public QFrame
+{
+ Q_OBJECT
+
+// Data members
+protected:
+ QGridLayout *layout;
+ int frame_width;
+ int active_row;
+
+// Construction
+public:
+ EmulKbd(QWidget *parent = 0, Qt::WFlags f = 0);
+ virtual ~EmulKbd();
+
+// Public methods
+ void addKey(const char *label, int keycode, int row, int col, int matrix_row = -1, int matrix_col = -1);
+ void setRow(int row);
+ int readCols(void);
+
+// Protected methods
+protected:
+ void setKey(int row, int col, bool on);
+
+// Base class overrides
+protected:
+ virtual QSizePolicy sizePolicy() const;
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual bool event(QEvent *e);
+
+// Friends
+ friend class EmulKey;
+};
+
+
+// Private helper class for EmulKbd
+// NOTE: with protected inheritance, dynamic_cast<> does not work (gcc 2.96)
+#include <QtGui/qpushbutton.h>
+class EmulKey : public QPushButton
+{
+ Q_OBJECT
+
+// Data members
+protected:
+ int row, col;
+ int keycode;
+
+// Construction
+public:
+ EmulKey(EmulKbd *parent, const char *label, int keycode, int _row, int _col);
+ virtual ~EmulKey();
+
+// superclass overrides
+ void setDown(bool enable);
+
+protected slots:
+ void keyPressed(void);
+ void keyReleased(void);
+
+// Friends
+public:
+ friend class EmulKbd;
+};
+
+#endif // !defined(EMULKBD_H)
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Main Qt window for embedded applications emulator (implementation)
+ */
+
+#include "emulwin.h"
+
+#include <drv/lcd_gfx_qt.h>
+#include <emul/emul.h>
+#include <emul/emulkbd.h>
+
+#include <cassert>
+
+#include <QtGui/QLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QSlider>
+#include <QtGui/QCheckBox>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMessageBox>
+#include <QtCore/QDateTime>
+#include <QtCore/QTimer>
+#include <QtGui/QApplication>
+#include <QtGui/QCloseEvent>
+using namespace Qt;
+
+EmulWin::EmulWin(Emulator *e)
+{
+ setWindowTitle(tr("BeRTOS Emul Demo"));
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ // Create the menu bar
+ QMenu *file_menu = menuBar()->addMenu(tr("&File"));
+ file_menu->addAction(tr("&Quit"),
+ e->emulApp, SLOT(closeAllWindows()), CTRL+Key_Q);
+
+ menuBar()->addSeparator();
+
+ QMenu *help_menu = menuBar()->addMenu(tr("&Help"));
+ help_menu->addAction(tr("&About"),
+ this, SLOT(about()), Key_F1);
+
+ // Make a central widget to contain the other widgets
+ QWidget *central = new QWidget(this);
+ setCentralWidget(central);
+
+ // Create a layout to position the widgets
+ QHBoxLayout *box_main = new QHBoxLayout(central);
+
+ // Main layout
+ QVBoxLayout *box_right = new QVBoxLayout();
+ box_main->addLayout(box_right);
+
+ // LCD
+ QHBoxLayout *lay_lcd = new QHBoxLayout();
+ box_right->addLayout(lay_lcd);
+ lay_lcd->addStretch();
+ lay_lcd->addWidget(e->emulLCD = new EmulLCD(central));
+ lay_lcd->addStretch();
+
+ // Keyboard
+ box_right->addWidget(e->emulKbd = new EmulKbd(central));
+
+ // Setup keyboard: Label Keycode Row Col MRow MCol
+ e->emulKbd->addKey("^", Key_Up, 0, 0, 0, 0);
+ e->emulKbd->addKey("v", Key_Down, 1, 0, 0, 1);
+ e->emulKbd->addKey("OK", Key_Return, 0, 1, 0, 2);
+ e->emulKbd->addKey("ESC", Key_Escape, 1, 1, 0, 3);
+}
+
+
+EmulWin::~EmulWin()
+{
+ emul->quit();
+}
+
+
+void EmulWin::closeEvent(QCloseEvent *ce)
+{
+ emul->quit();
+ ce->accept();
+}
+
+
+void EmulWin::about()
+{
+ QMessageBox::about(this,
+ "BeRTOS Embedded Application Emulator",
+ "Version 0.1\n"
+ "Copyright 2006, 2008 Develer S.r.l. (http://www.develer.com/)\n"
+ "Copyright 2001, 2002, 2003, 2005 Bernardo Innocenti <bernie@codewiz.org>\n"
+ "All rights reserved."
+ );
+}
+
+#include "emulwin_moc.cpp"
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Main Qt window for embedded applications emulator (interface)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/05/28 12:17:56 bernie
+ *#* Drop almost all the Qt3 cruft.
+ *#*
+ *#* Revision 1.3 2006/02/20 02:00:39 bernie
+ *#* Port to Qt 4.1.
+ *#*
+ *#* Revision 1.2 2006/01/16 03:51:51 bernie
+ *#* Fix boilerplate.
+ *#*
+ *#* Revision 1.1 2006/01/16 03:37:12 bernie
+ *#* Add emulator skeleton.
+ *#*
+ *#*/
+
+#ifndef EMUL_EMULWIN_H
+#define EMUL_EMULWIN_H
+
+#include <QtGui/QMainWindow>
+
+// fwd decls
+class Emulator;
+
+class EmulWin : public QMainWindow
+{
+ Q_OBJECT
+
+// construction
+public:
+ EmulWin(Emulator *emul);
+ ~EmulWin();
+
+protected:
+ void closeEvent(QCloseEvent *);
+
+private slots:
+ void about();
+};
+
+#endif // EMUL_EMULWIN_H
+
--- /dev/null
+#! /usr/bin/perl -w
+#
+# Convert BDF files to nano-X font files
+# modified by G Haerr from bdftobogl for 16 bit MWIMAGEBITS
+# modified on 2/10/00 by K Harris to accept any size input character
+# modified on 3/26/00 by G Haerr added ascent field, fixed $IMAGE_BITS
+# modified on 2/15/06 by <bernie@develer.com> for DevLib.
+# originally from BOGL - Ben's Own Graphics Library <pfaffben@debian.org>.
+#
+
+use POSIX;
+
+if ($#ARGV < 0) {
+ print "Usage: convbdf font.bdf > font.c\n";
+ exit -1;
+}
+
+$LAST_CHAR = 0xff;
+$IMAGE_BITS = 8;
+$IMAGE_NIBBLES = $IMAGE_BITS/4;
+$IMAGE_MASK = 0xff;
+$IMAGE_VERTICAL = 1;
+
+$file = $ARGV[0];
+
+$font = $file;
+$font =~ s#.*/##; # remove path name
+$font =~ s/\.bdf//;
+$font =~ tr/a-zA-Z0-9_/_/cs;
+
+print "/* Generated by convbdf on ", substr(`date`, 0, -1), ". */\n";
+print "#include <gfx/font.h>\n\n";
+
+open BDF, "<$file" || die;
+while (<BDF>) {
+ chop;
+ $pixel_size = $1 if /^PIXEL_SIZE (\d+)$/;
+ $font_ascent = $1 if /^FONT_ASCENT (\d+)$/;
+ $font_descent = $1 if /^FONT_DESCENT (\d+)$/;
+ $font_name = $1 if /^FONT (.*)$/;
+ $default_char = $1 if /^DEFAULT_CHAR (\d+)$/;
+
+ last if /^CHARS /;
+}
+
+print "/* Font information:\n\n";
+print " name: $font_name\n";
+print " pixel size: $pixel_size\n";
+print " ascent: $font_ascent\n";
+print " descent: $font_descent\n";
+print "*/\n\n";
+
+print "/* Font character bitmap data. */\n";
+print "static const PROGMEM uint8_t font_${font}_glyphs[] = {\n";
+
+$ch_height = $font_ascent + $font_descent;
+$ofs = 0;
+$maxwidth = 0;
+$proportional = 0;
+$firstchar = -1;
+while (<BDF>) {
+ chop;
+ undef $encoding, undef $width, undef $bbx, undef $bby, undef $bbw, undef $bbh if /^STARTCHAR /;
+ $encoding = $1 if /^ENCODING (\d+)/;
+ last if defined $encoding && $encoding > $LAST_CHAR;
+ $width = $1 if /^DWIDTH (-?\d+)/;
+ ($bbw, $bbh, $bbx, $bby) = ($1, $2, $3, $4) if /^BBX (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;
+
+ if (/^BITMAP$/) {
+ next if !defined $encoding;
+ $firstchar = $encoding if $firstchar < 0;
+ $encoding_tab[$encoding] = $ofs;
+ $width -= $bbx, $bbx = 0 if $bbx < 0;
+ $width[$encoding] = $width;
+ $maxwidth != 0 and $width != $maxwidth and $proportional = 1;
+ $maxwidth = $width if $width > $maxwidth;
+ $ch_words = int (($width+$IMAGE_BITS-1)/$IMAGE_BITS);
+ $ch_bits = $ch_words*$IMAGE_BITS;
+ for (my $i = 0; $i < $ch_height; $i++) {
+ for (my $k = 0; $k < $ch_words; $k++) {
+ $bm[$i][$k] = 0;
+ }
+ }
+ for (my $i = 0; ; $i++) {
+ $_ = <BDF>;
+ chop;
+ last if /^ENDCHAR$/;
+
+ @hexnibbles = split //,$_;
+ for (my $k=0; $k<$ch_words; $k++) {
+ $ndx = $k*$IMAGE_NIBBLES;
+ $padnibbles = @hexnibbles - $ndx;
+ # if bbx pushes bits into next word
+ # and no more bits from bdf file
+ last if $padnibbles <= 0;
+ $padnibbles = 0 if $padnibbles >= $IMAGE_NIBBLES;
+ $value = hex join '',@hexnibbles[$ndx..($ndx+$IMAGE_NIBBLES-1-$padnibbles)];
+ $value = $value << ($padnibbles*$IMAGE_NIBBLES);
+ $bm[$ch_height - $font_descent - $bby - $bbh + $i][$k] |=
+ $value >> ($bbx);
+ if ($bbx) { # handle overflow into next image_word
+ $bm[$ch_height - $font_descent - $bby - $bbh + $i][$k+1] =
+ ($value << ($IMAGE_BITS - $bbx)) & $IMAGE_MASK;
+ }
+ }
+ }
+
+ # GLYPH PREVIEW
+### printf "\n/* Character %c (0x%02x): ", $encoding, $encoding;
+ printf "\n/* Character (0x%02x): ", $encoding;
+ print "bbw=$bbw, bbh=$bbh, bbx=$bbx, bby=$bby, width=$width */\n";
+
+ # GLYPH DATA
+ if ($IMAGE_VERTICAL) {
+ my $bitstring = "";
+ for (my $k = 0; $k < int(($ch_height + $IMAGE_BITS - 1) / $IMAGE_BITS); $k++) {
+ for (my $x = 0; $x < $width; $x++) {
+ my $v = 0;
+ for (my $y = 0; $y < $IMAGE_BITS && ($y + $k * $IMAGE_BITS < $ch_height); ++$y) {
+ my $bit = ($bm[$k * $IMAGE_BITS + $y][int($x / $IMAGE_BITS)] & (1 << ($IMAGE_BITS - ($x % $IMAGE_BITS) - 1))) ? 1 : 0;
+ $bitstring .= $bit ? '*' : ' ';
+ $v |= $bit << $y;
+ }
+ $ofs++;
+ printf "0x%02x, ", $v;
+ }
+ # Preview
+ printf "/* $bitstring */\n";
+ }
+
+ }
+ else { # IMAGE_HORIZONTAL
+
+ # Preview
+ print " +", ("-" x $ch_bits), "+\n";
+ for (my $i = 0; $i < $ch_height; $i++) {
+ print " |";
+ for (my $k = 0; $k < $ch_words; $k++) {
+ for (my $j = $IMAGE_BITS - 1; $j >= 0; $j--) {
+ print $bm[$i][$k] & (1 << $j) ? "*" : " ";
+ }
+ }
+ print "|\n";
+ }
+ print " +", ("-" x $ch_bits), "+ */\n";
+
+ for (my $i = 0; $i < $ch_height; $i++) {
+ for (my $k=0; $k<$ch_words; $k++) {
+ $ofs++;
+ printf "0x%02x, ", $bm[$i][$k];
+ }
+ printf "\n";
+ }
+ }
+ }
+}
+
+print "};\n\n";
+
+#print STDERR "Maximum character width=$maxwidth\n";
+
+if ($proportional) {
+ print "/* Character->glyph data. */\n";
+ print "static const PROGMEM uint16_t ${font}_offset[] = {\n";
+ for (my $i = $firstchar; $i <= $LAST_CHAR; $i++) {
+ my $char = $i;
+ my $ofs = $encoding_tab[$i];
+ $ofs = $encoding_tab[$default_char], $char = $default_char if !defined $ofs;
+ ### printf " $ofs,\t/* %c (0x%02x) */\n", $char, $i;
+ printf " $ofs,\t/* (0x%02x) */\n", $i;
+ }
+ print "};\n\n";
+
+ print "/* Character width data. */\n";
+ print "static const PROGMEM uint8_t ${font}_width[] = {\n";
+ for (my $i = $firstchar; $i <= $LAST_CHAR; $i++) {
+ my $char = $i;
+ my $width = $width[$i];
+ $width = $width[$default_char], $char = $default_char if !defined $encoding_tab[$i];
+ ### printf " $width,\t/* %c (0x%02x) */\n", $char, $i;
+ printf " $width,\t/* (0x%02x) */\n", $i;
+ }
+ print "};\n\n";
+
+ $font_offset = "${font}_offset";
+ $font_width = "${font}_width";
+} else {
+ $font_offset = "NULL";
+ $font_width = "NULL";
+}
+
+$lastchar = $LAST_CHAR;
+#$size = $lastchar - $firstchar + 1;
+
+print <<EOF
+/* Font structure definition. */
+EXTERN_CONST Font font_${font} =
+{
+ /* .glyph = */ font_${font}_glyphs,
+ /* .name = "$font", */
+ /* .width = */ $maxwidth,
+ /* .height = */ $ch_height,
+ /* .ascent = $font_ascent, */
+ /* .first = */ $firstchar,
+ /* .last = */ $lastchar,
+ /* .offset = */ $font_offset,
+ /* .width = */ $font_width,
+};
+EOF
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Font 8x6 IBM-PC 8bit
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2006/05/27 22:30:22 bernie
+ *#* Move 6x8 font to fonts/.
+ *#*
+ *#* Revision 1.3 2006/02/10 12:29:05 bernie
+ *#* Add multiple font support in bitmaps.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:11:35 bernie
+ *#* Move graphics stuff from mware/ to gfx/.
+ *#*
+ *#* Revision 1.6 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.5 2005/01/08 09:20:38 bernie
+ *#* Add missing type in declaration.
+ *#*
+ *#* Revision 1.4 2004/12/31 16:42:55 bernie
+ *#* Sanitize for non-Harvard processors.
+ *#*
+ *#* Revision 1.3 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 15:43:16 bernie
+ *#* Import mware modules.
+ *#*/
+
+#include "font.h"
+
+static const PROGMEM uint8_t default_font_glyphs[256 * 6] =
+{
+/* 0x00 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
+ 0x3E, 0x45, 0x51, 0x45, 0x3E, 0x00, /* */
+ 0x3E, 0x7B, 0x6F, 0x7B, 0x3E, 0x00, /* */
+ 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, /* */
+ 0x08, 0x1C, 0x3E, 0x1C, 0x08, 0x00, /* */
+ 0x18, 0x5A, 0x67, 0x5A, 0x18, 0x00, /* */
+ 0x0C, 0x5E, 0x6F, 0x5E, 0x0C, 0x00, /* */
+ 0x08, 0x1C, 0x3E, 0x1C, 0x08, 0x00, /* */
+/* 0x08 */
+ 0x77, 0x63, 0x41, 0x63, 0x77, 0x00, /* */
+ 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00, /* */
+ 0x77, 0x63, 0x41, 0x63, 0x77, 0x00, /* */
+ 0x20, 0x50, 0x5A, 0x56, 0x2E, 0x00, /* */
+ 0x06, 0x29, 0x79, 0x29, 0x06, 0x00, /* */
+ 0x60, 0x60, 0x7F, 0x05, 0x07, 0x00, /* */
+ 0x18, 0x1F, 0x01, 0x61, 0x7F, 0x00, /* */
+ 0x15, 0x0E, 0x1B, 0x0E, 0x15, 0x00, /* */
+/* 0x10 */
+ 0x00, 0x08, 0x1C, 0x3E, 0x08, 0x08, /* */
+ 0x7F, 0x3E, 0x1C, 0x08, 0x00, 0x00, /* */
+ 0x14, 0x36, 0x7F, 0x36, 0x14, 0x00, /* */
+ 0x00, 0x5F, 0x00, 0x5F, 0x00, 0x00, /* */
+ 0x02, 0x05, 0x7F, 0x01, 0x7F, 0x00, /* */
+ 0x20, 0x4A, 0x55, 0x29, 0x02, 0x00, /* */
+ 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, /* */
+ 0x54, 0x76, 0x7F, 0x76, 0x54, 0x00, /* */
+/* 0x18 */
+ 0x08, 0x0C, 0x7E, 0x0C, 0x08, 0x00, /* */
+ 0x10, 0x30, 0x7E, 0x30, 0x10, 0x00, /* */
+ 0x08, 0x08, 0x3E, 0x1C, 0x08, 0x00, /* */
+ 0x08, 0x1C, 0x3E, 0x08, 0x08, 0x00, /* */
+ 0x1C, 0x10, 0x10, 0x10, 0x10, 0x00, /* */
+ 0x08, 0x1C, 0x08, 0x1C, 0x08, 0x00, /* */
+ 0x18, 0x1C, 0x1E, 0x1C, 0x18, 0x00, /* */
+ 0x0C, 0x1C, 0x3C, 0x1C, 0x0C, 0x00, /* */
+/* 0x20 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
+ 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, /* ! */
+ 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, /* " */
+ 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, /* # */
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, /* $ */
+ 0x63, 0x13, 0x08, 0x64, 0x63, 0x00, /* % */
+ 0x36, 0x49, 0x55, 0x22, 0x50, 0x00, /* & */
+ 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, /* ' */
+/* 0x28 */
+ 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, /* ( */
+ 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, /* ) */
+ 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00, /* * */
+ 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, /* + */
+ 0x00, 0x50, 0x30, 0x00, 0x00, 0x00, /* , */
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /* - */
+ 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, /* . */
+ 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, /* / */
+/* 0x30 */
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, /* 0 */
+ 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, /* 1 */
+ 0x62, 0x51, 0x49, 0x49, 0x46, 0x00, /* 2 */
+ 0x21, 0x41, 0x45, 0x4B, 0x31, 0x00, /* 3 */
+ 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, /* 4 */
+ 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, /* 5 */
+ 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00, /* 6 */
+ 0x01, 0x71, 0x09, 0x05, 0x03, 0x00, /* 7 */
+/* 0x38 */
+ 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, /* 8 */
+ 0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, /* 9 */
+ 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, /* : */
+ 0x00, 0x56, 0x36, 0x00, 0x00, 0x00, /* ; */
+ 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, /* < */
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, /* = */
+ 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, /* > */
+ 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, /* ? */
+/* 0x40 */
+ 0x32, 0x49, 0x79, 0x41, 0x3E, 0x00, /* @ */
+ 0x7E, 0x09, 0x09, 0x09, 0x7E, 0x00, /* A */
+ 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, /* B */
+ 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, /* C */
+ 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00, /* D */
+ 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, /* E */
+ 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, /* F */
+ 0x3E, 0x41, 0x49, 0x49, 0x7A, 0x00, /* G */
+/* 0x48 */
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, /* H */
+ 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, /* I */
+ 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, /* J */
+ 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, /* K */
+ 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, /* L */
+ 0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x00, /* M */
+ 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, /* N */
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, /* O */
+/* 0x50 */
+ 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, /* P */
+ 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, /* Q */
+ 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, /* R */
+ 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, /* S */
+ 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, /* T */
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, /* U */
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, /* V */
+ 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, /* W */
+/* 0x58 */
+ 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, /* X */
+ 0x07, 0x08, 0x70, 0x08, 0x07, 0x00, /* Y */
+ 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, /* Z */
+ 0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, /* [ */
+ 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, /* \ */
+ 0x00, 0x41, 0x41, 0x7F, 0x00, 0x00, /* ] */
+ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, /* ^ */
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, /* _ */
+/* 0x60 */
+ 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, /* ` */
+ 0x00, 0x74, 0x54, 0x54, 0x78, 0x00, /* a */
+ 0x7F, 0x44, 0x44, 0x44, 0x38, 0x00, /* b */
+ 0x38, 0x44, 0x44, 0x44, 0x28, 0x00, /* c */
+ 0x38, 0x44, 0x44, 0x44, 0x7F, 0x00, /* d */
+ 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, /* e */
+ 0x08, 0x7E, 0x09, 0x01, 0x02, 0x00, /* f */
+ 0x08, 0x54, 0x54, 0x54, 0x3C, 0x00, /* g */
+/* 0x68 */
+ 0x7F, 0x04, 0x04, 0x04, 0x78, 0x00, /* h */
+ 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, /* i */
+ 0x20, 0x40, 0x44, 0x3D, 0x00, 0x00, /* j */
+ 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, /* k */
+ 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, /* l */
+ 0x7C, 0x04, 0x18, 0x04, 0x78, 0x00, /* m */
+ 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, /* n */
+ 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, /* o */
+/* 0x70 */
+ 0x7C, 0x14, 0x14, 0x14, 0x08, 0x00, /* p */
+ 0x08, 0x14, 0x14, 0x14, 0x7C, 0x00, /* q */
+ 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, /* r */
+ 0x48, 0x54, 0x54, 0x54, 0x24, 0x00, /* s */
+ 0x04, 0x3F, 0x44, 0x40, 0x20, 0x00, /* t */
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, /* u */
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, /* v */
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, /* w */
+/* 0x78 */
+ 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, /* x */
+ 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00, /* y */
+ 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, /* z */
+ 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, /* { */
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, /* | */
+ 0x00, 0x41, 0x36, 0x08, 0x00, 0x00, /* } */
+ 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, /* ~ */
+ 0x70, 0x48, 0x44, 0x48, 0x70, 0x00, /* \7f */
+/* 0x80 */
+ 0x38, 0xC4, 0xC4, 0x44, 0x28, 0x00, /* \80 */
+ 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x00, /* \81 */
+ 0x38, 0x54, 0x54, 0x55, 0x19, 0x00, /* \82 */
+ 0x22, 0x55, 0x55, 0x55, 0x78, 0x00, /* \83 */
+ 0x20, 0x55, 0x54, 0x54, 0x79, 0x00, /* \84 */
+ 0x21, 0x75, 0x55, 0x54, 0x78, 0x00, /* \85 */
+ 0x20, 0x74, 0x57, 0x54, 0x78, 0x00, /* \86 */
+ 0x08, 0x54, 0x54, 0x74, 0x14, 0x00, /* \87 */
+/* 0x88 */
+ 0x3A, 0x55, 0x55, 0x55, 0x1A, 0x00, /* \88 */
+ 0x39, 0x54, 0x54, 0x55, 0x18, 0x00, /* \89 */
+ 0x39, 0x55, 0x55, 0x54, 0x18, 0x00, /* \8a */
+ 0x00, 0x45, 0x7C, 0x41, 0x00, 0x00, /* \8b */
+ 0x02, 0x45, 0x7D, 0x42, 0x00, 0x00, /* \8c */
+ 0x01, 0x45, 0x7D, 0x40, 0x00, 0x00, /* \8d */
+ 0x79, 0x14, 0x12, 0x14, 0x79, 0x00, /* \8e */
+ 0x70, 0x2B, 0x2B, 0x2B, 0x70, 0x00, /* \8f */
+/* 0x90 */
+ 0x7C, 0x54, 0x55, 0x55, 0x45, 0x00, /* \90 */
+ 0x20, 0x54, 0x38, 0x54, 0x48, 0x00, /* \91 */
+ 0x7E, 0x09, 0x7F, 0x49, 0x49, 0x00, /* \92 */
+ 0x32, 0x49, 0x49, 0x49, 0x32, 0x00, /* \93 */
+ 0x32, 0x48, 0x48, 0x48, 0x32, 0x00, /* \94 */
+ 0x32, 0x4A, 0x4A, 0x48, 0x30, 0x00, /* \95 */
+ 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x00, /* \96 */
+ 0x3A, 0x42, 0x42, 0x20, 0x78, 0x00, /* \97 */
+/* 0x98 */
+ 0x0D, 0x50, 0x50, 0x50, 0x3D, 0x00, /* \98 */
+ 0x19, 0x24, 0x42, 0x24, 0x19, 0x00, /* \99 */
+ 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x00, /* \9a */
+ 0x18, 0x24, 0x7E, 0x24, 0x24, 0x00, /* \9b */
+ 0x28, 0x5E, 0x29, 0x42, 0x20, 0x00, /* \9c */
+ 0x09, 0x2A, 0x7C, 0x2A, 0x09, 0x00, /* \9d */
+ 0x7F, 0x05, 0x15, 0x3D, 0x52, 0x00, /* \9e */
+ 0x20, 0x48, 0x3E, 0x09, 0x02, 0x00, /* \9f */
+/* 0xa0 */
+ 0x20, 0x74, 0x55, 0x55, 0x79, 0x00, /* */
+ 0x01, 0x45, 0x7D, 0x40, 0x00, 0x00, /* ¡ */
+ 0x30, 0x48, 0x4A, 0x4A, 0x32, 0x00, /* ¢ */
+ 0x38, 0x40, 0x42, 0x22, 0x7A, 0x00, /* £ */
+ 0x7A, 0x12, 0x0A, 0x0A, 0x72, 0x00, /* ¤ */
+ 0x7D, 0x09, 0x11, 0x21, 0x7D, 0x00, /* ¥ */
+ 0x02, 0x15, 0x15, 0x12, 0x04, 0x00, /* ¦ */
+ 0x02, 0x15, 0x15, 0x15, 0x02, 0x00, /* § */
+/* 0xa8 */
+ 0x30, 0x48, 0x45, 0x40, 0x20, 0x00, /* ¨ */
+ 0x00, 0x38, 0x08, 0x08, 0x08, 0x00, /* © */
+ 0x00, 0x08, 0x08, 0x08, 0x38, 0x00, /* ª */
+ 0x0B, 0x04, 0x6A, 0x55, 0x48, 0x00, /* « */
+ 0x0B, 0x24, 0x32, 0x79, 0x20, 0x00, /* ¬ */
+ 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, /* */
+ 0x08, 0x14, 0x2A, 0x14, 0x22, 0x00, /* ® */
+ 0x22, 0x14, 0x2A, 0x14, 0x08, 0x00, /* ¯ */
+/* 0xb0 */
+ 0x2A, 0x55, 0x00, 0x2A, 0x55, 0x00, /* ° */
+ 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, /* ± */
+ 0x55, 0x2A, 0x7F, 0x55, 0x2A, 0x7F, /* ² */
+ 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, /* ³ */
+ 0x08, 0x08, 0xFF, 0x00, 0x00, 0x00, /* ´ */
+ 0x14, 0x14, 0xFF, 0x00, 0x00, 0x00, /* µ */
+ 0x08, 0xFF, 0x00, 0xFF, 0x00, 0x00, /* ¶ */
+ 0x08, 0xF8, 0x08, 0xF8, 0x00, 0x00, /* · */
+/* 0xb8 */
+ 0x14, 0x14, 0xFC, 0x00, 0x00, 0x00, /* ¸ */
+ 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, /* ¹ */
+ 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, /* º */
+ 0x14, 0xF4, 0x04, 0xFC, 0x00, 0x00, /* » */
+ 0x14, 0x17, 0x10, 0x1F, 0x00, 0x00, /* ¼ */
+ 0x08, 0x0F, 0x08, 0x0F, 0x00, 0x00, /* ½ */
+ 0x14, 0x14, 0x1F, 0x00, 0x00, 0x00, /* ¾ */
+ 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, /* ¿ */
+/* 0xc0 */
+ 0x00, 0x00, 0x0F, 0x08, 0x08, 0x08, /* À */
+ 0x08, 0x08, 0x0F, 0x08, 0x08, 0x08, /* Á */
+ 0x08, 0x08, 0xF8, 0x08, 0x08, 0x08, /* Â */
+ 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, /* Ã */
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* Ä */
+ 0x08, 0x08, 0xFF, 0x08, 0x08, 0x08, /* Å */
+ 0x00, 0x00, 0xFF, 0x14, 0x14, 0x14, /* Æ */
+ 0x00, 0xFF, 0x00, 0xFF, 0x08, 0x08, /* Ç */
+/* 0xc8 */
+ 0x00, 0x1F, 0x10, 0x17, 0x14, 0x14, /* È */
+ 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, /* É */
+ 0x28, 0x2F, 0x20, 0x2F, 0x28, 0x28, /* Ê */
+ 0x14, 0xF4, 0x04, 0xF4, 0x14, 0x14, /* Ë */
+ 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, /* Ì */
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, /* Í */
+ 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, /* Î */
+ 0x14, 0x14, 0xF7, 0x14, 0x14, 0x14, /* Ï */
+/* 0xd0 */
+ 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08, /* Ð */
+ 0x14, 0x14, 0xF4, 0x14, 0x14, 0x14, /* Ñ */
+ 0x08, 0x08, 0xF8, 0x08, 0x08, 0x08, /* Ò */
+ 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08, /* Ó */
+ 0x00, 0x00, 0x1F, 0x14, 0x14, 0x14, /* Ô */
+ 0x00, 0x00, 0xFC, 0x14, 0x14, 0x14, /* Õ */
+ 0x00, 0xF8, 0x08, 0xF8, 0x08, 0x08, /* Ö */
+ 0x08, 0xFF, 0x08, 0xFF, 0x08, 0x08, /* × */
+/* 0xd8 */
+ 0x14, 0x14, 0xFF, 0x14, 0x14, 0x14, /* Ø */
+ 0x08, 0x08, 0x0F, 0x00, 0x00, 0x00, /* Ù */
+ 0x00, 0x00, 0xF8, 0x08, 0x08, 0x08, /* Ú */
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, /* Û */
+ 0x70, 0x70, 0x70, 0x70, 0x70, 0x00, /* Ü */
+ 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, /* Ý */
+ 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x00, /* Þ */
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, /* ß */
+/* 0xe0 */
+ 0x30, 0x48, 0x48, 0x30, 0x48, 0x00, /* à */
+ 0x7E, 0x11, 0x25, 0x25, 0x1A, 0x00, /* á */
+ 0x7E, 0x02, 0x02, 0x02, 0x06, 0x00, /* â */
+ 0x04, 0x7C, 0x04, 0x7C, 0x04, 0x00, /* ã */
+ 0x41, 0x63, 0x55, 0x49, 0x63, 0x00, /* ä */
+ 0x3C, 0x42, 0x4A, 0x4A, 0x31, 0x00, /* å */
+ 0x40, 0x7C, 0x20, 0x20, 0x1C, 0x00, /* æ */
+ 0x08, 0x04, 0x7C, 0x08, 0x04, 0x00, /* ç */
+/* 0xe8 */
+ 0x49, 0x55, 0x77, 0x55, 0x49, 0x00, /* è */
+ 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x00, /* é */
+ 0x4C, 0x72, 0x02, 0x72, 0x4C, 0x00, /* ê */
+ 0x30, 0x4A, 0x45, 0x49, 0x31, 0x00, /* ë */
+ 0x18, 0x24, 0x18, 0x24, 0x18, 0x00, /* ì */
+ 0x5C, 0x72, 0x2A, 0x27, 0x1D, 0x00, /* í */
+ 0x1C, 0x2A, 0x49, 0x49, 0x00, 0x00, /* î */
+ 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x00, /* ï */
+/* 0xf0 */
+ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, /* ð */
+ 0x24, 0x24, 0x2E, 0x24, 0x24, 0x00, /* ñ */
+ 0x40, 0x51, 0x4A, 0x44, 0x00, 0x00, /* ò */
+ 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, /* ó */
+ 0x00, 0x00, 0xFE, 0x01, 0x02, 0x00, /* ô */
+ 0x20, 0x40, 0x3F, 0x00, 0x00, 0x00, /* õ */
+ 0x08, 0x08, 0x2A, 0x08, 0x08, 0x00, /* ö */
+ 0x24, 0x12, 0x24, 0x12, 0x00, 0x00, /* ÷ */
+/* 0xf8 */
+ 0x06, 0x09, 0x09, 0x09, 0x06, 0x00, /* ø */
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /* ù */
+ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, /* ú */
+ 0x10, 0x30, 0x7F, 0x01, 0x01, 0x00, /* û */
+ 0x01, 0x0E, 0x01, 0x01, 0x0E, 0x00, /* ü */
+ 0x0A, 0x09, 0x0D, 0x0A, 0x00, 0x00, /* ý */
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x00, /* þ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ÿ */
+};
+
+struct Font default_font =
+{
+ /* .glyph = */ default_font_glyphs,
+ /* .width = */ 6,
+ /* .height = */ 8
+};
+
--- /dev/null
+#
+# $Id$
+# Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+# All rights reserved.
+#
+# Makefile fragment for DevLib demo application.
+#
+# Author: Bernardo Innocenti <bernie@develer.com>
+#
+
+%.c: %.bdf
+ bertos/fonts/convbdf $< > $@
--- /dev/null
+STARTFONT 2.1
+FONT -Adobe-Helvetica-Bold-R-Normal--10-100-75-75-P-60-ISO8859-1
+SIZE 10 75 75
+FONTBOUNDINGBOX 11 13 -1 -2
+COMMENT $XConsortium: helvB10.bdf,v 1.13 95/01/26 18:01:30 gildea Exp $
+COMMENT
+COMMENT +
+COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated.
+COMMENT Copyright 1988, 1994 Digital Equipment Corporation.
+COMMENT
+COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be
+COMMENT registered in certain jurisdictions.
+COMMENT Permission to use these trademarks is hereby granted only in
+COMMENT association with the images described in this file.
+COMMENT
+COMMENT Permission to use, copy, modify, distribute and sell this software
+COMMENT and its documentation for any purpose and without fee is hereby
+COMMENT granted, provided that the above copyright notices appear in all
+COMMENT copies and that both those copyright notices and this permission
+COMMENT notice appear in supporting documentation, and that the names of
+COMMENT Adobe Systems and Digital Equipment Corporation not be used in
+COMMENT advertising or publicity pertaining to distribution of the software
+COMMENT without specific, written prior permission. Adobe Systems and
+COMMENT Digital Equipment Corporation make no representations about the
+COMMENT suitability of this software for any purpose. It is provided "as
+COMMENT is" without express or implied warranty.
+COMMENT -
+STARTPROPERTIES 28
+FOUNDRY "Adobe"
+FAMILY_NAME "Helvetica"
+WEIGHT_NAME "Bold"
+SLANT "R"
+SETWIDTH_NAME "Normal"
+ADD_STYLE_NAME ""
+PIXEL_SIZE 10
+POINT_SIZE 100
+RESOLUTION_X 75
+RESOLUTION_Y 75
+SPACING "P"
+AVERAGE_WIDTH 60
+CHARSET_REGISTRY "ISO8859"
+CHARSET_ENCODING "1"
+CAP_HEIGHT 8
+X_HEIGHT 6
+FONT_ASCENT 10
+FONT_DESCENT 2
+FACE_NAME "Helvetica Bold"
+COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
+NOTICE "Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. "
+_DEC_DEVICE_FONTNAMES "PS=Helvetica-Bold"
+_DEC_PRODUCTINFO "DECwindows Fonts V2.2, 07-Nov-1991"
+DEFAULT_CHAR 32
+RELATIVE_SETWIDTH 50
+RELATIVE_WEIGHT 70
+CHARSET_COLLECTIONS "ASCII ISO8859-1 ADOBE-STANDARD"
+FULL_NAME "Helvetica Bold"
+ENDPROPERTIES
+CHARS 229
+STARTCHAR space
+ENCODING 32
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclam
+ENCODING 33
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 2 8 1 0
+BITMAP
+C0
+C0
+C0
+C0
+80
+80
+00
+C0
+ENDCHAR
+STARTCHAR quotedbl
+ENCODING 34
+SWIDTH 474 0
+DWIDTH 5 0
+BBX 3 3 1 5
+BITMAP
+A0
+A0
+A0
+ENDCHAR
+STARTCHAR numbersign
+ENCODING 35
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 7 0 0
+BITMAP
+50
+50
+FC
+50
+F8
+A0
+A0
+ENDCHAR
+STARTCHAR dollar
+ENCODING 36
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 -1
+BITMAP
+20
+70
+A8
+E0
+70
+38
+A8
+70
+20
+ENDCHAR
+STARTCHAR percent
+ENCODING 37
+SWIDTH 889 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+62
+B4
+68
+10
+10
+2C
+56
+8C
+ENDCHAR
+STARTCHAR ampersand
+ENCODING 38
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+70
+D8
+D8
+70
+DE
+CC
+DC
+76
+ENDCHAR
+STARTCHAR quoteright
+ENCODING 39
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 3 0 5
+BITMAP
+C0
+40
+80
+ENDCHAR
+STARTCHAR parenleft
+ENCODING 40
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 10 0 -2
+BITMAP
+20
+60
+40
+C0
+C0
+C0
+C0
+40
+60
+20
+ENDCHAR
+STARTCHAR parenright
+ENCODING 41
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 10 0 -2
+BITMAP
+80
+C0
+40
+60
+60
+60
+60
+40
+C0
+80
+ENDCHAR
+STARTCHAR asterisk
+ENCODING 42
+SWIDTH 389 0
+DWIDTH 4 0
+BBX 3 3 0 5
+BITMAP
+A0
+40
+A0
+ENDCHAR
+STARTCHAR plus
+ENCODING 43
+SWIDTH 584 0
+DWIDTH 6 0
+BBX 6 5 0 1
+BITMAP
+30
+30
+FC
+30
+30
+ENDCHAR
+STARTCHAR comma
+ENCODING 44
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 4 0 -2
+BITMAP
+40
+40
+40
+80
+ENDCHAR
+STARTCHAR minus
+ENCODING 45
+SWIDTH 584 0
+DWIDTH 7 0
+BBX 5 1 1 3
+BITMAP
+F8
+ENDCHAR
+STARTCHAR period
+ENCODING 46
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 1 2 1 0
+BITMAP
+80
+80
+ENDCHAR
+STARTCHAR slash
+ENCODING 47
+SWIDTH 278 0
+DWIDTH 4 0
+BBX 4 8 0 0
+BITMAP
+10
+10
+20
+20
+40
+40
+80
+80
+ENDCHAR
+STARTCHAR zero
+ENCODING 48
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+D8
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR one
+ENCODING 49
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 4 8 0 0
+BITMAP
+30
+F0
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR two
+ENCODING 50
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+18
+18
+30
+60
+C0
+F8
+ENDCHAR
+STARTCHAR three
+ENCODING 51
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+18
+30
+18
+18
+D8
+70
+ENDCHAR
+STARTCHAR four
+ENCODING 52
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 8 0 0
+BITMAP
+18
+38
+58
+58
+98
+FC
+18
+18
+ENDCHAR
+STARTCHAR five
+ENCODING 53
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+F8
+C0
+C0
+F0
+18
+98
+D8
+70
+ENDCHAR
+STARTCHAR six
+ENCODING 54
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+C0
+F0
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR seven
+ENCODING 55
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+F8
+18
+18
+30
+30
+30
+60
+60
+ENDCHAR
+STARTCHAR eight
+ENCODING 56
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+D8
+70
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR nine
+ENCODING 57
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+D8
+D8
+78
+18
+D8
+70
+ENDCHAR
+STARTCHAR colon
+ENCODING 58
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 1 6 1 0
+BITMAP
+80
+80
+00
+00
+80
+80
+ENDCHAR
+STARTCHAR semicolon
+ENCODING 59
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 2 8 0 -2
+BITMAP
+40
+40
+00
+00
+40
+40
+40
+80
+ENDCHAR
+STARTCHAR less
+ENCODING 60
+SWIDTH 584 0
+DWIDTH 5 0
+BBX 4 5 0 1
+BITMAP
+30
+60
+C0
+60
+30
+ENDCHAR
+STARTCHAR equal
+ENCODING 61
+SWIDTH 584 0
+DWIDTH 6 0
+BBX 5 3 0 2
+BITMAP
+F8
+00
+F8
+ENDCHAR
+STARTCHAR greater
+ENCODING 62
+SWIDTH 584 0
+DWIDTH 5 0
+BBX 4 5 0 1
+BITMAP
+C0
+60
+30
+60
+C0
+ENDCHAR
+STARTCHAR question
+ENCODING 63
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+D8
+18
+30
+60
+60
+00
+60
+ENDCHAR
+STARTCHAR at
+ENCODING 64
+SWIDTH 975 0
+DWIDTH 11 0
+BBX 10 9 0 -2
+BITMAP
+1F00
+6080
+4D40
+9240
+A240
+A480
+9B00
+4000
+3E00
+ENDCHAR
+STARTCHAR A
+ENCODING 65
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR B
+ENCODING 66
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+F8
+CC
+CC
+F8
+CC
+CC
+CC
+F8
+ENDCHAR
+STARTCHAR C
+ENCODING 67
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+3C
+66
+C2
+C0
+C0
+C2
+66
+3C
+ENDCHAR
+STARTCHAR D
+ENCODING 68
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+F0
+D8
+CC
+CC
+CC
+CC
+D8
+F0
+ENDCHAR
+STARTCHAR E
+ENCODING 69
+SWIDTH 667 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+F8
+C0
+C0
+F8
+C0
+C0
+C0
+F8
+ENDCHAR
+STARTCHAR F
+ENCODING 70
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+F8
+C0
+C0
+F0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR G
+ENCODING 71
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+3C
+66
+C2
+C0
+CE
+C6
+66
+3A
+ENDCHAR
+STARTCHAR H
+ENCODING 72
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+CC
+CC
+CC
+FC
+CC
+CC
+CC
+CC
+ENDCHAR
+STARTCHAR I
+ENCODING 73
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 8 0 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR J
+ENCODING 74
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+18
+18
+18
+18
+18
+18
+D8
+70
+ENDCHAR
+STARTCHAR K
+ENCODING 75
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 7 8 0 0
+BITMAP
+CC
+D8
+F0
+E0
+F0
+D8
+CC
+C6
+ENDCHAR
+STARTCHAR L
+ENCODING 76
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+F8
+ENDCHAR
+STARTCHAR M
+ENCODING 77
+SWIDTH 833 0
+DWIDTH 10 0
+BBX 9 8 0 0
+BITMAP
+C180
+E380
+E380
+F780
+D580
+DD80
+C980
+C980
+ENDCHAR
+STARTCHAR N
+ENCODING 78
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+C6
+E6
+E6
+D6
+D6
+CE
+CE
+C6
+ENDCHAR
+STARTCHAR O
+ENCODING 79
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+38
+6C
+C6
+C6
+C6
+C6
+6C
+38
+ENDCHAR
+STARTCHAR P
+ENCODING 80
+SWIDTH 667 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+F8
+CC
+CC
+CC
+F8
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Q
+ENCODING 81
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 9 0 -1
+BITMAP
+38
+6C
+C6
+C6
+C6
+D6
+6C
+3C
+02
+ENDCHAR
+STARTCHAR R
+ENCODING 82
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+F8
+CC
+CC
+CC
+F8
+CC
+CC
+CC
+ENDCHAR
+STARTCHAR S
+ENCODING 83
+SWIDTH 667 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+78
+CC
+E0
+78
+1C
+8C
+CC
+78
+ENDCHAR
+STARTCHAR T
+ENCODING 84
+SWIDTH 611 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+FC
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR U
+ENCODING 85
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+CC
+CC
+CC
+CC
+CC
+CC
+CC
+78
+ENDCHAR
+STARTCHAR V
+ENCODING 86
+SWIDTH 667 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+C6
+C6
+6C
+6C
+6C
+38
+38
+10
+ENDCHAR
+STARTCHAR W
+ENCODING 87
+SWIDTH 944 0
+DWIDTH 11 0
+BBX 10 8 0 0
+BITMAP
+CCC0
+CCC0
+CCC0
+6D80
+6D80
+7F80
+3300
+2100
+ENDCHAR
+STARTCHAR X
+ENCODING 88
+SWIDTH 667 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+C6
+C6
+6C
+38
+38
+6C
+C6
+C6
+ENDCHAR
+STARTCHAR Y
+ENCODING 89
+SWIDTH 667 0
+DWIDTH 9 0
+BBX 8 8 0 0
+BITMAP
+C3
+C3
+66
+66
+3C
+18
+18
+18
+ENDCHAR
+STARTCHAR Z
+ENCODING 90
+SWIDTH 611 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+FC
+0C
+18
+30
+70
+60
+C0
+FC
+ENDCHAR
+STARTCHAR bracketleft
+ENCODING 91
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 10 0 -2
+BITMAP
+E0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+E0
+ENDCHAR
+STARTCHAR backslash
+ENCODING 92
+SWIDTH 278 0
+DWIDTH 4 0
+BBX 4 8 0 0
+BITMAP
+80
+80
+40
+40
+20
+20
+10
+10
+ENDCHAR
+STARTCHAR bracketright
+ENCODING 93
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 10 0 -2
+BITMAP
+E0
+60
+60
+60
+60
+60
+60
+60
+60
+E0
+ENDCHAR
+STARTCHAR asciicircum
+ENCODING 94
+SWIDTH 584 0
+DWIDTH 5 0
+BBX 5 4 0 4
+BITMAP
+20
+70
+D8
+88
+ENDCHAR
+STARTCHAR underscore
+ENCODING 95
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 1 0 -2
+BITMAP
+FC
+ENDCHAR
+STARTCHAR quoteleft
+ENCODING 96
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 3 0 5
+BITMAP
+40
+80
+C0
+ENDCHAR
+STARTCHAR a
+ENCODING 97
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 6 0 0
+BITMAP
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR b
+ENCODING 98
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+C0
+C0
+F0
+D8
+C8
+C8
+D8
+F0
+ENDCHAR
+STARTCHAR c
+ENCODING 99
+SWIDTH 556 0
+DWIDTH 5 0
+BBX 4 6 0 0
+BITMAP
+70
+D0
+C0
+C0
+D0
+70
+ENDCHAR
+STARTCHAR d
+ENCODING 100
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+18
+18
+78
+D8
+98
+98
+D8
+78
+ENDCHAR
+STARTCHAR e
+ENCODING 101
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+70
+D8
+F8
+C0
+D8
+70
+ENDCHAR
+STARTCHAR f
+ENCODING 102
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 4 8 0 0
+BITMAP
+70
+C0
+E0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR g
+ENCODING 103
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 -2
+BITMAP
+68
+D8
+98
+98
+D8
+78
+18
+70
+ENDCHAR
+STARTCHAR h
+ENCODING 104
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+C0
+C0
+F0
+D8
+D8
+D8
+D8
+D8
+ENDCHAR
+STARTCHAR i
+ENCODING 105
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 8 0 0
+BITMAP
+C0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR j
+ENCODING 106
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 10 0 -2
+BITMAP
+C0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+80
+ENDCHAR
+STARTCHAR k
+ENCODING 107
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 8 0 0
+BITMAP
+C0
+C0
+D8
+F0
+E0
+F0
+D8
+CC
+ENDCHAR
+STARTCHAR l
+ENCODING 108
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 8 0 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR m
+ENCODING 109
+SWIDTH 889 0
+DWIDTH 9 0
+BBX 8 6 0 0
+BITMAP
+B6
+DB
+DB
+DB
+DB
+DB
+ENDCHAR
+STARTCHAR n
+ENCODING 110
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+B0
+D8
+D8
+D8
+D8
+D8
+ENDCHAR
+STARTCHAR o
+ENCODING 111
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR p
+ENCODING 112
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 -2
+BITMAP
+B0
+D8
+C8
+C8
+D8
+F0
+C0
+C0
+ENDCHAR
+STARTCHAR q
+ENCODING 113
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 -2
+BITMAP
+68
+D8
+98
+98
+D8
+78
+18
+18
+ENDCHAR
+STARTCHAR r
+ENCODING 114
+SWIDTH 389 0
+DWIDTH 4 0
+BBX 4 6 0 0
+BITMAP
+B0
+E0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR s
+ENCODING 115
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+70
+D8
+70
+18
+D8
+70
+ENDCHAR
+STARTCHAR t
+ENCODING 116
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 8 0 0
+BITMAP
+C0
+C0
+E0
+C0
+C0
+C0
+C0
+60
+ENDCHAR
+STARTCHAR u
+ENCODING 117
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+D8
+D8
+D8
+D8
+D8
+68
+ENDCHAR
+STARTCHAR v
+ENCODING 118
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+D8
+D8
+D8
+50
+70
+20
+ENDCHAR
+STARTCHAR w
+ENCODING 119
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 6 0 0
+BITMAP
+D6
+D6
+D6
+6C
+6C
+6C
+ENDCHAR
+STARTCHAR x
+ENCODING 120
+SWIDTH 556 0
+DWIDTH 7 0
+BBX 6 6 0 0
+BITMAP
+CC
+78
+30
+78
+CC
+CC
+ENDCHAR
+STARTCHAR y
+ENCODING 121
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 -2
+BITMAP
+D8
+D8
+D8
+D8
+78
+30
+30
+60
+ENDCHAR
+STARTCHAR z
+ENCODING 122
+SWIDTH 500 0
+DWIDTH 6 0
+BBX 5 6 0 0
+BITMAP
+F8
+18
+30
+60
+C0
+F8
+ENDCHAR
+STARTCHAR braceleft
+ENCODING 123
+SWIDTH 389 0
+DWIDTH 5 0
+BBX 4 10 0 -2
+BITMAP
+30
+60
+60
+60
+C0
+60
+60
+60
+60
+30
+ENDCHAR
+STARTCHAR bar
+ENCODING 124
+SWIDTH 280 0
+DWIDTH 3 0
+BBX 1 10 1 -2
+BITMAP
+80
+80
+80
+80
+80
+80
+80
+80
+80
+80
+ENDCHAR
+STARTCHAR braceright
+ENCODING 125
+SWIDTH 389 0
+DWIDTH 5 0
+BBX 4 10 0 -2
+BITMAP
+C0
+60
+60
+60
+30
+60
+60
+60
+60
+C0
+ENDCHAR
+STARTCHAR asciitilde
+ENCODING 126
+SWIDTH 584 0
+DWIDTH 6 0
+BBX 6 2 0 2
+BITMAP
+6C
+D8
+ENDCHAR
+STARTCHAR space
+ENCODING 160
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclamdown
+ENCODING 161
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 2 8 1 -2
+BITMAP
+C0
+00
+40
+40
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR cent
+ENCODING 162
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 -1
+BITMAP
+10
+70
+D8
+A0
+A0
+D8
+70
+40
+ENDCHAR
+STARTCHAR sterling
+ENCODING 163
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+38
+68
+60
+F0
+60
+60
+68
+D8
+ENDCHAR
+STARTCHAR currency
+ENCODING 164
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 6 0 1
+BITMAP
+D8
+70
+D8
+D8
+70
+D8
+ENDCHAR
+STARTCHAR yen
+ENCODING 165
+SWIDTH 556 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+84
+CC
+48
+78
+FC
+30
+FC
+30
+ENDCHAR
+STARTCHAR brokenbar
+ENCODING 166
+SWIDTH 280 0
+DWIDTH 3 0
+BBX 1 10 1 -2
+BITMAP
+80
+80
+80
+80
+00
+00
+80
+80
+80
+80
+ENDCHAR
+STARTCHAR section
+ENCODING 167
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 10 0 -2
+BITMAP
+70
+C8
+E0
+70
+98
+C8
+70
+38
+98
+70
+ENDCHAR
+STARTCHAR dieresis
+ENCODING 168
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 3 1 0 7
+BITMAP
+A0
+ENDCHAR
+STARTCHAR copyright
+ENCODING 169
+SWIDTH 737 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+3C
+42
+99
+A5
+A1
+9D
+42
+3C
+ENDCHAR
+STARTCHAR ordfeminine
+ENCODING 170
+SWIDTH 370 0
+DWIDTH 5 0
+BBX 3 5 1 3
+BITMAP
+E0
+20
+A0
+00
+E0
+ENDCHAR
+STARTCHAR guillemotleft
+ENCODING 171
+SWIDTH 556 0
+DWIDTH 7 0
+BBX 6 3 0 1
+BITMAP
+6C
+D8
+6C
+ENDCHAR
+STARTCHAR logicalnot
+ENCODING 172
+SWIDTH 584 0
+DWIDTH 7 0
+BBX 5 3 1 2
+BITMAP
+F8
+08
+08
+ENDCHAR
+STARTCHAR hyphen
+ENCODING 173
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 4 1 0 3
+BITMAP
+F0
+ENDCHAR
+STARTCHAR registered
+ENCODING 174
+SWIDTH 737 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+3C
+42
+BD
+A5
+B9
+A5
+42
+3C
+ENDCHAR
+STARTCHAR macron
+ENCODING 175
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 3 1 0 7
+BITMAP
+E0
+ENDCHAR
+STARTCHAR degree
+ENCODING 176
+SWIDTH 400 0
+DWIDTH 4 0
+BBX 3 3 1 4
+BITMAP
+60
+A0
+C0
+ENDCHAR
+STARTCHAR plusminus
+ENCODING 177
+SWIDTH 584 0
+DWIDTH 6 0
+BBX 6 7 0 0
+BITMAP
+30
+30
+FC
+30
+30
+00
+FC
+ENDCHAR
+STARTCHAR twosuperior
+ENCODING 178
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 3 4 0 3
+BITMAP
+60
+A0
+40
+E0
+ENDCHAR
+STARTCHAR threesuperior
+ENCODING 179
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 3 4 0 3
+BITMAP
+E0
+40
+20
+C0
+ENDCHAR
+STARTCHAR acute
+ENCODING 180
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 2 2 0 7
+BITMAP
+40
+80
+ENDCHAR
+STARTCHAR mu
+ENCODING 181
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 -2
+BITMAP
+D8
+D8
+D8
+D8
+D8
+E8
+C0
+C0
+ENDCHAR
+STARTCHAR paragraph
+ENCODING 182
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 10 0 -2
+BITMAP
+7C
+E8
+E8
+E8
+68
+28
+28
+28
+28
+28
+ENDCHAR
+STARTCHAR periodcentered
+ENCODING 183
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 1 0 3
+BITMAP
+C0
+ENDCHAR
+STARTCHAR cedilla
+ENCODING 184
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 2 2 0 -2
+BITMAP
+40
+C0
+ENDCHAR
+STARTCHAR onesuperior
+ENCODING 185
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 2 4 0 3
+BITMAP
+40
+C0
+40
+40
+ENDCHAR
+STARTCHAR ordmasculine
+ENCODING 186
+SWIDTH 365 0
+DWIDTH 5 0
+BBX 3 5 1 3
+BITMAP
+E0
+A0
+E0
+00
+E0
+ENDCHAR
+STARTCHAR guillemotright
+ENCODING 187
+SWIDTH 556 0
+DWIDTH 7 0
+BBX 6 3 0 1
+BITMAP
+D8
+6C
+D8
+ENDCHAR
+STARTCHAR onequarter
+ENCODING 188
+SWIDTH 834 0
+DWIDTH 9 0
+BBX 8 8 0 0
+BITMAP
+42
+C4
+48
+48
+12
+26
+2F
+42
+ENDCHAR
+STARTCHAR onehalf
+ENCODING 189
+SWIDTH 834 0
+DWIDTH 9 0
+BBX 7 8 0 0
+BITMAP
+42
+C4
+48
+48
+16
+2A
+24
+4E
+ENDCHAR
+STARTCHAR threequarters
+ENCODING 190
+SWIDTH 834 0
+DWIDTH 9 0
+BBX 8 8 0 0
+BITMAP
+E2
+44
+28
+C8
+12
+26
+2F
+42
+ENDCHAR
+STARTCHAR questiondown
+ENCODING 191
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 -2
+BITMAP
+30
+00
+30
+30
+60
+C0
+D8
+70
+ENDCHAR
+STARTCHAR Agrave
+ENCODING 192
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+20
+10
+00
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR Aacute
+ENCODING 193
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+08
+10
+00
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR Acircumflex
+ENCODING 194
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+10
+28
+00
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR Atilde
+ENCODING 195
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+14
+28
+00
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR Adieresis
+ENCODING 196
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 10 0 0
+BITMAP
+28
+00
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR Aring
+ENCODING 197
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+10
+28
+10
+38
+38
+6C
+6C
+6C
+FE
+C6
+C6
+ENDCHAR
+STARTCHAR AE
+ENCODING 198
+SWIDTH 1000 0
+DWIDTH 10 0
+BBX 9 8 0 0
+BITMAP
+3F80
+3C00
+6C00
+6F80
+6C00
+FC00
+CC00
+CF80
+ENDCHAR
+STARTCHAR Ccedilla
+ENCODING 199
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 10 0 -2
+BITMAP
+3C
+66
+C2
+C0
+C0
+C2
+66
+3C
+10
+30
+ENDCHAR
+STARTCHAR Egrave
+ENCODING 200
+SWIDTH 667 0
+DWIDTH 6 0
+BBX 5 11 0 0
+BITMAP
+40
+20
+00
+F8
+C0
+C0
+F8
+C0
+C0
+C0
+F8
+ENDCHAR
+STARTCHAR Eacute
+ENCODING 201
+SWIDTH 667 0
+DWIDTH 6 0
+BBX 5 11 0 0
+BITMAP
+10
+20
+00
+F8
+C0
+C0
+F8
+C0
+C0
+C0
+F8
+ENDCHAR
+STARTCHAR Ecircumflex
+ENCODING 202
+SWIDTH 667 0
+DWIDTH 6 0
+BBX 5 11 0 0
+BITMAP
+20
+50
+00
+F8
+C0
+C0
+F8
+C0
+C0
+C0
+F8
+ENDCHAR
+STARTCHAR Edieresis
+ENCODING 203
+SWIDTH 667 0
+DWIDTH 6 0
+BBX 5 10 0 0
+BITMAP
+50
+00
+F8
+C0
+C0
+F8
+C0
+C0
+C0
+F8
+ENDCHAR
+STARTCHAR Igrave
+ENCODING 204
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 11 0 0
+BITMAP
+80
+40
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Iacute
+ENCODING 205
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 11 0 0
+BITMAP
+40
+80
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Icircumflex
+ENCODING 206
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 3 11 0 0
+BITMAP
+40
+A0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Idieresis
+ENCODING 207
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 3 10 0 0
+BITMAP
+A0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Eth
+ENCODING 208
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+F0
+D8
+CC
+EC
+CC
+CC
+D8
+F0
+ENDCHAR
+STARTCHAR Ntilde
+ENCODING 209
+SWIDTH 722 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+14
+28
+00
+C6
+C6
+E6
+D6
+D6
+CE
+CE
+C6
+ENDCHAR
+STARTCHAR Ograve
+ENCODING 210
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+20
+10
+00
+38
+6C
+C6
+C6
+C6
+C6
+6C
+38
+ENDCHAR
+STARTCHAR Oacute
+ENCODING 211
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+04
+08
+00
+38
+6C
+C6
+C6
+C6
+C6
+6C
+38
+ENDCHAR
+STARTCHAR Ocircumflex
+ENCODING 212
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+10
+28
+00
+38
+6C
+C6
+C6
+C6
+C6
+6C
+38
+ENDCHAR
+STARTCHAR Otilde
+ENCODING 213
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 11 0 0
+BITMAP
+14
+28
+00
+38
+6C
+C6
+C6
+C6
+C6
+6C
+38
+ENDCHAR
+STARTCHAR Odieresis
+ENCODING 214
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 10 0 0
+BITMAP
+28
+00
+38
+6C
+C6
+C6
+C6
+C6
+6C
+38
+ENDCHAR
+STARTCHAR multiply
+ENCODING 215
+SWIDTH 584 0
+DWIDTH 6 0
+BBX 6 5 0 1
+BITMAP
+CC
+78
+30
+78
+CC
+ENDCHAR
+STARTCHAR Oslash
+ENCODING 216
+SWIDTH 778 0
+DWIDTH 8 0
+BBX 7 8 0 0
+BITMAP
+3A
+6C
+CE
+D6
+D6
+E6
+6C
+B8
+ENDCHAR
+STARTCHAR Ugrave
+ENCODING 217
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 11 0 0
+BITMAP
+20
+10
+00
+CC
+CC
+CC
+CC
+CC
+CC
+CC
+78
+ENDCHAR
+STARTCHAR Uacute
+ENCODING 218
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 11 0 0
+BITMAP
+08
+10
+00
+CC
+CC
+CC
+CC
+CC
+CC
+CC
+78
+ENDCHAR
+STARTCHAR Ucircumflex
+ENCODING 219
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 11 0 0
+BITMAP
+10
+28
+00
+CC
+CC
+CC
+CC
+CC
+CC
+CC
+78
+ENDCHAR
+STARTCHAR Udieresis
+ENCODING 220
+SWIDTH 722 0
+DWIDTH 7 0
+BBX 6 10 0 0
+BITMAP
+28
+00
+CC
+CC
+CC
+CC
+CC
+CC
+CC
+78
+ENDCHAR
+STARTCHAR Yacute
+ENCODING 221
+SWIDTH 667 0
+DWIDTH 9 0
+BBX 8 11 0 0
+BITMAP
+04
+08
+00
+C3
+C3
+66
+66
+3C
+18
+18
+18
+ENDCHAR
+STARTCHAR Thorn
+ENCODING 222
+SWIDTH 667 0
+DWIDTH 7 0
+BBX 6 8 0 0
+BITMAP
+C0
+F8
+CC
+CC
+CC
+F8
+C0
+C0
+ENDCHAR
+STARTCHAR germandbls
+ENCODING 223
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 8 0 0
+BITMAP
+70
+C8
+C8
+D0
+C8
+C8
+C8
+D0
+ENDCHAR
+STARTCHAR agrave
+ENCODING 224
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 9 0 0
+BITMAP
+40
+20
+00
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR aacute
+ENCODING 225
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 9 0 0
+BITMAP
+08
+10
+00
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR acircumflex
+ENCODING 226
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 9 0 0
+BITMAP
+30
+68
+00
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR atilde
+ENCODING 227
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 9 0 0
+BITMAP
+28
+50
+00
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR adieresis
+ENCODING 228
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 9 0 0
+BITMAP
+50
+50
+00
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR aring
+ENCODING 229
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 9 0 0
+BITMAP
+20
+50
+20
+70
+98
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR ae
+ENCODING 230
+SWIDTH 889 0
+DWIDTH 9 0
+BBX 8 6 0 0
+BITMAP
+7E
+9B
+7F
+D8
+DB
+6E
+ENDCHAR
+STARTCHAR ccedilla
+ENCODING 231
+SWIDTH 556 0
+DWIDTH 5 0
+BBX 4 8 0 -2
+BITMAP
+70
+D0
+C0
+C0
+D0
+70
+20
+60
+ENDCHAR
+STARTCHAR egrave
+ENCODING 232
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+40
+20
+00
+70
+D8
+F8
+C0
+D8
+70
+ENDCHAR
+STARTCHAR eacute
+ENCODING 233
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+10
+20
+00
+70
+D8
+F8
+C0
+D8
+70
+ENDCHAR
+STARTCHAR ecircumflex
+ENCODING 234
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+20
+50
+00
+70
+D8
+F8
+C0
+D8
+70
+ENDCHAR
+STARTCHAR edieresis
+ENCODING 235
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+50
+50
+00
+70
+D8
+F8
+C0
+D8
+70
+ENDCHAR
+STARTCHAR igrave
+ENCODING 236
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 9 0 0
+BITMAP
+80
+40
+00
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR iacute
+ENCODING 237
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 3 9 0 0
+BITMAP
+20
+40
+00
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR icircumflex
+ENCODING 238
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 3 9 -1 0
+BITMAP
+40
+A0
+00
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR idieresis
+ENCODING 239
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 3 9 0 0
+BITMAP
+A0
+A0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR eth
+ENCODING 240
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+50
+60
+A0
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR ntilde
+ENCODING 241
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+28
+50
+00
+B0
+D8
+D8
+D8
+D8
+D8
+ENDCHAR
+STARTCHAR ograve
+ENCODING 242
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+40
+20
+00
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR oacute
+ENCODING 243
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+10
+20
+00
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR ocircumflex
+ENCODING 244
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+20
+50
+00
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR otilde
+ENCODING 245
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+50
+A0
+00
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR odieresis
+ENCODING 246
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+50
+50
+00
+70
+D8
+D8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR divide
+ENCODING 247
+SWIDTH 584 0
+DWIDTH 6 0
+BBX 6 5 0 1
+BITMAP
+30
+00
+FC
+00
+30
+ENDCHAR
+STARTCHAR oslash
+ENCODING 248
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 6 6 0 0
+BITMAP
+74
+D8
+F8
+D8
+D8
+70
+ENDCHAR
+STARTCHAR ugrave
+ENCODING 249
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+40
+20
+00
+D8
+D8
+D8
+D8
+D8
+68
+ENDCHAR
+STARTCHAR uacute
+ENCODING 250
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+10
+20
+00
+D8
+D8
+D8
+D8
+D8
+68
+ENDCHAR
+STARTCHAR ucircumflex
+ENCODING 251
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+20
+50
+00
+D8
+D8
+D8
+D8
+D8
+68
+ENDCHAR
+STARTCHAR udieresis
+ENCODING 252
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+50
+50
+00
+D8
+D8
+D8
+D8
+D8
+68
+ENDCHAR
+STARTCHAR yacute
+ENCODING 253
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 11 0 -2
+BITMAP
+10
+20
+00
+D8
+D8
+D8
+D8
+78
+30
+30
+60
+ENDCHAR
+STARTCHAR thorn
+ENCODING 254
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 5 10 0 -2
+BITMAP
+C0
+C0
+F0
+D8
+C8
+C8
+D8
+F0
+C0
+C0
+ENDCHAR
+STARTCHAR ydieresis
+ENCODING 255
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 11 0 -2
+BITMAP
+50
+50
+00
+D8
+D8
+D8
+D8
+78
+30
+30
+60
+ENDCHAR
+STARTCHAR Lslash
+ENCODING -1
+SWIDTH 611 0
+DWIDTH 6 0
+BBX 6 8 -1 0
+BITMAP
+60
+60
+60
+70
+E0
+60
+60
+7C
+ENDCHAR
+STARTCHAR OE
+ENCODING -1
+SWIDTH 1000 0
+DWIDTH 10 0
+BBX 9 8 0 0
+BITMAP
+3F80
+6C00
+CC00
+CF80
+CC00
+CC00
+6C00
+3F80
+ENDCHAR
+STARTCHAR Scaron
+ENCODING -1
+SWIDTH 667 0
+DWIDTH 7 0
+BBX 6 9 0 0
+BITMAP
+28
+10
+00
+78
+CC
+70
+3C
+CC
+78
+ENDCHAR
+STARTCHAR Ydieresis
+ENCODING -1
+SWIDTH 667 0
+DWIDTH 8 0
+BBX 8 8 0 0
+BITMAP
+14
+00
+C3
+66
+3C
+18
+18
+18
+ENDCHAR
+STARTCHAR Zcaron
+ENCODING -1
+SWIDTH 611 0
+DWIDTH 7 0
+BBX 6 9 0 0
+BITMAP
+28
+10
+00
+FC
+18
+30
+60
+C0
+FC
+ENDCHAR
+STARTCHAR breve
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 4 2 0 6
+BITMAP
+90
+60
+ENDCHAR
+STARTCHAR bullet
+ENCODING -1
+SWIDTH 350 0
+DWIDTH 4 0
+BBX 2 2 1 2
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR caron
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 2 0 6
+BITMAP
+A0
+40
+ENDCHAR
+STARTCHAR circumflex
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 2 0 6
+BITMAP
+40
+A0
+ENDCHAR
+STARTCHAR dagger
+ENCODING -1
+SWIDTH 556 0
+DWIDTH 7 0
+BBX 6 10 0 -2
+BITMAP
+30
+30
+FC
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR daggerdbl
+ENCODING -1
+SWIDTH 556 0
+DWIDTH 7 0
+BBX 6 10 0 -2
+BITMAP
+30
+30
+FC
+30
+30
+30
+FC
+30
+30
+30
+ENDCHAR
+STARTCHAR dotaccent
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 2 0
+BBX 1 1 0 7
+BITMAP
+80
+ENDCHAR
+STARTCHAR dotlessi
+ENCODING -1
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 6 0 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR ellipsis
+ENCODING -1
+SWIDTH 1000 0
+DWIDTH 10 0
+BBX 8 1 1 0
+BITMAP
+DB
+ENDCHAR
+STARTCHAR emdash
+ENCODING -1
+SWIDTH 1000 0
+DWIDTH 10 0
+BBX 10 1 0 3
+BITMAP
+FFC0
+ENDCHAR
+STARTCHAR endash
+ENCODING -1
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 6 1 0 3
+BITMAP
+FC
+ENDCHAR
+STARTCHAR fi
+ENCODING -1
+SWIDTH 611 0
+DWIDTH 7 0
+BBX 7 8 -1 0
+BITMAP
+36
+60
+F6
+66
+66
+66
+66
+66
+ENDCHAR
+STARTCHAR fl
+ENCODING -1
+SWIDTH 611 0
+DWIDTH 7 0
+BBX 7 8 -1 0
+BITMAP
+36
+66
+F6
+66
+66
+66
+66
+66
+ENDCHAR
+STARTCHAR florin
+ENCODING -1
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 -2
+BITMAP
+38
+60
+F8
+60
+60
+60
+60
+60
+C0
+ENDCHAR
+STARTCHAR fraction
+ENCODING -1
+SWIDTH 167 0
+DWIDTH 4 0
+BBX 5 7 -1 0
+BITMAP
+08
+10
+10
+20
+40
+40
+80
+ENDCHAR
+STARTCHAR grave
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 2 2 0 6
+BITMAP
+80
+40
+ENDCHAR
+STARTCHAR guilsinglleft
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 3 3 1 1
+BITMAP
+60
+C0
+60
+ENDCHAR
+STARTCHAR guilsinglright
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 3 3 1 1
+BITMAP
+C0
+60
+C0
+ENDCHAR
+STARTCHAR hungarumlaut
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 4 2 0 6
+BITMAP
+50
+A0
+ENDCHAR
+STARTCHAR lslash
+ENCODING -1
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 4 8 -1 0
+BITMAP
+60
+60
+60
+70
+E0
+60
+60
+60
+ENDCHAR
+STARTCHAR oe
+ENCODING -1
+SWIDTH 944 0
+DWIDTH 10 0
+BBX 9 6 0 0
+BITMAP
+7700
+CD80
+CF80
+CC00
+CD80
+7700
+ENDCHAR
+STARTCHAR ogonek
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 3 0
+BBX 2 2 0 -2
+BITMAP
+80
+C0
+ENDCHAR
+STARTCHAR perthousand
+ENCODING -1
+SWIDTH 1000 0
+DWIDTH 11 0
+BBX 10 7 0 0
+BITMAP
+6200
+B400
+6800
+1000
+2D80
+56C0
+8D80
+ENDCHAR
+STARTCHAR quotedblbase
+ENCODING -1
+SWIDTH 500 0
+DWIDTH 6 0
+BBX 5 3 0 -2
+BITMAP
+D8
+48
+90
+ENDCHAR
+STARTCHAR quotedblleft
+ENCODING -1
+SWIDTH 500 0
+DWIDTH 6 0
+BBX 5 3 0 5
+BITMAP
+48
+90
+D8
+ENDCHAR
+STARTCHAR quotedblright
+ENCODING -1
+SWIDTH 500 0
+DWIDTH 6 0
+BBX 5 3 0 5
+BITMAP
+D8
+48
+90
+ENDCHAR
+STARTCHAR quotesinglbase
+ENCODING -1
+SWIDTH 278 0
+DWIDTH 3 0
+BBX 2 3 0 -2
+BITMAP
+C0
+40
+80
+ENDCHAR
+STARTCHAR quotesingle
+ENCODING -1
+SWIDTH 238 0
+DWIDTH 3 0
+BBX 1 3 1 5
+BITMAP
+80
+80
+80
+ENDCHAR
+STARTCHAR ring
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 3 3 0 5
+BITMAP
+40
+A0
+40
+ENDCHAR
+STARTCHAR scaron
+ENCODING -1
+SWIDTH 556 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+50
+20
+00
+70
+D8
+70
+18
+D8
+70
+ENDCHAR
+STARTCHAR tilde
+ENCODING -1
+SWIDTH 333 0
+DWIDTH 4 0
+BBX 4 2 0 6
+BITMAP
+50
+A0
+ENDCHAR
+STARTCHAR trademark
+ENCODING -1
+SWIDTH 1000 0
+DWIDTH 11 0
+BBX 9 4 1 3
+BITMAP
+E880
+4D80
+4A80
+4A80
+ENDCHAR
+STARTCHAR zcaron
+ENCODING -1
+SWIDTH 500 0
+DWIDTH 5 0
+BBX 5 9 0 0
+BITMAP
+50
+20
+00
+F8
+18
+30
+60
+C0
+F8
+ENDCHAR
+ENDFONT
--- /dev/null
+STARTFONT 2.1
+COMMENT $Xorg: $
+COMMENT ISO10646-1 extension by Markus Kuhn <mkuhn@acm.org>, 2001-03-20
+COMMENT (c) Copyright Bigelow & Holmes 1986, 1985. Lucida is a registered
+COMMENT trademark of Bigelow & Holmes. See LEGAL NOTICE file for terms
+COMMENT of the license.
+COMMENT GRID 0014 0014 0200 0200
+FONT -B&H-Lucida-Bold-R-Normal-Sans-14-140-75-75-P-92-ISO10646-1
+SIZE 14 72 72
+FONTBOUNDINGBOX 18 21 -1 -5
+STARTPROPERTIES 22
+COMMENT Begin LogicalFontDescription
+FONTNAME_REGISTRY ""
+FOUNDRY "B&H"
+FAMILY_NAME "Lucida"
+WEIGHT_NAME "Bold"
+SLANT "R"
+SETWIDTH_NAME "Normal"
+ADD_STYLE_NAME "Sans"
+PIXEL_SIZE 14
+POINT_SIZE 140
+RESOLUTION_X 75
+RESOLUTION_Y 75
+SPACING "P"
+AVERAGE_WIDTH 92
+CHARSET_REGISTRY "ISO10646"
+CHARSET_ENCODING "1"
+COMMENT END LogicalFontDescription
+FONT_ASCENT 13
+FONT_DESCENT 2
+DEFAULT_CHAR 0
+COPYRIGHT "Copyright Bigelow & Holmes 1986, 1985."
+FACE_NAME "Lucida Sans Bold"
+X_HEIGHT 8
+CAP_HEIGHT 10
+ENDPROPERTIES
+CHARS 756
+STARTCHAR char0
+ENCODING 0
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 7 9 2 0
+BITMAP
+AA
+00
+82
+00
+82
+00
+82
+00
+AA
+ENDCHAR
+STARTCHAR space
+ENCODING 32
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclam
+ENCODING 33
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 10 1 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+80
+80
+00
+C0
+C0
+ENDCHAR
+STARTCHAR quotedbl
+ENCODING 34
+SWIDTH 530 0
+DWIDTH 7 0
+BBX 5 4 1 7
+BITMAP
+D8
+D8
+90
+90
+ENDCHAR
+STARTCHAR numbersign
+ENCODING 35
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 9 10 0 0
+BITMAP
+1B00
+1B00
+1B00
+7F80
+3600
+3600
+FF80
+6C00
+6C00
+6C00
+ENDCHAR
+STARTCHAR dollar
+ENCODING 36
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 12 1 -1
+BITMAP
+10
+7C
+D6
+D0
+F0
+70
+1C
+1E
+16
+D6
+7C
+10
+ENDCHAR
+STARTCHAR percent
+ENCODING 37
+SWIDTH 898 0
+DWIDTH 12 0
+BBX 10 10 1 0
+BITMAP
+7000
+D980
+DB00
+7200
+0400
+0800
+1380
+36C0
+66C0
+0380
+ENDCHAR
+STARTCHAR ampersand
+ENCODING 38
+SWIDTH 792 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+3C00
+6600
+6600
+6400
+3980
+5980
+CD00
+C600
+E700
+7980
+ENDCHAR
+STARTCHAR quotesingle
+ENCODING 39
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+C0
+C0
+80
+80
+ENDCHAR
+STARTCHAR parenleft
+ENCODING 40
+SWIDTH 386 0
+DWIDTH 6 0
+BBX 4 12 1 -1
+BITMAP
+30
+60
+60
+C0
+C0
+C0
+C0
+C0
+C0
+60
+60
+30
+ENDCHAR
+STARTCHAR parenright
+ENCODING 41
+SWIDTH 386 0
+DWIDTH 6 0
+BBX 4 12 1 -1
+BITMAP
+C0
+60
+60
+30
+30
+30
+30
+30
+30
+60
+60
+C0
+ENDCHAR
+STARTCHAR asterisk
+ENCODING 42
+SWIDTH 464 0
+DWIDTH 7 0
+BBX 5 5 1 5
+BITMAP
+20
+A8
+70
+A8
+20
+ENDCHAR
+STARTCHAR plus
+ENCODING 43
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 7 1 1
+BITMAP
+10
+10
+10
+FE
+10
+10
+10
+ENDCHAR
+STARTCHAR comma
+ENCODING 44
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 2 4 1 -2
+BITMAP
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR hyphen
+ENCODING 45
+SWIDTH 289 0
+DWIDTH 5 0
+BBX 3 1 1 4
+BITMAP
+E0
+ENDCHAR
+STARTCHAR period
+ENCODING 46
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 2 2 1 0
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR slash
+ENCODING 47
+SWIDTH 596 0
+DWIDTH 8 0
+BBX 8 12 0 -1
+BITMAP
+03
+06
+06
+0C
+0C
+18
+18
+30
+30
+60
+60
+C0
+ENDCHAR
+STARTCHAR zero
+ENCODING 48
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+3C
+66
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR one
+ENCODING 49
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 5 10 2 0
+BITMAP
+18
+F8
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR two
+ENCODING 50
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+7E
+C7
+03
+03
+06
+0C
+18
+60
+FF
+FF
+ENDCHAR
+STARTCHAR three
+ENCODING 51
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+7E
+C7
+03
+06
+3C
+06
+03
+03
+C7
+7E
+ENDCHAR
+STARTCHAR four
+ENCODING 52
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+0C
+1C
+2C
+4C
+8C
+FF
+FF
+0C
+0C
+0C
+ENDCHAR
+STARTCHAR five
+ENCODING 53
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 10 2 0
+BITMAP
+FC
+FC
+80
+80
+FC
+0E
+06
+06
+CC
+78
+ENDCHAR
+STARTCHAR six
+ENCODING 54
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+3E
+63
+C0
+DC
+E6
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR seven
+ENCODING 55
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+FF
+FF
+06
+0C
+18
+30
+30
+60
+60
+60
+ENDCHAR
+STARTCHAR eight
+ENCODING 56
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+7E
+C7
+C3
+72
+3C
+4E
+C7
+C3
+E3
+7E
+ENDCHAR
+STARTCHAR nine
+ENCODING 57
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+3C
+66
+C3
+C3
+C3
+67
+1B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR colon
+ENCODING 58
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 2 7 1 0
+BITMAP
+C0
+C0
+00
+00
+00
+C0
+C0
+ENDCHAR
+STARTCHAR semicolon
+ENCODING 59
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 2 9 1 -2
+BITMAP
+C0
+C0
+00
+00
+00
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR less
+ENCODING 60
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 6 7 2 1
+BITMAP
+0C
+38
+60
+C0
+60
+38
+0C
+ENDCHAR
+STARTCHAR equal
+ENCODING 61
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 3 1 3
+BITMAP
+FE
+00
+FE
+ENDCHAR
+STARTCHAR greater
+ENCODING 62
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 6 7 2 1
+BITMAP
+C0
+70
+18
+0C
+18
+70
+C0
+ENDCHAR
+STARTCHAR question
+ENCODING 63
+SWIDTH 572 0
+DWIDTH 8 0
+BBX 6 10 1 0
+BITMAP
+78
+CC
+0C
+0C
+18
+30
+30
+00
+30
+30
+ENDCHAR
+STARTCHAR at
+ENCODING 64
+SWIDTH 833 0
+DWIDTH 12 0
+BBX 10 10 1 0
+BITMAP
+1E00
+6100
+4180
+8F80
+9980
+9980
+9980
+4EC0
+6000
+1F00
+ENDCHAR
+STARTCHAR A
+ENCODING 65
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR B
+ENCODING 66
+SWIDTH 669 0
+DWIDTH 10 0
+BBX 7 10 2 0
+BITMAP
+FC
+C6
+C6
+CC
+F0
+CC
+C6
+C6
+C6
+FC
+ENDCHAR
+STARTCHAR C
+ENCODING 67
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+ENDCHAR
+STARTCHAR D
+ENCODING 68
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 10 2 0
+BITMAP
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+ENDCHAR
+STARTCHAR E
+ENCODING 69
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR F
+ENCODING 70
+SWIDTH 602 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR G
+ENCODING 71
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR H
+ENCODING 72
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 10 2 0
+BITMAP
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR I
+ENCODING 73
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 2 10 2 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR J
+ENCODING 74
+SWIDTH 501 0
+DWIDTH 6 0
+BBX 4 12 0 -2
+BITMAP
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+E0
+ENDCHAR
+STARTCHAR K
+ENCODING 75
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR L
+ENCODING 76
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR M
+ENCODING 77
+SWIDTH 940 0
+DWIDTH 15 0
+BBX 11 10 2 0
+BITMAP
+E0E0
+E0E0
+B160
+B160
+B160
+9A60
+9A60
+8C60
+8C60
+8060
+ENDCHAR
+STARTCHAR N
+ENCODING 78
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 10 2 0
+BITMAP
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR O
+ENCODING 79
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 10 1 0
+BITMAP
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR P
+ENCODING 80
+SWIDTH 657 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+F8
+CC
+CC
+CC
+CC
+F8
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Q
+ENCODING 81
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 12 1 -2
+BITMAP
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+0300
+0180
+ENDCHAR
+STARTCHAR R
+ENCODING 82
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR S
+ENCODING 83
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR T
+ENCODING 84
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR U
+ENCODING 85
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 10 2 0
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR V
+ENCODING 86
+SWIDTH 735 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+C180
+C180
+C180
+6100
+6300
+6300
+3200
+3600
+1C00
+1C00
+ENDCHAR
+STARTCHAR W
+ENCODING 87
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 10 1 0
+BITMAP
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR X
+ENCODING 88
+SWIDTH 699 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+C6
+C6
+6C
+6C
+38
+38
+6C
+6C
+C6
+C6
+ENDCHAR
+STARTCHAR Y
+ENCODING 89
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR Z
+ENCODING 90
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+ENDCHAR
+STARTCHAR bracketleft
+ENCODING 91
+SWIDTH 386 0
+DWIDTH 6 0
+BBX 4 12 1 -1
+BITMAP
+F0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+F0
+ENDCHAR
+STARTCHAR backslash
+ENCODING 92
+SWIDTH 596 0
+DWIDTH 8 0
+BBX 8 12 0 -1
+BITMAP
+C0
+60
+60
+30
+30
+18
+18
+0C
+0C
+06
+06
+03
+ENDCHAR
+STARTCHAR bracketright
+ENCODING 93
+SWIDTH 386 0
+DWIDTH 6 0
+BBX 4 12 1 -1
+BITMAP
+F0
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+F0
+ENDCHAR
+STARTCHAR asciicircum
+ENCODING 94
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 6 7 2 3
+BITMAP
+30
+30
+78
+48
+CC
+84
+84
+ENDCHAR
+STARTCHAR underscore
+ENCODING 95
+SWIDTH 500 0
+DWIDTH 11 0
+BBX 9 1 1 -1
+BITMAP
+FF80
+ENDCHAR
+STARTCHAR grave
+ENCODING 96
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 2 9
+BITMAP
+E0
+38
+ENDCHAR
+STARTCHAR a
+ENCODING 97
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 8 1 0
+BITMAP
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR b
+ENCODING 98
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+C0
+C0
+C0
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+ENDCHAR
+STARTCHAR c
+ENCODING 99
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR d
+ENCODING 100
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+03
+03
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+ENDCHAR
+STARTCHAR e
+ENCODING 101
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR f
+ENCODING 102
+SWIDTH 461 0
+DWIDTH 7 0
+BBX 7 11 0 0
+BITMAP
+1E
+30
+30
+FE
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR g
+ENCODING 103
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR h
+ENCODING 104
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR i
+ENCODING 105
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 2 11 1 0
+BITMAP
+C0
+C0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR j
+ENCODING 106
+SWIDTH 361 0
+DWIDTH 5 0
+BBX 4 13 0 -2
+BITMAP
+30
+30
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+E0
+ENDCHAR
+STARTCHAR k
+ENCODING 107
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+C0
+C0
+C0
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+ENDCHAR
+STARTCHAR l
+ENCODING 108
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 2 11 1 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR m
+ENCODING 109
+SWIDTH 1006 0
+DWIDTH 14 0
+BBX 12 8 1 0
+BITMAP
+DDE0
+EF70
+C630
+C630
+C630
+C630
+C630
+C630
+ENDCHAR
+STARTCHAR n
+ENCODING 110
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR o
+ENCODING 111
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR p
+ENCODING 112
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+C0
+C0
+ENDCHAR
+STARTCHAR q
+ENCODING 113
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+03
+03
+ENDCHAR
+STARTCHAR r
+ENCODING 114
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 8 2 0
+BITMAP
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR s
+ENCODING 115
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 8 1 0
+BITMAP
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR t
+ENCODING 116
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 10 1 0
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+ENDCHAR
+STARTCHAR u
+ENCODING 117
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR v
+ENCODING 118
+SWIDTH 663 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+C6
+C6
+C6
+C6
+64
+68
+38
+38
+ENDCHAR
+STARTCHAR w
+ENCODING 119
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 8 1 0
+BITMAP
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR x
+ENCODING 120
+SWIDTH 568 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+C6
+C6
+64
+38
+38
+4C
+C6
+C6
+ENDCHAR
+STARTCHAR y
+ENCODING 121
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 10 1 -2
+BITMAP
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR z
+ENCODING 122
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+ENDCHAR
+STARTCHAR braceleft
+ENCODING 123
+SWIDTH 386 0
+DWIDTH 6 0
+BBX 4 12 1 -1
+BITMAP
+70
+C0
+C0
+60
+20
+C0
+20
+60
+C0
+C0
+C0
+70
+ENDCHAR
+STARTCHAR bar
+ENCODING 124
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 12 1 -1
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR braceright
+ENCODING 125
+SWIDTH 386 0
+DWIDTH 6 0
+BBX 4 12 1 -1
+BITMAP
+E0
+30
+30
+60
+40
+30
+40
+60
+30
+30
+30
+E0
+ENDCHAR
+STARTCHAR asciitilde
+ENCODING 126
+SWIDTH 687 0
+DWIDTH 9 0
+BBX 7 3 1 3
+BITMAP
+72
+BA
+9C
+ENDCHAR
+STARTCHAR space
+ENCODING 160
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclamdown
+ENCODING 161
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 10 1 -2
+BITMAP
+C0
+C0
+00
+40
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR cent
+ENCODING 162
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 12 1 -1
+BITMAP
+08
+08
+3E
+6A
+C8
+C8
+C8
+C8
+68
+3E
+08
+08
+ENDCHAR
+STARTCHAR sterling
+ENCODING 163
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 10 1 0
+BITMAP
+1C
+32
+30
+30
+FC
+30
+30
+30
+60
+FE
+ENDCHAR
+STARTCHAR currency
+ENCODING 164
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 9 10 0 0
+BITMAP
+8080
+4100
+3E00
+6300
+6300
+6300
+6300
+3E00
+4100
+8080
+ENDCHAR
+STARTCHAR yen
+ENCODING 165
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+C3
+C3
+62
+66
+34
+7E
+18
+7E
+18
+18
+ENDCHAR
+STARTCHAR brokenbar
+ENCODING 166
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 12 1 -1
+BITMAP
+C0
+C0
+C0
+C0
+C0
+00
+00
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR section
+ENCODING 167
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 6 11 2 -1
+BITMAP
+78
+CC
+C0
+70
+D8
+CC
+6C
+38
+0C
+CC
+78
+ENDCHAR
+STARTCHAR dieresis
+ENCODING 168
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 2 3 9
+BITMAP
+90
+90
+ENDCHAR
+STARTCHAR copyright
+ENCODING 169
+SWIDTH 825 0
+DWIDTH 12 0
+BBX 10 10 1 0
+BITMAP
+1E00
+6180
+4080
+8E40
+9840
+9840
+8E40
+4080
+6180
+1E00
+ENDCHAR
+STARTCHAR ordfeminine
+ENCODING 170
+SWIDTH 536 0
+DWIDTH 8 0
+BBX 6 6 1 4
+BITMAP
+70
+18
+78
+D8
+D8
+6C
+ENDCHAR
+STARTCHAR guillemotleft
+ENCODING 171
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 8 5 0 2
+BITMAP
+33
+66
+CC
+66
+33
+ENDCHAR
+STARTCHAR logicalnot
+ENCODING 172
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 4 1 1
+BITMAP
+FE
+02
+02
+02
+ENDCHAR
+STARTCHAR hyphen
+ENCODING 173
+SWIDTH 289 0
+DWIDTH 5 0
+BBX 3 1 1 4
+BITMAP
+E0
+ENDCHAR
+STARTCHAR registered
+ENCODING 174
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 7 1 3
+BITMAP
+38
+44
+BA
+B2
+AA
+44
+38
+ENDCHAR
+STARTCHAR macron
+ENCODING 175
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 1 3 9
+BITMAP
+F0
+ENDCHAR
+STARTCHAR degree
+ENCODING 176
+SWIDTH 241 0
+DWIDTH 4 0
+BBX 4 3 0 7
+BITMAP
+60
+90
+60
+ENDCHAR
+STARTCHAR plusminus
+ENCODING 177
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 7 1 1
+BITMAP
+10
+10
+FE
+10
+10
+00
+FE
+ENDCHAR
+STARTCHAR twosuperior
+ENCODING 178
+SWIDTH 536 0
+DWIDTH 7 0
+BBX 5 6 1 4
+BITMAP
+F0
+18
+18
+60
+C0
+F8
+ENDCHAR
+STARTCHAR threesuperior
+ENCODING 179
+SWIDTH 536 0
+DWIDTH 7 0
+BBX 5 6 1 4
+BITMAP
+F0
+18
+70
+18
+18
+F0
+ENDCHAR
+STARTCHAR acute
+ENCODING 180
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 3 9
+BITMAP
+38
+E0
+ENDCHAR
+STARTCHAR mu
+ENCODING 181
+SWIDTH 699 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+FB
+C0
+C0
+ENDCHAR
+STARTCHAR paragraph
+ENCODING 182
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 6 11 2 -1
+BITMAP
+7C
+F4
+F4
+F4
+F4
+74
+14
+14
+14
+14
+14
+ENDCHAR
+STARTCHAR periodcentered
+ENCODING 183
+SWIDTH 343 0
+DWIDTH 10 0
+BBX 2 2 4 3
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR cedilla
+ENCODING 184
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 3 2 3 -2
+BITMAP
+20
+C0
+ENDCHAR
+STARTCHAR onesuperior
+ENCODING 185
+SWIDTH 536 0
+DWIDTH 7 0
+BBX 4 6 1 4
+BITMAP
+30
+F0
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR ordmasculine
+ENCODING 186
+SWIDTH 536 0
+DWIDTH 8 0
+BBX 6 6 1 4
+BITMAP
+78
+CC
+CC
+CC
+CC
+78
+ENDCHAR
+STARTCHAR guillemotright
+ENCODING 187
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 8 5 1 2
+BITMAP
+CC
+66
+33
+66
+CC
+ENDCHAR
+STARTCHAR onequarter
+ENCODING 188
+SWIDTH 1066 0
+DWIDTH 14 0
+BBX 12 10 1 0
+BITMAP
+6100
+E100
+6200
+6200
+64E0
+6560
+0A60
+0BF0
+1060
+1060
+ENDCHAR
+STARTCHAR onehalf
+ENCODING 189
+SWIDTH 1066 0
+DWIDTH 14 0
+BBX 12 10 1 0
+BITMAP
+6100
+E100
+6200
+6200
+64E0
+6530
+0870
+08E0
+1180
+11F0
+ENDCHAR
+STARTCHAR threequarters
+ENCODING 190
+SWIDTH 1120 0
+DWIDTH 15 0
+BBX 13 10 1 0
+BITMAP
+7080
+9880
+3100
+1A00
+9A70
+74B0
+0530
+09F8
+1030
+1030
+ENDCHAR
+STARTCHAR questiondown
+ENCODING 191
+SWIDTH 572 0
+DWIDTH 8 0
+BBX 6 10 1 -2
+BITMAP
+30
+30
+00
+30
+30
+60
+C0
+C0
+CC
+78
+ENDCHAR
+STARTCHAR Agrave
+ENCODING 192
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+7000
+1C00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR Aacute
+ENCODING 193
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+0700
+1C00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR Acircumflex
+ENCODING 194
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1C00
+2600
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR Atilde
+ENCODING 195
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1A00
+2C00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR Adieresis
+ENCODING 196
+SWIDTH 773 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+24
+24
+00
+18
+18
+2C
+2C
+66
+46
+FE
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR Aring
+ENCODING 197
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1C00
+2600
+1C00
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR AE
+ENCODING 198
+SWIDTH 997 0
+DWIDTH 13 0
+BBX 11 10 1 0
+BITMAP
+1FE0
+1600
+2600
+2600
+67C0
+4600
+7E00
+C600
+C600
+C7E0
+ENDCHAR
+STARTCHAR Ccedilla
+ENCODING 199
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 12 2 -2
+BITMAP
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+08
+30
+ENDCHAR
+STARTCHAR Egrave
+ENCODING 200
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+70
+1C
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR Eacute
+ENCODING 201
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+1C
+70
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR Ecircumflex
+ENCODING 202
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+30
+58
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR Edieresis
+ENCODING 203
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+48
+48
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR Igrave
+ENCODING 204
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 4 13 1 0
+BITMAP
+E0
+30
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Iacute
+ENCODING 205
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 4 13 1 0
+BITMAP
+70
+C0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Icircumflex
+ENCODING 206
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 4 13 1 0
+BITMAP
+60
+B0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Idieresis
+ENCODING 207
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 4 13 1 0
+BITMAP
+90
+90
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Eth
+ENCODING 208
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 11 10 0 0
+BITMAP
+3F80
+30C0
+3060
+3060
+FC60
+3060
+3060
+3060
+30C0
+3F80
+ENDCHAR
+STARTCHAR Ntilde
+ENCODING 209
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+1A
+2C
+00
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR Ograve
+ENCODING 210
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+3800
+0E00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR Oacute
+ENCODING 211
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+0700
+1C00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR Ocircumflex
+ENCODING 212
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+0C00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR Otilde
+ENCODING 213
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+0D00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR Odieresis
+ENCODING 214
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+2100
+2100
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR multiply
+ENCODING 215
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 5 5 2 2
+BITMAP
+C8
+70
+20
+70
+98
+ENDCHAR
+STARTCHAR Oslash
+ENCODING 216
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 12 1 -1
+BITMAP
+0040
+3F40
+6180
+C2C0
+C2C0
+C4C0
+C8C0
+D0C0
+D0C0
+6180
+BF00
+8000
+ENDCHAR
+STARTCHAR Ugrave
+ENCODING 217
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+70
+1C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR Uacute
+ENCODING 218
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+0E
+38
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR Ucircumflex
+ENCODING 219
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+18
+2C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR Udieresis
+ENCODING 220
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+64
+3C
+ENDCHAR
+STARTCHAR Yacute
+ENCODING 221
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+0E
+38
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR Thorn
+ENCODING 222
+SWIDTH 657 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+C0
+C0
+F8
+CC
+CC
+CC
+CC
+F8
+C0
+C0
+ENDCHAR
+STARTCHAR germandbls
+ENCODING 223
+SWIDTH 724 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+7C
+C6
+C6
+C4
+CC
+C6
+C3
+C3
+C3
+C3
+CE
+ENDCHAR
+STARTCHAR agrave
+ENCODING 224
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+70
+1C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR aacute
+ENCODING 225
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+0E
+38
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR acircumflex
+ENCODING 226
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+18
+2C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR atilde
+ENCODING 227
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+34
+58
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR adieresis
+ENCODING 228
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+24
+24
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR aring
+ENCODING 229
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+18
+2C
+18
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR ae
+ENCODING 230
+SWIDTH 913 0
+DWIDTH 14 0
+BBX 12 8 1 0
+BITMAP
+7DE0
+0730
+0630
+7FF0
+C600
+C600
+C710
+79E0
+ENDCHAR
+STARTCHAR ccedilla
+ENCODING 231
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 10 1 -2
+BITMAP
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+10
+60
+ENDCHAR
+STARTCHAR egrave
+ENCODING 232
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+70
+1C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR eacute
+ENCODING 233
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+0E
+38
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR ecircumflex
+ENCODING 234
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+18
+2C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR edieresis
+ENCODING 235
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+44
+44
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR igrave
+ENCODING 236
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 11 0 0
+BITMAP
+E0
+30
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR iacute
+ENCODING 237
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 11 0 0
+BITMAP
+70
+C0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR icircumflex
+ENCODING 238
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 11 0 0
+BITMAP
+60
+B0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR idieresis
+ENCODING 239
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 11 0 0
+BITMAP
+90
+90
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR eth
+ENCODING 240
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+10
+3E
+0C
+3E
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR ntilde
+ENCODING 241
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+1A
+2C
+00
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR ograve
+ENCODING 242
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+70
+1C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR oacute
+ENCODING 243
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+0E
+38
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR ocircumflex
+ENCODING 244
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+18
+2C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR otilde
+ENCODING 245
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+34
+58
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR odieresis
+ENCODING 246
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+24
+24
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR divide
+ENCODING 247
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 7 1 1
+BITMAP
+10
+10
+00
+FE
+00
+10
+10
+ENDCHAR
+STARTCHAR oslash
+ENCODING 248
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 10 1 -1
+BITMAP
+01
+3D
+66
+CB
+CB
+D3
+D3
+66
+BC
+80
+ENDCHAR
+STARTCHAR ugrave
+ENCODING 249
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+70
+1C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uacute
+ENCODING 250
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+1C
+70
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR ucircumflex
+ENCODING 251
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+18
+2C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR udieresis
+ENCODING 252
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR yacute
+ENCODING 253
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+1C
+70
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR thorn
+ENCODING 254
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+C0
+C0
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+C0
+C0
+ENDCHAR
+STARTCHAR ydieresis
+ENCODING 255
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+44
+44
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR Amacron
+ENCODING 256
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 12 1 0
+BITMAP
+1E00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR amacron
+ENCODING 257
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 10 1 0
+BITMAP
+3C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR Abreve
+ENCODING 258
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+2100
+1E00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR abreve
+ENCODING 259
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+42
+3C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR Aogonek
+ENCODING 260
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 12 1 -2
+BITMAP
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+0800
+0600
+ENDCHAR
+STARTCHAR aogonek
+ENCODING 261
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 10 1 -2
+BITMAP
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+10
+0C
+ENDCHAR
+STARTCHAR Cacute
+ENCODING 262
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+0E
+38
+00
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+ENDCHAR
+STARTCHAR cacute
+ENCODING 263
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+0E
+38
+00
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Ccircumflex
+ENCODING 264
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+18
+2C
+00
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+ENDCHAR
+STARTCHAR ccircumflex
+ENCODING 265
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+30
+58
+00
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Cdotaccent
+ENCODING 266
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+18
+18
+00
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+ENDCHAR
+STARTCHAR cdotaccent
+ENCODING 267
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+30
+30
+00
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Ccaron
+ENCODING 268
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+2C
+18
+00
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+ENDCHAR
+STARTCHAR ccaron
+ENCODING 269
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+58
+30
+00
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Dcaron
+ENCODING 270
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 13 2 0
+BITMAP
+2C00
+1800
+0000
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+ENDCHAR
+STARTCHAR dcaron
+ENCODING 271
+SWIDTH 926 0
+DWIDTH 14 0
+BBX 12 11 1 0
+BITMAP
+0330
+0330
+0310
+3F20
+6300
+C300
+C300
+C300
+C300
+6700
+3B00
+ENDCHAR
+STARTCHAR Dcroat
+ENCODING 272
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 11 10 0 0
+BITMAP
+3F80
+30C0
+3060
+3060
+FC60
+3060
+3060
+3060
+30C0
+3F80
+ENDCHAR
+STARTCHAR dcroat
+ENCODING 273
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+03
+1F
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+ENDCHAR
+STARTCHAR Emacron
+ENCODING 274
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 12 2 0
+BITMAP
+F0
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR emacron
+ENCODING 275
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+3C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Ebreve
+ENCODING 276
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+84
+78
+00
+7E
+60
+60
+60
+7C
+60
+60
+60
+60
+7E
+ENDCHAR
+STARTCHAR ebreve
+ENCODING 277
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+42
+3C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Edotaccent
+ENCODING 278
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+60
+60
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR edotaccent
+ENCODING 279
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+18
+18
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Eogonek
+ENCODING 280
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 12 2 -2
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+20
+18
+ENDCHAR
+STARTCHAR eogonek
+ENCODING 281
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 10 1 -2
+BITMAP
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+20
+18
+ENDCHAR
+STARTCHAR Ecaron
+ENCODING 282
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+B0
+60
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR ecaron
+ENCODING 283
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+2C
+18
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR Gcircumflex
+ENCODING 284
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+18
+2C
+00
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR gcircumflex
+ENCODING 285
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+18
+2C
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR Gbreve
+ENCODING 286
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+42
+3C
+00
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR gbreve
+ENCODING 287
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+42
+3C
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR Gdotaccent
+ENCODING 288
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+18
+18
+00
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR gdotaccent
+ENCODING 289
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+18
+18
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR Gcommaaccent
+ENCODING 290
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 15 2 -5
+BITMAP
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR gcommaaccent
+ENCODING 291
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 15 1 -2
+BITMAP
+08
+10
+18
+18
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR Hcircumflex
+ENCODING 292
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+18
+2C
+00
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR hcircumflex
+ENCODING 293
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+60
+B0
+00
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR Hbar
+ENCODING 294
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 10 2 0
+BITMAP
+C3
+FF
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR hbar
+ENCODING 295
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+C0
+F8
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR Itilde
+ENCODING 296
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 5 13 1 0
+BITMAP
+68
+B0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR itilde
+ENCODING 297
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 5 11 0 0
+BITMAP
+68
+B0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Imacron
+ENCODING 298
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 4 12 1 0
+BITMAP
+F0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR imacron
+ENCODING 299
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 10 0 0
+BITMAP
+F0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Ibreve
+ENCODING 300
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 6 13 0 0
+BITMAP
+84
+78
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR ibreve
+ENCODING 301
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 6 11 -1 0
+BITMAP
+84
+78
+00
+30
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR Iogonek
+ENCODING 302
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 3 12 2 -2
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+80
+60
+ENDCHAR
+STARTCHAR iogonek
+ENCODING 303
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 3 13 1 -2
+BITMAP
+C0
+C0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+80
+60
+ENDCHAR
+STARTCHAR Idotaccent
+ENCODING 304
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 2 13 2 0
+BITMAP
+C0
+C0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR dotlessi
+ENCODING 305
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 2 8 1 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR IJ
+ENCODING 306
+SWIDTH 844 0
+DWIDTH 12 0
+BBX 8 12 2 -2
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+03
+0E
+ENDCHAR
+STARTCHAR ij
+ENCODING 307
+SWIDTH 704 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+C6
+C6
+00
+C6
+C6
+C6
+C6
+C6
+C6
+C6
+C6
+06
+1C
+ENDCHAR
+STARTCHAR Jcircumflex
+ENCODING 308
+SWIDTH 501 0
+DWIDTH 6 0
+BBX 5 15 0 -2
+BITMAP
+30
+58
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+E0
+ENDCHAR
+STARTCHAR jcircumflex
+ENCODING 309
+SWIDTH 361 0
+DWIDTH 5 0
+BBX 5 13 0 -2
+BITMAP
+30
+58
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+E0
+ENDCHAR
+STARTCHAR Kcommaaccent
+ENCODING 310
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 15 2 -5
+BITMAP
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR kcommaaccent
+ENCODING 311
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 16 1 -5
+BITMAP
+C0
+C0
+C0
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR kgreenlandic
+ENCODING 312
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 8 1 0
+BITMAP
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+ENDCHAR
+STARTCHAR Lacute
+ENCODING 313
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+38
+E0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR lacute
+ENCODING 314
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 5 14 0 0
+BITMAP
+38
+E0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR Lcommaaccent
+ENCODING 315
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 15 2 -5
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+00
+60
+60
+20
+40
+ENDCHAR
+STARTCHAR lcommaaccent
+ENCODING 316
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 2 16 1 -5
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+00
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR Lcaron
+ENCODING 317
+SWIDTH 854 0
+DWIDTH 13 0
+BBX 10 11 2 0
+BITMAP
+00C0
+C0C0
+C040
+C080
+C000
+C000
+C000
+C000
+C000
+C000
+FC00
+ENDCHAR
+STARTCHAR lcaron
+ENCODING 318
+SWIDTH 608 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+CC
+CC
+C4
+C8
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Ldot
+ENCODING 319
+SWIDTH 932 0
+DWIDTH 19 0
+BBX 13 10 2 0
+BITMAP
+C000
+C000
+C000
+C000
+C000
+C018
+C018
+C000
+C000
+FC00
+ENDCHAR
+STARTCHAR ldot
+ENCODING 320
+SWIDTH 686 0
+DWIDTH 14 0
+BBX 9 11 1 0
+BITMAP
+C000
+C000
+C000
+C000
+C000
+C000
+C180
+C180
+C000
+C000
+C000
+ENDCHAR
+STARTCHAR Lslash
+ENCODING 321
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 8 10 0 0
+BITMAP
+30
+30
+30
+30
+3C
+F0
+30
+30
+30
+3F
+ENDCHAR
+STARTCHAR lslash
+ENCODING 322
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 6 11 0 0
+BITMAP
+30
+30
+30
+30
+3C
+F0
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR Nacute
+ENCODING 323
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+0E
+38
+00
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR nacute
+ENCODING 324
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+0E
+38
+00
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR Ncommaaccent
+ENCODING 325
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 15 2 -5
+BITMAP
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+00
+0C
+0C
+04
+08
+ENDCHAR
+STARTCHAR ncommaaccent
+ENCODING 326
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 13 1 -5
+BITMAP
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR Ncaron
+ENCODING 327
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+58
+30
+00
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR ncaron
+ENCODING 328
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+2C
+18
+00
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR napostrophe
+ENCODING 329
+SWIDTH 945 0
+DWIDTH 14 0
+BBX 12 11 1 0
+BITMAP
+C000
+C000
+4000
+8DE0
+0E70
+0C30
+0C30
+0C30
+0C30
+0C30
+0C30
+ENDCHAR
+STARTCHAR Eng
+ENCODING 330
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 12 2 -2
+BITMAP
+E1
+E1
+B1
+B1
+99
+99
+8F
+8F
+87
+87
+03
+0E
+ENDCHAR
+STARTCHAR eng
+ENCODING 331
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+03
+0E
+ENDCHAR
+STARTCHAR Omacron
+ENCODING 332
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 12 1 0
+BITMAP
+1E00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR omacron
+ENCODING 333
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+3C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR Obreve
+ENCODING 334
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+2100
+1E00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR obreve
+ENCODING 335
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+42
+3C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR Ohungarumlaut
+ENCODING 336
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+1B00
+1200
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR ohungarumlaut
+ENCODING 337
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+36
+24
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR OE
+ENCODING 338
+SWIDTH 1102 0
+DWIDTH 15 0
+BBX 13 10 1 0
+BITMAP
+3DF8
+6380
+C180
+C180
+C1F0
+C180
+C180
+C180
+6380
+3DF8
+ENDCHAR
+STARTCHAR oe
+ENCODING 339
+SWIDTH 990 0
+DWIDTH 15 0
+BBX 13 8 1 0
+BITMAP
+3CF0
+6398
+C318
+C3F8
+C300
+C300
+6388
+3CF0
+ENDCHAR
+STARTCHAR Racute
+ENCODING 340
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+0E
+38
+00
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR racute
+ENCODING 341
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 11 2 0
+BITMAP
+38
+E0
+00
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Rcommaaccent
+ENCODING 342
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 15 2 -5
+BITMAP
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR rcommaaccent
+ENCODING 343
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 13 2 -5
+BITMAP
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+00
+60
+60
+20
+40
+ENDCHAR
+STARTCHAR Rcaron
+ENCODING 344
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+2C
+18
+00
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR rcaron
+ENCODING 345
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 11 2 0
+BITMAP
+B0
+60
+00
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR Sacute
+ENCODING 346
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+1C
+70
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR sacute
+ENCODING 347
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+1C
+70
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR Scircumflex
+ENCODING 348
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+30
+58
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR scircumflex
+ENCODING 349
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+60
+B0
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR Scedilla
+ENCODING 350
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 12 1 -2
+BITMAP
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+08
+30
+ENDCHAR
+STARTCHAR scedilla
+ENCODING 351
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 10 1 -2
+BITMAP
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+10
+60
+ENDCHAR
+STARTCHAR Scaron
+ENCODING 352
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+2C
+18
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR scaron
+ENCODING 353
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+58
+30
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR Tcommaaccent
+ENCODING 354
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+08
+30
+ENDCHAR
+STARTCHAR tcommaaccent
+ENCODING 355
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 12 1 -2
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+20
+C0
+ENDCHAR
+STARTCHAR Tcaron
+ENCODING 356
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+2C
+18
+00
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR tcaron
+ENCODING 357
+SWIDTH 679 0
+DWIDTH 11 0
+BBX 9 11 1 0
+BITMAP
+0180
+6180
+6080
+F900
+6000
+6000
+6000
+6000
+6000
+6000
+3800
+ENDCHAR
+STARTCHAR Tbar
+ENCODING 358
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+FF
+18
+18
+18
+3E
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR tbar
+ENCODING 359
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 10 1 0
+BITMAP
+60
+60
+F8
+60
+60
+F8
+60
+60
+60
+38
+ENDCHAR
+STARTCHAR Utilde
+ENCODING 360
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+1A
+2C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR utilde
+ENCODING 361
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+1A
+2C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR Umacron
+ENCODING 362
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 12 2 0
+BITMAP
+3C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR umacron
+ENCODING 363
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+3C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR Ubreve
+ENCODING 364
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+42
+3C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR ubreve
+ENCODING 365
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+42
+3C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR Uring
+ENCODING 366
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 14 2 0
+BITMAP
+18
+2C
+18
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uring
+ENCODING 367
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 12 1 0
+BITMAP
+18
+2C
+18
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR Uhungarumlaut
+ENCODING 368
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+36
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uhungarumlaut
+ENCODING 369
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+36
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR Uogonek
+ENCODING 370
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 12 2 -2
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+10
+0C
+ENDCHAR
+STARTCHAR uogonek
+ENCODING 371
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+10
+0C
+ENDCHAR
+STARTCHAR Wcircumflex
+ENCODING 372
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+0C00
+1600
+0000
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR wcircumflex
+ENCODING 373
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 11 1 0
+BITMAP
+0C00
+1600
+0000
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR Ycircumflex
+ENCODING 374
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+18
+2C
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR ycircumflex
+ENCODING 375
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+30
+58
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR Ydieresis
+ENCODING 376
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+24
+24
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR Zacute
+ENCODING 377
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+0E
+38
+00
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+ENDCHAR
+STARTCHAR zacute
+ENCODING 378
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+0E
+38
+00
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+ENDCHAR
+STARTCHAR Zdotaccent
+ENCODING 379
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+18
+18
+00
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+ENDCHAR
+STARTCHAR zdotaccent
+ENCODING 380
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+18
+18
+00
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+ENDCHAR
+STARTCHAR Zcaron
+ENCODING 381
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+2C
+18
+00
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+ENDCHAR
+STARTCHAR zcaron
+ENCODING 382
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+2C
+18
+00
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+ENDCHAR
+STARTCHAR uni0186
+ENCODING 390
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+7C
+C6
+03
+03
+03
+03
+03
+03
+C6
+7C
+ENDCHAR
+STARTCHAR uni0189
+ENCODING 393
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 11 10 0 0
+BITMAP
+3F80
+30C0
+3060
+3060
+FC60
+3060
+3060
+3060
+30C0
+3F80
+ENDCHAR
+STARTCHAR uni018E
+ENCODING 398
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+FC
+0C
+0C
+0C
+0C
+7C
+0C
+0C
+0C
+FC
+ENDCHAR
+STARTCHAR florin
+ENCODING 402
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 11 2 -1
+BITMAP
+1C
+32
+30
+30
+FC
+60
+60
+60
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni0197
+ENCODING 407
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 5 10 1 0
+BITMAP
+60
+60
+60
+60
+F8
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni019A
+ENCODING 410
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 5 11 0 0
+BITMAP
+60
+60
+60
+60
+60
+F8
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni019D
+ENCODING 413
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 10 12 0 -2
+BITMAP
+3840
+3840
+2C40
+2C40
+2640
+2640
+3340
+3140
+31C0
+31C0
+3000
+E000
+ENDCHAR
+STARTCHAR uni019F
+ENCODING 415
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 10 1 0
+BITMAP
+3F00
+6180
+C0C0
+C0C0
+FFC0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR Ohorn
+ENCODING 416
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 11 10 1 0
+BITMAP
+3F60
+61E0
+C0E0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR ohorn
+ENCODING 417
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 10 8 1 0
+BITMAP
+3CC0
+66C0
+C340
+C380
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni01A7
+ENCODING 423
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+7C
+C6
+06
+0E
+3C
+78
+E0
+C0
+C6
+7C
+ENDCHAR
+STARTCHAR uni01A8
+ENCODING 424
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 8 1 0
+BITMAP
+F8
+0C
+0C
+3C
+F0
+C0
+C0
+7C
+ENDCHAR
+STARTCHAR uni01AE
+ENCODING 430
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+0E
+ENDCHAR
+STARTCHAR Uhorn
+ENCODING 431
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 10 10 2 0
+BITMAP
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uhorn
+ENCODING 432
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 10 8 1 0
+BITMAP
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+E700
+7B00
+ENDCHAR
+STARTCHAR uni01B5
+ENCODING 437
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+FE
+06
+0C
+1C
+7C
+30
+70
+60
+C0
+FE
+ENDCHAR
+STARTCHAR uni01B6
+ENCODING 438
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+FE
+06
+0C
+7C
+30
+60
+C0
+FE
+ENDCHAR
+STARTCHAR uni01BB
+ENCODING 443
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 10 1 0
+BITMAP
+7E
+C7
+03
+03
+FF
+0C
+18
+60
+FF
+FF
+ENDCHAR
+STARTCHAR uni01BC
+ENCODING 444
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 10 2 0
+BITMAP
+FC
+FC
+80
+80
+FC
+0E
+06
+06
+CC
+78
+ENDCHAR
+STARTCHAR uni01C0
+ENCODING 448
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 12 1 -1
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni01C2
+ENCODING 450
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 12 1 -1
+BITMAP
+18
+18
+18
+18
+18
+FE
+18
+FE
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR uni01C3
+ENCODING 451
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 10 1 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+80
+80
+00
+C0
+C0
+ENDCHAR
+STARTCHAR uni01CD
+ENCODING 461
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1600
+0C00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni01CE
+ENCODING 462
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+2C
+18
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni01CF
+ENCODING 463
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 4 13 1 0
+BITMAP
+B0
+60
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni01D0
+ENCODING 464
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 11 0 0
+BITMAP
+B0
+60
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni01D1
+ENCODING 465
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+1600
+0C00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni01D2
+ENCODING 466
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+2C
+18
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni01D3
+ENCODING 467
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+2C
+18
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni01D4
+ENCODING 468
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+2C
+18
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni01D5
+ENCODING 469
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 15 2 0
+BITMAP
+3C
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+64
+3C
+ENDCHAR
+STARTCHAR uni01D6
+ENCODING 470
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+3C
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni01D7
+ENCODING 471
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 16 2 0
+BITMAP
+0E
+38
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+64
+3C
+ENDCHAR
+STARTCHAR uni01D8
+ENCODING 472
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+0E
+38
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni01D9
+ENCODING 473
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 16 2 0
+BITMAP
+2C
+18
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+64
+3C
+ENDCHAR
+STARTCHAR uni01DA
+ENCODING 474
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+2C
+18
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni01DB
+ENCODING 475
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 16 2 0
+BITMAP
+70
+1C
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+64
+3C
+ENDCHAR
+STARTCHAR uni01DC
+ENCODING 476
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+70
+1C
+00
+24
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni01DD
+ENCODING 477
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+78
+8C
+06
+06
+FE
+C6
+CC
+78
+ENDCHAR
+STARTCHAR uni01DE
+ENCODING 478
+SWIDTH 773 0
+DWIDTH 10 0
+BBX 8 15 1 0
+BITMAP
+3C
+00
+24
+24
+00
+18
+18
+2C
+2C
+66
+46
+FE
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni01DF
+ENCODING 479
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 13 1 0
+BITMAP
+3C
+00
+24
+24
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni01E0
+ENCODING 480
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 15 1 0
+BITMAP
+1E00
+0000
+0C00
+0C00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni01E1
+ENCODING 481
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 13 1 0
+BITMAP
+3C
+00
+18
+18
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni01E2
+ENCODING 482
+SWIDTH 997 0
+DWIDTH 13 0
+BBX 11 12 1 0
+BITMAP
+0F00
+0000
+1FE0
+1600
+2600
+2600
+67C0
+4600
+7E00
+C600
+C600
+C7E0
+ENDCHAR
+STARTCHAR uni01E3
+ENCODING 483
+SWIDTH 913 0
+DWIDTH 14 0
+BBX 12 10 1 0
+BITMAP
+0780
+0000
+7DE0
+0730
+0630
+7FF0
+C600
+C600
+C710
+79E0
+ENDCHAR
+STARTCHAR uni01E4
+ENCODING 484
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 9 10 2 0
+BITMAP
+3E00
+6300
+C000
+C000
+C000
+C300
+CF80
+C300
+6300
+3F00
+ENDCHAR
+STARTCHAR uni01E5
+ENCODING 485
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+3F
+63
+C3
+C3
+C3
+67
+3B
+FF
+C6
+7C
+ENDCHAR
+STARTCHAR Gcaron
+ENCODING 486
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+2C
+18
+00
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR gcaron
+ENCODING 487
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+2C
+18
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR uni01E8
+ENCODING 488
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+2C
+18
+00
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni01E9
+ENCODING 489
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+B0
+60
+00
+C0
+C0
+C0
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+ENDCHAR
+STARTCHAR uni01EA
+ENCODING 490
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 12 1 -2
+BITMAP
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+0800
+0600
+ENDCHAR
+STARTCHAR uni01EB
+ENCODING 491
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+10
+0C
+ENDCHAR
+STARTCHAR uni01EC
+ENCODING 492
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 14 1 -2
+BITMAP
+1E00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+0800
+0600
+ENDCHAR
+STARTCHAR uni01ED
+ENCODING 493
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+3C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+10
+0C
+ENDCHAR
+STARTCHAR uni01F0
+ENCODING 496
+SWIDTH 361 0
+DWIDTH 5 0
+BBX 5 13 0 -2
+BITMAP
+58
+30
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+E0
+ENDCHAR
+STARTCHAR uni01F4
+ENCODING 500
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+0E
+38
+00
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR uni01F5
+ENCODING 501
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+07
+1C
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR uni01F8
+ENCODING 504
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+E0
+38
+00
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR uni01F9
+ENCODING 505
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+70
+1C
+00
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR Aringacute
+ENCODING 506
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+0700
+1C00
+0000
+1C00
+2600
+1C00
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR aringacute
+ENCODING 507
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+0E
+38
+00
+18
+2C
+18
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR AEacute
+ENCODING 508
+SWIDTH 997 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+0380
+0E00
+0000
+1FE0
+1600
+2600
+2600
+67C0
+4600
+7E00
+C600
+C600
+C7E0
+ENDCHAR
+STARTCHAR aeacute
+ENCODING 509
+SWIDTH 913 0
+DWIDTH 14 0
+BBX 12 11 1 0
+BITMAP
+01C0
+0700
+0000
+7DE0
+0730
+0630
+7FF0
+C600
+C600
+C710
+79E0
+ENDCHAR
+STARTCHAR Oslashacute
+ENCODING 510
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 15 1 -1
+BITMAP
+0380
+0E00
+0000
+0040
+3F40
+6180
+C2C0
+C2C0
+C4C0
+C8C0
+D0C0
+D0C0
+6180
+BF00
+8000
+ENDCHAR
+STARTCHAR oslashacute
+ENCODING 511
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 13 1 -1
+BITMAP
+07
+1C
+00
+01
+3D
+66
+CB
+CB
+D3
+D3
+66
+BC
+80
+ENDCHAR
+STARTCHAR uni0200
+ENCODING 512
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+3600
+1200
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni0201
+ENCODING 513
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+36
+12
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni0202
+ENCODING 514
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1E00
+2100
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni0203
+ENCODING 515
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+3C
+42
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni0204
+ENCODING 516
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+D8
+48
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR uni0205
+ENCODING 517
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+6C
+24
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni0206
+ENCODING 518
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+78
+84
+00
+7E
+60
+60
+60
+7C
+60
+60
+60
+60
+7E
+ENDCHAR
+STARTCHAR uni0207
+ENCODING 519
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+3C
+42
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni0208
+ENCODING 520
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 5 13 0 0
+BITMAP
+D8
+48
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR uni0209
+ENCODING 521
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 5 11 -1 0
+BITMAP
+D8
+48
+00
+30
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR uni020A
+ENCODING 522
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 6 13 0 0
+BITMAP
+78
+84
+00
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR uni020B
+ENCODING 523
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 6 11 -1 0
+BITMAP
+78
+84
+00
+30
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR uni020C
+ENCODING 524
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+3600
+1200
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni020D
+ENCODING 525
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+6C
+24
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni020E
+ENCODING 526
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+1E00
+2100
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni020F
+ENCODING 527
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+3C
+42
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni0210
+ENCODING 528
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+6C
+24
+00
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni0211
+ENCODING 529
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+D8
+48
+00
+6C
+6C
+70
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni0212
+ENCODING 530
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+3C
+42
+00
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni0213
+ENCODING 531
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+78
+84
+00
+6C
+6C
+70
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni0214
+ENCODING 532
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+6C
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni0215
+ENCODING 533
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+6C
+24
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni0216
+ENCODING 534
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+3C
+42
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni0217
+ENCODING 535
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+3C
+42
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR Scommaaccent
+ENCODING 536
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 15 1 -5
+BITMAP
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR scommaaccent
+ENCODING 537
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 13 1 -5
+BITMAP
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+00
+30
+30
+10
+20
+ENDCHAR
+STARTCHAR Tcommaaccent
+ENCODING 538
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 15 1 -5
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+00
+18
+18
+08
+10
+ENDCHAR
+STARTCHAR tcommaaccent
+ENCODING 539
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 15 1 -5
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+00
+30
+30
+10
+20
+ENDCHAR
+STARTCHAR uni021E
+ENCODING 542
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+2C
+18
+00
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni021F
+ENCODING 543
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+B0
+60
+00
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni0226
+ENCODING 550
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+0C00
+0C00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni0227
+ENCODING 551
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 0
+BITMAP
+18
+18
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni0228
+ENCODING 552
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 12 2 -2
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+20
+C0
+ENDCHAR
+STARTCHAR uni0229
+ENCODING 553
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 10 1 -2
+BITMAP
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+10
+60
+ENDCHAR
+STARTCHAR uni022A
+ENCODING 554
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 15 1 0
+BITMAP
+1E00
+0000
+2100
+2100
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni022B
+ENCODING 555
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+3C
+00
+24
+24
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni022C
+ENCODING 556
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 15 1 0
+BITMAP
+1E00
+0000
+0D00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni022D
+ENCODING 557
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+3C
+00
+34
+58
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni022E
+ENCODING 558
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 0
+BITMAP
+0C00
+0C00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni022F
+ENCODING 559
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+18
+18
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni0230
+ENCODING 560
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 15 1 0
+BITMAP
+1E00
+0000
+0C00
+0C00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni0231
+ENCODING 561
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+3C
+00
+18
+18
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni0232
+ENCODING 562
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 12 1 0
+BITMAP
+3C
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR uni0233
+ENCODING 563
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 12 1 -2
+BITMAP
+3C
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR uni0250
+ENCODING 592
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 8 1 0
+BITMAP
+EE
+73
+63
+63
+7E
+60
+60
+3E
+ENDCHAR
+STARTCHAR uni0254
+ENCODING 596
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+78
+CC
+06
+06
+06
+06
+8C
+78
+ENDCHAR
+STARTCHAR uni0258
+ENCODING 600
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+78
+CC
+C6
+FE
+06
+06
+8C
+78
+ENDCHAR
+STARTCHAR uni0259
+ENCODING 601
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+78
+8C
+06
+06
+FE
+C6
+CC
+78
+ENDCHAR
+STARTCHAR uni025F
+ENCODING 607
+SWIDTH 461 0
+DWIDTH 7 0
+BBX 7 11 0 -3
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+FE
+18
+18
+F0
+ENDCHAR
+STARTCHAR uni0265
+ENCODING 613
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+03
+03
+03
+ENDCHAR
+STARTCHAR uni0275
+ENCODING 629
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+3C
+66
+C3
+FF
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni0279
+ENCODING 633
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 8 2 0
+BITMAP
+18
+18
+18
+18
+18
+38
+D8
+D8
+ENDCHAR
+STARTCHAR uni0287
+ENCODING 647
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 10 1 0
+BITMAP
+E0
+30
+30
+30
+30
+30
+30
+F8
+30
+30
+ENDCHAR
+STARTCHAR uni0288
+ENCODING 648
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 12 1 -2
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+60
+60
+38
+ENDCHAR
+STARTCHAR uni0289
+ENCODING 649
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 8 1 0
+BITMAP
+C3
+C3
+C3
+FF
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni028C
+ENCODING 652
+SWIDTH 663 0
+DWIDTH 9 0
+BBX 7 8 1 0
+BITMAP
+38
+38
+2C
+4C
+C6
+C6
+C6
+C6
+ENDCHAR
+STARTCHAR uni028D
+ENCODING 653
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 8 1 0
+BITMAP
+3180
+3180
+3BC0
+6AC0
+6EC0
+C460
+C460
+C060
+ENDCHAR
+STARTCHAR uni028E
+ENCODING 654
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 10 1 0
+BITMAP
+0E
+0C
+18
+38
+2C
+6C
+C6
+C6
+C6
+C6
+ENDCHAR
+STARTCHAR uni029E
+ENCODING 670
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 11 1 -3
+BITMAP
+E3
+63
+33
+1B
+0F
+1B
+33
+63
+03
+03
+03
+ENDCHAR
+STARTCHAR uni02BB
+ENCODING 699
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+40
+80
+C0
+C0
+ENDCHAR
+STARTCHAR afii57929
+ENCODING 700
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR afii64937
+ENCODING 701
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+C0
+C0
+80
+40
+ENDCHAR
+STARTCHAR circumflex
+ENCODING 710
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 2 3 9
+BITMAP
+60
+B0
+ENDCHAR
+STARTCHAR caron
+ENCODING 711
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 2 3 9
+BITMAP
+B0
+60
+ENDCHAR
+STARTCHAR uni02C8
+ENCODING 712
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+C0
+C0
+80
+80
+ENDCHAR
+STARTCHAR macron
+ENCODING 713
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 1 3 9
+BITMAP
+F0
+ENDCHAR
+STARTCHAR uni02CA
+ENCODING 714
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 3 9
+BITMAP
+38
+E0
+ENDCHAR
+STARTCHAR uni02CB
+ENCODING 715
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 2 9
+BITMAP
+E0
+38
+ENDCHAR
+STARTCHAR uni02CD
+ENCODING 717
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 1 3 -2
+BITMAP
+F0
+ENDCHAR
+STARTCHAR uni02CE
+ENCODING 718
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 2 -3
+BITMAP
+E0
+38
+ENDCHAR
+STARTCHAR uni02CF
+ENCODING 719
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 3 -3
+BITMAP
+38
+E0
+ENDCHAR
+STARTCHAR breve
+ENCODING 728
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 6 2 2 9
+BITMAP
+84
+78
+ENDCHAR
+STARTCHAR dotaccent
+ENCODING 729
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 2 2 4 9
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR ring
+ENCODING 730
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 4 3 3 8
+BITMAP
+60
+B0
+60
+ENDCHAR
+STARTCHAR ogonek
+ENCODING 731
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 3 2 5 -2
+BITMAP
+80
+60
+ENDCHAR
+STARTCHAR tilde
+ENCODING 732
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 3 9
+BITMAP
+68
+B0
+ENDCHAR
+STARTCHAR hungarumlaut
+ENCODING 733
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 3 9
+BITMAP
+D8
+90
+ENDCHAR
+STARTCHAR uni02EE
+ENCODING 750
+SWIDTH 530 0
+DWIDTH 7 0
+BBX 5 4 1 7
+BITMAP
+D8
+D8
+48
+90
+ENDCHAR
+STARTCHAR uni037E
+ENCODING 894
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 2 9 1 -2
+BITMAP
+C0
+C0
+00
+00
+00
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR tonos
+ENCODING 900
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 2 3 9
+BITMAP
+38
+E0
+ENDCHAR
+STARTCHAR dieresistonos
+ENCODING 901
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 5 5 3 9
+BITMAP
+38
+E0
+00
+90
+90
+ENDCHAR
+STARTCHAR anoteleia
+ENCODING 903
+SWIDTH 343 0
+DWIDTH 10 0
+BBX 2 2 4 3
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR mu
+ENCODING 956
+SWIDTH 699 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+FB
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E00
+ENCODING 7680
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 14 1 -4
+BITMAP
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+0000
+0C00
+1600
+0C00
+ENDCHAR
+STARTCHAR uni1E01
+ENCODING 7681
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 12 1 -4
+BITMAP
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+00
+18
+2C
+18
+ENDCHAR
+STARTCHAR uni1E02
+ENCODING 7682
+SWIDTH 669 0
+DWIDTH 10 0
+BBX 7 13 2 0
+BITMAP
+30
+30
+00
+FC
+C6
+C6
+CC
+F0
+CC
+C6
+C6
+C6
+FC
+ENDCHAR
+STARTCHAR uni1E03
+ENCODING 7683
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+60
+60
+00
+C0
+C0
+C0
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+ENDCHAR
+STARTCHAR uni1E04
+ENCODING 7684
+SWIDTH 669 0
+DWIDTH 10 0
+BBX 7 13 2 -3
+BITMAP
+FC
+C6
+C6
+CC
+F0
+CC
+C6
+C6
+C6
+FC
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E05
+ENCODING 7685
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 14 1 -3
+BITMAP
+C0
+C0
+C0
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E06
+ENCODING 7686
+SWIDTH 669 0
+DWIDTH 10 0
+BBX 7 12 2 -2
+BITMAP
+FC
+C6
+C6
+CC
+F0
+CC
+C6
+C6
+C6
+FC
+00
+78
+ENDCHAR
+STARTCHAR uni1E07
+ENCODING 7687
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+C0
+C0
+C0
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+00
+3C
+ENDCHAR
+STARTCHAR uni1E08
+ENCODING 7688
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 8 15 2 -2
+BITMAP
+0E
+38
+00
+3E
+63
+C0
+C0
+C0
+C0
+C0
+C0
+63
+3E
+08
+30
+ENDCHAR
+STARTCHAR uni1E09
+ENCODING 7689
+SWIDTH 545 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+0E
+38
+00
+3C
+66
+C0
+C0
+C0
+C0
+62
+3C
+10
+60
+ENDCHAR
+STARTCHAR uni1E0A
+ENCODING 7690
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 13 2 0
+BITMAP
+1800
+1800
+0000
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+ENDCHAR
+STARTCHAR uni1E0B
+ENCODING 7691
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+06
+06
+00
+03
+03
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+ENDCHAR
+STARTCHAR uni1E0C
+ENCODING 7692
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 13 2 -3
+BITMAP
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR uni1E0D
+ENCODING 7693
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 14 1 -3
+BITMAP
+03
+03
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E0E
+ENCODING 7694
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 12 2 -2
+BITMAP
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+0000
+3C00
+ENDCHAR
+STARTCHAR uni1E0F
+ENCODING 7695
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+03
+03
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+00
+3C
+ENDCHAR
+STARTCHAR uni1E10
+ENCODING 7696
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 12 2 -2
+BITMAP
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+0800
+3000
+ENDCHAR
+STARTCHAR uni1E11
+ENCODING 7697
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+03
+03
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+08
+30
+ENDCHAR
+STARTCHAR uni1E12
+ENCODING 7698
+SWIDTH 819 0
+DWIDTH 12 0
+BBX 9 13 2 -3
+BITMAP
+FE00
+C300
+C180
+C180
+C180
+C180
+C180
+C180
+C300
+FE00
+0000
+1800
+2C00
+ENDCHAR
+STARTCHAR uni1E13
+ENCODING 7699
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 14 1 -3
+BITMAP
+03
+03
+03
+3F
+63
+C3
+C3
+C3
+C3
+67
+3B
+00
+18
+2C
+ENDCHAR
+STARTCHAR uni1E14
+ENCODING 7700
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 15 1 0
+BITMAP
+E0
+38
+00
+78
+00
+7E
+60
+60
+60
+7C
+60
+60
+60
+60
+7E
+ENDCHAR
+STARTCHAR uni1E15
+ENCODING 7701
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+70
+1C
+00
+3C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni1E16
+ENCODING 7702
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 15 2 0
+BITMAP
+1C
+70
+00
+F0
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR uni1E17
+ENCODING 7703
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+0E
+38
+00
+3C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni1E18
+ENCODING 7704
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 -3
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+00
+60
+B0
+ENDCHAR
+STARTCHAR uni1E19
+ENCODING 7705
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 -3
+BITMAP
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+00
+30
+58
+ENDCHAR
+STARTCHAR uni1E1A
+ENCODING 7706
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 -3
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+00
+68
+B0
+ENDCHAR
+STARTCHAR uni1E1B
+ENCODING 7707
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 -3
+BITMAP
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+00
+34
+58
+ENDCHAR
+STARTCHAR uni1E1C
+ENCODING 7708
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 15 1 -2
+BITMAP
+84
+78
+00
+7E
+60
+60
+60
+7C
+60
+60
+60
+60
+7E
+10
+60
+ENDCHAR
+STARTCHAR uni1E1D
+ENCODING 7709
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+42
+3C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+10
+60
+ENDCHAR
+STARTCHAR uni1E1E
+ENCODING 7710
+SWIDTH 602 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+60
+60
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E1F
+ENCODING 7711
+SWIDTH 461 0
+DWIDTH 7 0
+BBX 7 14 0 0
+BITMAP
+18
+18
+00
+1E
+30
+30
+FE
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR uni1E20
+ENCODING 7712
+SWIDTH 759 0
+DWIDTH 11 0
+BBX 8 12 2 0
+BITMAP
+3C
+00
+3E
+63
+C0
+C0
+C0
+C3
+C3
+C3
+63
+3F
+ENDCHAR
+STARTCHAR uni1E21
+ENCODING 7713
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+3C
+00
+3F
+63
+C3
+C3
+C3
+67
+3B
+03
+C6
+7C
+ENDCHAR
+STARTCHAR uni1E22
+ENCODING 7714
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+18
+18
+00
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E23
+ENCODING 7715
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+60
+60
+00
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E24
+ENCODING 7716
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E25
+ENCODING 7717
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 -3
+BITMAP
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E26
+ENCODING 7718
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+24
+24
+00
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E27
+ENCODING 7719
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+90
+90
+00
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E28
+ENCODING 7720
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 12 2 -2
+BITMAP
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+08
+30
+ENDCHAR
+STARTCHAR uni1E29
+ENCODING 7721
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+08
+30
+ENDCHAR
+STARTCHAR uni1E2A
+ENCODING 7722
+SWIDTH 813 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C3
+C3
+C3
+FF
+C3
+C3
+C3
+C3
+C3
+00
+42
+3C
+ENDCHAR
+STARTCHAR uni1E2B
+ENCODING 7723
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 -3
+BITMAP
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+42
+3C
+ENDCHAR
+STARTCHAR uni1E2C
+ENCODING 7724
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 5 13 0 -3
+BITMAP
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+00
+68
+B0
+ENDCHAR
+STARTCHAR uni1E2D
+ENCODING 7725
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 5 14 -1 -3
+BITMAP
+30
+30
+00
+30
+30
+30
+30
+30
+30
+30
+30
+00
+68
+B0
+ENDCHAR
+STARTCHAR uni1E2E
+ENCODING 7726
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 5 16 1 0
+BITMAP
+38
+E0
+00
+90
+90
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni1E2F
+ENCODING 7727
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 5 14 0 0
+BITMAP
+38
+E0
+00
+90
+90
+00
+60
+60
+60
+60
+60
+60
+60
+60
+ENDCHAR
+STARTCHAR uni1E30
+ENCODING 7728
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+0E
+38
+00
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E31
+ENCODING 7729
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+38
+E0
+00
+C0
+C0
+C0
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+ENDCHAR
+STARTCHAR uni1E32
+ENCODING 7730
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E33
+ENCODING 7731
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 14 1 -3
+BITMAP
+C0
+C0
+C0
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E34
+ENCODING 7732
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 12 2 -2
+BITMAP
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+00
+3C
+ENDCHAR
+STARTCHAR uni1E35
+ENCODING 7733
+SWIDTH 681 0
+DWIDTH 9 0
+BBX 8 13 1 -2
+BITMAP
+C0
+C0
+C0
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C7
+00
+3C
+ENDCHAR
+STARTCHAR uni1E36
+ENCODING 7734
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 13 2 -3
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1E37
+ENCODING 7735
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 2 14 1 -3
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+00
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E38
+ENCODING 7736
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 15 2 -3
+BITMAP
+F0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1E39
+ENCODING 7737
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 16 0 -3
+BITMAP
+F0
+00
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1E3A
+ENCODING 7738
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 12 2 -2
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+00
+F0
+ENDCHAR
+STARTCHAR uni1E3B
+ENCODING 7739
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 13 0 -2
+BITMAP
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+00
+F0
+ENDCHAR
+STARTCHAR uni1E3C
+ENCODING 7740
+SWIDTH 620 0
+DWIDTH 9 0
+BBX 6 13 2 -3
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+FC
+00
+60
+B0
+ENDCHAR
+STARTCHAR uni1E3D
+ENCODING 7741
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 4 14 0 -3
+BITMAP
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+60
+00
+60
+B0
+ENDCHAR
+STARTCHAR uni1E3E
+ENCODING 7742
+SWIDTH 940 0
+DWIDTH 15 0
+BBX 11 13 2 0
+BITMAP
+0380
+0E00
+0000
+E0E0
+E0E0
+B160
+B160
+B160
+9A60
+9A60
+8C60
+8C60
+8060
+ENDCHAR
+STARTCHAR uni1E3F
+ENCODING 7743
+SWIDTH 1006 0
+DWIDTH 14 0
+BBX 12 11 1 0
+BITMAP
+0380
+0E00
+0000
+DDE0
+EF70
+C630
+C630
+C630
+C630
+C630
+C630
+ENDCHAR
+STARTCHAR uni1E40
+ENCODING 7744
+SWIDTH 940 0
+DWIDTH 15 0
+BBX 11 13 2 0
+BITMAP
+0600
+0600
+0000
+E0E0
+E0E0
+B160
+B160
+B160
+9A60
+9A60
+8C60
+8C60
+8060
+ENDCHAR
+STARTCHAR uni1E41
+ENCODING 7745
+SWIDTH 1006 0
+DWIDTH 14 0
+BBX 12 11 1 0
+BITMAP
+0600
+0600
+0000
+DDE0
+EF70
+C630
+C630
+C630
+C630
+C630
+C630
+ENDCHAR
+STARTCHAR uni1E42
+ENCODING 7746
+SWIDTH 940 0
+DWIDTH 15 0
+BBX 11 13 2 -3
+BITMAP
+E0E0
+E0E0
+B160
+B160
+B160
+9A60
+9A60
+8C60
+8C60
+8060
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E43
+ENCODING 7747
+SWIDTH 1006 0
+DWIDTH 14 0
+BBX 12 11 1 -3
+BITMAP
+DDE0
+EF70
+C630
+C630
+C630
+C630
+C630
+C630
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E44
+ENCODING 7748
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 0
+BITMAP
+30
+30
+00
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR uni1E45
+ENCODING 7749
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 0
+BITMAP
+18
+18
+00
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E46
+ENCODING 7750
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+00
+0C
+0C
+ENDCHAR
+STARTCHAR uni1E47
+ENCODING 7751
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E48
+ENCODING 7752
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 12 2 -2
+BITMAP
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+00
+1E
+ENDCHAR
+STARTCHAR uni1E49
+ENCODING 7753
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 10 1 -2
+BITMAP
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+3C
+ENDCHAR
+STARTCHAR uni1E4A
+ENCODING 7754
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+E1
+E1
+B1
+B1
+99
+99
+8D
+8D
+87
+87
+00
+0C
+16
+ENDCHAR
+STARTCHAR uni1E4B
+ENCODING 7755
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+18
+2C
+ENDCHAR
+STARTCHAR uni1E4C
+ENCODING 7756
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 16 1 0
+BITMAP
+0700
+1C00
+0000
+0D00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1E4D
+ENCODING 7757
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+0E
+38
+00
+34
+58
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1E4E
+ENCODING 7758
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 16 1 0
+BITMAP
+1200
+1200
+0000
+0D00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1E4F
+ENCODING 7759
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+24
+24
+00
+34
+58
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1E50
+ENCODING 7760
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 15 1 0
+BITMAP
+3800
+0E00
+0000
+1E00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1E51
+ENCODING 7761
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+70
+1C
+00
+3C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1E52
+ENCODING 7762
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 15 1 0
+BITMAP
+0700
+1C00
+0000
+1E00
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1E53
+ENCODING 7763
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+0E
+38
+00
+3C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1E54
+ENCODING 7764
+SWIDTH 657 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+1C
+70
+00
+F8
+CC
+CC
+CC
+CC
+F8
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E55
+ENCODING 7765
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+0E
+38
+00
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E56
+ENCODING 7766
+SWIDTH 657 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+30
+30
+00
+F8
+CC
+CC
+CC
+CC
+F8
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E57
+ENCODING 7767
+SWIDTH 696 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+18
+18
+00
+DC
+E6
+C3
+C3
+C3
+C3
+C6
+FC
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E58
+ENCODING 7768
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 13 2 0
+BITMAP
+18
+18
+00
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni1E59
+ENCODING 7769
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 11 2 0
+BITMAP
+60
+60
+00
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni1E5A
+ENCODING 7770
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 13 2 -3
+BITMAP
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E5B
+ENCODING 7771
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 11 2 -3
+BITMAP
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1E5C
+ENCODING 7772
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 15 2 -3
+BITMAP
+78
+00
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E5D
+ENCODING 7773
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 13 2 -3
+BITMAP
+F0
+00
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1E5E
+ENCODING 7774
+SWIDTH 734 0
+DWIDTH 11 0
+BBX 8 12 2 -2
+BITMAP
+FC
+C6
+C6
+C4
+CC
+F8
+CC
+C6
+C3
+C3
+00
+3C
+ENDCHAR
+STARTCHAR uni1E5F
+ENCODING 7775
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 5 10 2 -2
+BITMAP
+D8
+D8
+E0
+C0
+C0
+C0
+C0
+C0
+00
+F0
+ENDCHAR
+STARTCHAR uni1E60
+ENCODING 7776
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+30
+30
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR uni1E61
+ENCODING 7777
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 11 1 0
+BITMAP
+30
+30
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR uni1E62
+ENCODING 7778
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 13 1 -3
+BITMAP
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E63
+ENCODING 7779
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 11 1 -3
+BITMAP
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E64
+ENCODING 7780
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 16 1 0
+BITMAP
+18
+18
+00
+1C
+70
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR uni1E65
+ENCODING 7781
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 14 1 0
+BITMAP
+30
+30
+00
+1C
+70
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR uni1E66
+ENCODING 7782
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 16 1 0
+BITMAP
+18
+18
+00
+2C
+18
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+ENDCHAR
+STARTCHAR uni1E67
+ENCODING 7783
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 14 1 0
+BITMAP
+30
+30
+00
+58
+30
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+ENDCHAR
+STARTCHAR uni1E68
+ENCODING 7784
+SWIDTH 594 0
+DWIDTH 9 0
+BBX 7 16 1 -3
+BITMAP
+30
+30
+00
+7C
+C6
+C0
+E0
+78
+3C
+0E
+06
+C6
+7C
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E69
+ENCODING 7785
+SWIDTH 622 0
+DWIDTH 8 0
+BBX 6 14 1 -3
+BITMAP
+30
+30
+00
+7C
+C0
+C0
+F0
+3C
+0C
+0C
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E6A
+ENCODING 7786
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+18
+18
+00
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR uni1E6B
+ENCODING 7787
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 13 1 0
+BITMAP
+60
+60
+00
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+ENDCHAR
+STARTCHAR uni1E6C
+ENCODING 7788
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 13 1 -3
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E6D
+ENCODING 7789
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 13 1 -3
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E6E
+ENCODING 7790
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+00
+3C
+ENDCHAR
+STARTCHAR uni1E6F
+ENCODING 7791
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 12 1 -2
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+00
+78
+ENDCHAR
+STARTCHAR uni1E70
+ENCODING 7792
+SWIDTH 735 0
+DWIDTH 10 0
+BBX 8 13 1 -3
+BITMAP
+FF
+18
+18
+18
+18
+18
+18
+18
+18
+18
+00
+18
+2C
+ENDCHAR
+STARTCHAR uni1E71
+ENCODING 7793
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 13 1 -3
+BITMAP
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+00
+30
+58
+ENDCHAR
+STARTCHAR uni1E72
+ENCODING 7794
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+00
+24
+24
+ENDCHAR
+STARTCHAR uni1E73
+ENCODING 7795
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+00
+24
+24
+ENDCHAR
+STARTCHAR uni1E74
+ENCODING 7796
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+00
+34
+58
+ENDCHAR
+STARTCHAR uni1E75
+ENCODING 7797
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+00
+34
+58
+ENDCHAR
+STARTCHAR uni1E76
+ENCODING 7798
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+00
+18
+2C
+ENDCHAR
+STARTCHAR uni1E77
+ENCODING 7799
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+00
+18
+2C
+ENDCHAR
+STARTCHAR uni1E78
+ENCODING 7800
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 16 2 0
+BITMAP
+0E
+38
+00
+1A
+2C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1E79
+ENCODING 7801
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+07
+1C
+00
+1A
+2C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni1E7A
+ENCODING 7802
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 15 2 0
+BITMAP
+24
+24
+00
+3C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1E7B
+ENCODING 7803
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+24
+24
+00
+3C
+00
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+ENDCHAR
+STARTCHAR uni1E7C
+ENCODING 7804
+SWIDTH 735 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1A00
+2C00
+0000
+C180
+C180
+C180
+6100
+6300
+6300
+3200
+3600
+1C00
+1C00
+ENDCHAR
+STARTCHAR uni1E7D
+ENCODING 7805
+SWIDTH 663 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+34
+58
+00
+C6
+C6
+C6
+C6
+64
+68
+38
+38
+ENDCHAR
+STARTCHAR uni1E7E
+ENCODING 7806
+SWIDTH 735 0
+DWIDTH 11 0
+BBX 9 13 1 -3
+BITMAP
+C180
+C180
+C180
+6100
+6300
+6300
+3200
+3600
+1C00
+1C00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E7F
+ENCODING 7807
+SWIDTH 663 0
+DWIDTH 9 0
+BBX 7 11 1 -3
+BITMAP
+C6
+C6
+C6
+C6
+64
+68
+38
+38
+00
+30
+30
+ENDCHAR
+STARTCHAR Wgrave
+ENCODING 7808
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+3800
+0E00
+0000
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR wgrave
+ENCODING 7809
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 11 1 0
+BITMAP
+3800
+0E00
+0000
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR Wacute
+ENCODING 7810
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+0380
+0E00
+0000
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR wacute
+ENCODING 7811
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 11 1 0
+BITMAP
+0380
+0E00
+0000
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR Wdieresis
+ENCODING 7812
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+0900
+0900
+0000
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR wdieresis
+ENCODING 7813
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 11 1 0
+BITMAP
+0900
+0900
+0000
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR uni1E86
+ENCODING 7814
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 13 1 0
+BITMAP
+0600
+0600
+0000
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR uni1E87
+ENCODING 7815
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 11 1 0
+BITMAP
+0600
+0600
+0000
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR uni1E88
+ENCODING 7816
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 13 1 -3
+BITMAP
+C060
+C060
+C660
+C660
+6640
+6B40
+6B40
+7BC0
+3180
+3180
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E89
+ENCODING 7817
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 11 1 -3
+BITMAP
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E8A
+ENCODING 7818
+SWIDTH 699 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+18
+18
+00
+C6
+C6
+6C
+6C
+38
+38
+6C
+6C
+C6
+C6
+ENDCHAR
+STARTCHAR uni1E8B
+ENCODING 7819
+SWIDTH 568 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+30
+30
+00
+C6
+C6
+64
+38
+38
+4C
+C6
+C6
+ENDCHAR
+STARTCHAR uni1E8C
+ENCODING 7820
+SWIDTH 699 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+24
+24
+00
+C6
+C6
+6C
+6C
+38
+38
+6C
+6C
+C6
+C6
+ENDCHAR
+STARTCHAR uni1E8D
+ENCODING 7821
+SWIDTH 568 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+48
+48
+00
+C6
+C6
+64
+38
+38
+4C
+C6
+C6
+ENDCHAR
+STARTCHAR uni1E8E
+ENCODING 7822
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+18
+18
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR uni1E8F
+ENCODING 7823
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+18
+18
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR uni1E90
+ENCODING 7824
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 13 1 0
+BITMAP
+18
+2C
+00
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+ENDCHAR
+STARTCHAR uni1E91
+ENCODING 7825
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+18
+2C
+00
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+ENDCHAR
+STARTCHAR uni1E92
+ENCODING 7826
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 13 1 -3
+BITMAP
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E93
+ENCODING 7827
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 11 1 -3
+BITMAP
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E94
+ENCODING 7828
+SWIDTH 675 0
+DWIDTH 9 0
+BBX 7 12 1 -2
+BITMAP
+FE
+06
+0C
+1C
+18
+30
+70
+60
+C0
+FE
+00
+78
+ENDCHAR
+STARTCHAR uni1E95
+ENCODING 7829
+SWIDTH 608 0
+DWIDTH 9 0
+BBX 7 10 1 -2
+BITMAP
+FE
+06
+0C
+18
+30
+60
+C0
+FE
+00
+78
+ENDCHAR
+STARTCHAR uni1E96
+ENCODING 7830
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 13 1 -2
+BITMAP
+C0
+C0
+C0
+DE
+E7
+C3
+C3
+C3
+C3
+C3
+C3
+00
+3C
+ENDCHAR
+STARTCHAR uni1E97
+ENCODING 7831
+SWIDTH 436 0
+DWIDTH 7 0
+BBX 5 13 1 0
+BITMAP
+90
+90
+00
+60
+60
+F8
+60
+60
+60
+60
+60
+60
+38
+ENDCHAR
+STARTCHAR uni1E98
+ENCODING 7832
+SWIDTH 885 0
+DWIDTH 13 0
+BBX 11 12 1 0
+BITMAP
+0600
+0B00
+0600
+0000
+C060
+C460
+C460
+6EC0
+6AC0
+7B80
+3180
+3180
+ENDCHAR
+STARTCHAR uni1E99
+ENCODING 7833
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 14 1 -2
+BITMAP
+18
+2C
+18
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR uni1EA0
+ENCODING 7840
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 -3
+BITMAP
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EA1
+ENCODING 7841
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 11 1 -3
+BITMAP
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EA4
+ENCODING 7844
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+0700
+1C00
+0000
+1C00
+2600
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni1EA5
+ENCODING 7845
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+0E
+38
+00
+18
+2C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni1EA6
+ENCODING 7846
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+7000
+1C00
+0000
+1C00
+2600
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni1EA7
+ENCODING 7847
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+70
+1C
+00
+18
+2C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni1EAA
+ENCODING 7850
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+1A00
+2C00
+0000
+1C00
+2600
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni1EAB
+ENCODING 7851
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+1A
+2C
+00
+18
+2C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni1EAC
+ENCODING 7852
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 -3
+BITMAP
+0C00
+1600
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EAD
+ENCODING 7853
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 -3
+BITMAP
+18
+2C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EAE
+ENCODING 7854
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+0700
+1C00
+0000
+2100
+1E00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni1EAF
+ENCODING 7855
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+0E
+38
+00
+42
+3C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni1EB0
+ENCODING 7856
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+3800
+0E00
+0000
+2100
+1E00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni1EB1
+ENCODING 7857
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+70
+1C
+00
+42
+3C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni1EB4
+ENCODING 7860
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 0
+BITMAP
+1A00
+2C00
+0000
+2100
+1E00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni1EB5
+ENCODING 7861
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 0
+BITMAP
+1A
+2C
+00
+42
+3C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+ENDCHAR
+STARTCHAR uni1EB6
+ENCODING 7862
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 16 1 -3
+BITMAP
+2100
+1E00
+0000
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EB7
+ENCODING 7863
+SWIDTH 623 0
+DWIDTH 9 0
+BBX 8 14 1 -3
+BITMAP
+42
+3C
+00
+7C
+06
+06
+7E
+C6
+C6
+CE
+77
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EB8
+ENCODING 7864
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 -3
+BITMAP
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1EB9
+ENCODING 7865
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 -3
+BITMAP
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1EBC
+ENCODING 7868
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 13 2 0
+BITMAP
+68
+B0
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR uni1EBD
+ENCODING 7869
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 11 1 0
+BITMAP
+34
+58
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni1EBE
+ENCODING 7870
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 16 2 0
+BITMAP
+1C
+70
+00
+30
+58
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR uni1EBF
+ENCODING 7871
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 14 1 0
+BITMAP
+0E
+38
+00
+18
+2C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni1EC0
+ENCODING 7872
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 16 2 0
+BITMAP
+E0
+38
+00
+30
+58
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR uni1EC1
+ENCODING 7873
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 14 1 0
+BITMAP
+70
+1C
+00
+18
+2C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni1EC4
+ENCODING 7876
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 16 2 0
+BITMAP
+34
+58
+00
+30
+58
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+ENDCHAR
+STARTCHAR uni1EC5
+ENCODING 7877
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 14 1 0
+BITMAP
+1A
+2C
+00
+18
+2C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+ENDCHAR
+STARTCHAR uni1EC6
+ENCODING 7878
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 16 2 -3
+BITMAP
+60
+B0
+00
+FC
+C0
+C0
+C0
+F8
+C0
+C0
+C0
+C0
+FC
+00
+60
+60
+ENDCHAR
+STARTCHAR uni1EC7
+ENCODING 7879
+SWIDTH 614 0
+DWIDTH 9 0
+BBX 7 14 1 -3
+BITMAP
+18
+2C
+00
+3C
+66
+C6
+FE
+C0
+C0
+62
+3C
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1ECA
+ENCODING 7882
+SWIDTH 361 0
+DWIDTH 6 0
+BBX 2 13 2 -3
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+00
+C0
+C0
+ENDCHAR
+STARTCHAR uni1ECB
+ENCODING 7883
+SWIDTH 361 0
+DWIDTH 4 0
+BBX 2 14 1 -3
+BITMAP
+C0
+C0
+00
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+00
+C0
+C0
+ENDCHAR
+STARTCHAR uni1ECC
+ENCODING 7884
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 13 1 -3
+BITMAP
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1ECD
+ENCODING 7885
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1ED0
+ENCODING 7888
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 16 1 0
+BITMAP
+0700
+1C00
+0000
+0C00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1ED1
+ENCODING 7889
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+0E
+38
+00
+18
+2C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1ED2
+ENCODING 7890
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 16 1 0
+BITMAP
+3800
+0E00
+0000
+0C00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1ED3
+ENCODING 7891
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+70
+1C
+00
+18
+2C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1ED6
+ENCODING 7894
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 16 1 0
+BITMAP
+0D00
+1600
+0000
+0C00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1ED7
+ENCODING 7895
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 14 1 0
+BITMAP
+1A
+2C
+00
+18
+2C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+ENDCHAR
+STARTCHAR uni1ED8
+ENCODING 7896
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 10 16 1 -3
+BITMAP
+0C00
+1600
+0000
+3F00
+6180
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1ED9
+ENCODING 7897
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 8 14 1 -3
+BITMAP
+18
+2C
+00
+3C
+66
+C3
+C3
+C3
+C3
+66
+3C
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EDA
+ENCODING 7898
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 11 13 1 0
+BITMAP
+0380
+0E00
+0000
+3F60
+61E0
+C0E0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1EDB
+ENCODING 7899
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 10 11 1 0
+BITMAP
+0380
+0E00
+0000
+3CC0
+66C0
+C340
+C380
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni1EDC
+ENCODING 7900
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 11 13 1 0
+BITMAP
+1C00
+0700
+0000
+3F60
+61E0
+C0E0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1EDD
+ENCODING 7901
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 10 11 1 0
+BITMAP
+3800
+0E00
+0000
+3CC0
+66C0
+C340
+C380
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni1EE0
+ENCODING 7904
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 11 13 1 0
+BITMAP
+0680
+0B00
+0000
+3F60
+61E0
+C0E0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+ENDCHAR
+STARTCHAR uni1EE1
+ENCODING 7905
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 10 11 1 0
+BITMAP
+0D00
+1600
+0000
+3CC0
+66C0
+C340
+C380
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni1EE2
+ENCODING 7906
+SWIDTH 855 0
+DWIDTH 12 0
+BBX 11 13 1 -3
+BITMAP
+3F60
+61E0
+C0E0
+C0C0
+C0C0
+C0C0
+C0C0
+C0C0
+6180
+3F00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EE3
+ENCODING 7907
+SWIDTH 675 0
+DWIDTH 10 0
+BBX 10 11 1 -3
+BITMAP
+3CC0
+66C0
+C340
+C380
+C300
+C300
+6600
+3C00
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR uni1EE4
+ENCODING 7908
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 13 2 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+C3
+66
+3C
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EE5
+ENCODING 7909
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 8 11 1 -3
+BITMAP
+C3
+C3
+C3
+C3
+C3
+C3
+E7
+7B
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EE8
+ENCODING 7912
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 10 13 2 0
+BITMAP
+0380
+0E00
+0000
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni1EE9
+ENCODING 7913
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 10 11 1 0
+BITMAP
+0380
+0E00
+0000
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+E700
+7B00
+ENDCHAR
+STARTCHAR uni1EEA
+ENCODING 7914
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 10 13 2 0
+BITMAP
+3800
+0E00
+0000
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni1EEB
+ENCODING 7915
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 10 11 1 0
+BITMAP
+3800
+0E00
+0000
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+E700
+7B00
+ENDCHAR
+STARTCHAR uni1EEE
+ENCODING 7918
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 10 13 2 0
+BITMAP
+0D00
+1600
+0000
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+C300
+C300
+6600
+3C00
+ENDCHAR
+STARTCHAR uni1EEF
+ENCODING 7919
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 10 11 1 0
+BITMAP
+0D00
+1600
+0000
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+E700
+7B00
+ENDCHAR
+STARTCHAR uni1EF0
+ENCODING 7920
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 10 13 2 -3
+BITMAP
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+C300
+C300
+6600
+3C00
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR uni1EF1
+ENCODING 7921
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 10 11 1 -3
+BITMAP
+C3C0
+C3C0
+C340
+C380
+C300
+C300
+E700
+7B00
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR Ygrave
+ENCODING 7922
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+70
+1C
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR ygrave
+ENCODING 7923
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+E0
+38
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR uni1EF4
+ENCODING 7924
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 -3
+BITMAP
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1EF5
+ENCODING 7925
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -5
+BITMAP
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1EF8
+ENCODING 7928
+SWIDTH 738 0
+DWIDTH 10 0
+BBX 8 13 1 0
+BITMAP
+1A
+2C
+00
+C3
+C3
+62
+66
+34
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR uni1EF9
+ENCODING 7929
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 7 13 1 -2
+BITMAP
+34
+58
+00
+C6
+C6
+C6
+C6
+6C
+68
+38
+30
+60
+E0
+ENDCHAR
+STARTCHAR uni2000
+ENCODING 8192
+SWIDTH 500 0
+DWIDTH 7 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2001
+ENCODING 8193
+SWIDTH 1000 0
+DWIDTH 15 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2002
+ENCODING 8194
+SWIDTH 500 0
+DWIDTH 7 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2003
+ENCODING 8195
+SWIDTH 1000 0
+DWIDTH 15 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2004
+ENCODING 8196
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2005
+ENCODING 8197
+SWIDTH 250 0
+DWIDTH 4 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2006
+ENCODING 8198
+SWIDTH 167 0
+DWIDTH 2 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2007
+ENCODING 8199
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2008
+ENCODING 8200
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2009
+ENCODING 8201
+SWIDTH 200 0
+DWIDTH 3 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni200A
+ENCODING 8202
+SWIDTH 100 0
+DWIDTH 1 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni200B
+ENCODING 8203
+SWIDTH 0 0
+DWIDTH 0 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2010
+ENCODING 8208
+SWIDTH 289 0
+DWIDTH 5 0
+BBX 3 1 1 4
+BITMAP
+E0
+ENDCHAR
+STARTCHAR uni2011
+ENCODING 8209
+SWIDTH 289 0
+DWIDTH 5 0
+BBX 3 1 1 4
+BITMAP
+E0
+ENDCHAR
+STARTCHAR figuredash
+ENCODING 8210
+SWIDTH 500 0
+DWIDTH 7 0
+BBX 5 1 1 4
+BITMAP
+F8
+ENDCHAR
+STARTCHAR endash
+ENCODING 8211
+SWIDTH 500 0
+DWIDTH 7 0
+BBX 5 1 1 4
+BITMAP
+F8
+ENDCHAR
+STARTCHAR emdash
+ENCODING 8212
+SWIDTH 1000 0
+DWIDTH 15 0
+BBX 13 1 1 4
+BITMAP
+FFF8
+ENDCHAR
+STARTCHAR afii00208
+ENCODING 8213
+SWIDTH 1000 0
+DWIDTH 15 0
+BBX 13 1 1 4
+BITMAP
+FFF8
+ENDCHAR
+STARTCHAR quoteleft
+ENCODING 8216
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+40
+80
+C0
+C0
+ENDCHAR
+STARTCHAR quoteright
+ENCODING 8217
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR quotesinglbase
+ENCODING 8218
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 -2
+BITMAP
+C0
+C0
+40
+80
+ENDCHAR
+STARTCHAR quotereversed
+ENCODING 8219
+SWIDTH 265 0
+DWIDTH 4 0
+BBX 2 4 1 7
+BITMAP
+C0
+C0
+80
+40
+ENDCHAR
+STARTCHAR quotedblleft
+ENCODING 8220
+SWIDTH 530 0
+DWIDTH 7 0
+BBX 5 4 1 7
+BITMAP
+48
+90
+D8
+D8
+ENDCHAR
+STARTCHAR quotedblright
+ENCODING 8221
+SWIDTH 530 0
+DWIDTH 7 0
+BBX 5 4 1 7
+BITMAP
+D8
+D8
+48
+90
+ENDCHAR
+STARTCHAR quotedblbase
+ENCODING 8222
+SWIDTH 530 0
+DWIDTH 7 0
+BBX 5 4 1 -2
+BITMAP
+D8
+D8
+48
+90
+ENDCHAR
+STARTCHAR uni201F
+ENCODING 8223
+SWIDTH 530 0
+DWIDTH 7 0
+BBX 5 4 1 7
+BITMAP
+D8
+D8
+90
+48
+ENDCHAR
+STARTCHAR dagger
+ENCODING 8224
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 6 11 2 -1
+BITMAP
+30
+30
+30
+FC
+30
+30
+30
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR daggerdbl
+ENCODING 8225
+SWIDTH 693 0
+DWIDTH 10 0
+BBX 6 11 2 -1
+BITMAP
+30
+30
+30
+FC
+30
+30
+30
+FC
+30
+30
+30
+ENDCHAR
+STARTCHAR bullet
+ENCODING 8226
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 4 4 3 2
+BITMAP
+F0
+F0
+F0
+F0
+ENDCHAR
+STARTCHAR ellipsis
+ENCODING 8230
+SWIDTH 1000 0
+DWIDTH 10 0
+BBX 6 2 2 0
+BITMAP
+CC
+CC
+ENDCHAR
+STARTCHAR perthousand
+ENCODING 8240
+SWIDTH 1313 0
+DWIDTH 18 0
+BBX 16 10 1 0
+BITMAP
+7000
+D980
+DB00
+7200
+0400
+0800
+138E
+36DB
+66DB
+038E
+ENDCHAR
+STARTCHAR guilsinglleft
+ENCODING 8249
+SWIDTH 361 0
+DWIDTH 5 0
+BBX 4 5 0 2
+BITMAP
+30
+60
+C0
+60
+30
+ENDCHAR
+STARTCHAR guilsinglright
+ENCODING 8250
+SWIDTH 361 0
+DWIDTH 5 0
+BBX 4 5 1 2
+BITMAP
+C0
+60
+30
+60
+C0
+ENDCHAR
+STARTCHAR fraction
+ENCODING 8260
+SWIDTH 93 0
+DWIDTH 4 0
+BBX 6 10 -1 0
+BITMAP
+0C
+0C
+18
+18
+30
+30
+60
+60
+C0
+C0
+ENDCHAR
+STARTCHAR oneinferior
+ENCODING 8321
+SWIDTH 536 0
+DWIDTH 7 0
+BBX 4 6 1 -2
+BITMAP
+30
+F0
+30
+30
+30
+30
+ENDCHAR
+STARTCHAR twoinferior
+ENCODING 8322
+SWIDTH 536 0
+DWIDTH 7 0
+BBX 5 6 1 -2
+BITMAP
+F0
+18
+18
+60
+C0
+F8
+ENDCHAR
+STARTCHAR threeinferior
+ENCODING 8323
+SWIDTH 536 0
+DWIDTH 7 0
+BBX 5 6 1 -2
+BITMAP
+F0
+18
+70
+18
+18
+F0
+ENDCHAR
+STARTCHAR uni20A5
+ENCODING 8357
+SWIDTH 1006 0
+DWIDTH 14 0
+BBX 12 12 1 -2
+BITMAP
+00C0
+0180
+DDE0
+EF70
+C730
+C630
+C630
+CE30
+CE30
+DE30
+1800
+3000
+ENDCHAR
+STARTCHAR uni20A6
+ENCODING 8358
+SWIDTH 783 0
+DWIDTH 12 0
+BBX 8 10 2 0
+BITMAP
+E1
+E1
+B1
+FF
+99
+FF
+8D
+8D
+87
+87
+ENDCHAR
+STARTCHAR uni20A9
+ENCODING 8361
+SWIDTH 940 0
+DWIDTH 13 0
+BBX 11 10 1 0
+BITMAP
+C060
+C060
+C660
+FFE0
+6640
+7FC0
+6B40
+7BC0
+3180
+3180
+ENDCHAR
+STARTCHAR Euro
+ENCODING 8364
+SWIDTH 726 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+1F00
+3180
+6000
+FE00
+6000
+FE00
+6000
+6000
+3180
+1F00
+ENDCHAR
+STARTCHAR uni20AD
+ENCODING 8365
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+C3
+C6
+CC
+D8
+FF
+D8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni2103
+ENCODING 8451
+SWIDTH 955 0
+DWIDTH 15 0
+BBX 14 10 0 0
+BITMAP
+60F8
+918C
+6300
+0300
+0300
+0300
+0300
+0300
+018C
+00F8
+ENDCHAR
+STARTCHAR uni2109
+ENCODING 8457
+SWIDTH 831 0
+DWIDTH 13 0
+BBX 12 10 0 0
+BITMAP
+63F0
+9300
+6300
+0300
+03E0
+0300
+0300
+0300
+0300
+0300
+ENDCHAR
+STARTCHAR trademark
+ENCODING 8482
+SWIDTH 901 0
+DWIDTH 13 0
+BBX 10 5 1 5
+BITMAP
+FEC0
+2540
+2540
+2540
+2440
+ENDCHAR
+STARTCHAR uni212A
+ENCODING 8490
+SWIDTH 753 0
+DWIDTH 11 0
+BBX 8 10 2 0
+BITMAP
+C3
+C6
+CC
+D8
+F0
+D8
+CC
+C6
+C3
+C3
+ENDCHAR
+STARTCHAR uni212B
+ENCODING 8491
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 13 1 0
+BITMAP
+1C00
+2600
+1C00
+1C00
+1C00
+2600
+2600
+6300
+4300
+FF00
+C180
+C180
+C180
+ENDCHAR
+STARTCHAR uni2132
+ENCODING 8498
+SWIDTH 602 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+0C
+0C
+0C
+0C
+0C
+7C
+0C
+0C
+0C
+FC
+ENDCHAR
+STARTCHAR universal
+ENCODING 8704
+SWIDTH 773 0
+DWIDTH 11 0
+BBX 9 10 1 0
+BITMAP
+C180
+C180
+C180
+FF00
+4300
+6300
+2600
+2600
+1C00
+1C00
+ENDCHAR
+STARTCHAR existential
+ENCODING 8707
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 6 10 2 0
+BITMAP
+FC
+0C
+0C
+0C
+7C
+0C
+0C
+0C
+0C
+FC
+ENDCHAR
+STARTCHAR uni2204
+ENCODING 8708
+SWIDTH 645 0
+DWIDTH 9 0
+BBX 8 12 1 -1
+BITMAP
+03
+7E
+06
+0E
+0E
+3E
+1E
+36
+36
+66
+7E
+C0
+ENDCHAR
+STARTCHAR minus
+ENCODING 8722
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 1 1 4
+BITMAP
+FE
+ENDCHAR
+STARTCHAR fraction
+ENCODING 8725
+SWIDTH 93 0
+DWIDTH 4 0
+BBX 6 10 -1 0
+BITMAP
+0C
+0C
+18
+18
+30
+30
+60
+60
+C0
+C0
+ENDCHAR
+STARTCHAR periodcentered
+ENCODING 8729
+SWIDTH 343 0
+DWIDTH 10 0
+BBX 2 2 4 3
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR uni2236
+ENCODING 8758
+SWIDTH 343 0
+DWIDTH 4 0
+BBX 2 7 1 0
+BITMAP
+C0
+C0
+00
+00
+00
+C0
+C0
+ENDCHAR
+STARTCHAR uni2259
+ENCODING 8793
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 6 1 3
+BITMAP
+18
+2C
+00
+FE
+00
+FE
+ENDCHAR
+STARTCHAR uni225A
+ENCODING 8794
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 6 1 3
+BITMAP
+2C
+18
+00
+FE
+00
+FE
+ENDCHAR
+STARTCHAR notequal
+ENCODING 8800
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 12 1 -1
+BITMAP
+03
+06
+06
+0C
+0C
+FE
+18
+FE
+30
+60
+60
+C0
+ENDCHAR
+STARTCHAR equivalence
+ENCODING 8801
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 7 5 0 2
+BITMAP
+FE
+00
+FE
+00
+FE
+ENDCHAR
+STARTCHAR uni2262
+ENCODING 8802
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 12 0 -1
+BITMAP
+03
+06
+06
+0C
+FE
+18
+FE
+30
+FE
+60
+60
+C0
+ENDCHAR
+STARTCHAR lessequal
+ENCODING 8804
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 6 9 2 -1
+BITMAP
+0C
+38
+60
+C0
+60
+38
+0C
+00
+FC
+ENDCHAR
+STARTCHAR greaterequal
+ENCODING 8805
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 6 9 2 -1
+BITMAP
+C0
+70
+18
+0C
+18
+70
+C0
+00
+FC
+ENDCHAR
+STARTCHAR uni226E
+ENCODING 8814
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 12 1 -1
+BITMAP
+03
+06
+06
+0E
+1C
+38
+78
+30
+3C
+66
+60
+C0
+ENDCHAR
+STARTCHAR uni226F
+ENCODING 8815
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 12 1 -1
+BITMAP
+03
+06
+06
+6C
+3C
+1C
+1E
+3C
+38
+60
+60
+C0
+ENDCHAR
+STARTCHAR uni2270
+ENCODING 8816
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+03
+06
+06
+1C
+3C
+78
+38
+3C
+36
+60
+7E
+C0
+ENDCHAR
+STARTCHAR uni2271
+ENCODING 8817
+SWIDTH 687 0
+DWIDTH 10 0
+BBX 8 12 1 -2
+BITMAP
+03
+06
+66
+3C
+0C
+1E
+1C
+38
+70
+60
+7E
+C0
+ENDCHAR
+STARTCHAR fi
+ENCODING -1
+SWIDTH 711 0
+DWIDTH 11 0
+BBX 9 11 0 0
+BITMAP
+1D80
+3180
+3000
+FF80
+3180
+3180
+3180
+3180
+3180
+3180
+3180
+ENDCHAR
+STARTCHAR fl
+ENCODING -1
+SWIDTH 711 0
+DWIDTH 10 0
+BBX 9 11 0 0
+BITMAP
+1F80
+3180
+3180
+FD80
+3180
+3180
+3180
+3180
+3180
+3180
+3180
+ENDCHAR
+ENDFONT
--- /dev/null
+STARTFONT 2.1
+FONT -Adobe-New Century Schoolbook-Bold-R-Normal--18-180-75-75-P-113-ISO10646-1
+SIZE 18 75 75
+FONTBOUNDINGBOX 24 31 -3 -8
+COMMENT $Xorg: $
+COMMENT ISO10646-1 extension by Markus Kuhn <mkuhn@acm.org>, 2001-03-20
+COMMENT
+COMMENT +
+COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated.
+COMMENT Copyright 1988, 1994 Digital Equipment Corporation.
+COMMENT
+COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be
+COMMENT registered in certain jurisdictions.
+COMMENT Permission to use these trademarks is hereby granted only in
+COMMENT association with the images described in this file.
+COMMENT
+COMMENT Permission to use, copy, modify, distribute and sell this software
+COMMENT and its documentation for any purpose and without fee is hereby
+COMMENT granted, provided that the above copyright notices appear in all
+COMMENT copies and that both those copyright notices and this permission
+COMMENT notice appear in supporting documentation, and that the names of
+COMMENT Adobe Systems and Digital Equipment Corporation not be used in
+COMMENT advertising or publicity pertaining to distribution of the software
+COMMENT without specific, written prior permission. Adobe Systems and
+COMMENT Digital Equipment Corporation make no representations about the
+COMMENT suitability of this software for any purpose. It is provided "as
+COMMENT is" without express or implied warranty.
+COMMENT -
+STARTPROPERTIES 26
+FOUNDRY "Adobe"
+FAMILY_NAME "New Century Schoolbook"
+WEIGHT_NAME "Bold"
+SLANT "R"
+SETWIDTH_NAME "Normal"
+ADD_STYLE_NAME ""
+PIXEL_SIZE 18
+POINT_SIZE 180
+RESOLUTION_X 75
+RESOLUTION_Y 75
+SPACING "P"
+AVERAGE_WIDTH 113
+CHARSET_REGISTRY "ISO10646"
+CHARSET_ENCODING "1"
+CAP_HEIGHT 14
+X_HEIGHT 9
+FONT_ASCENT 16
+FONT_DESCENT 4
+FACE_NAME "New Century Schoolbook Bold"
+COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
+NOTICE "New Century Schoolbook is a trademark of Linotype-Hell AG and/or its subsidiaries."
+_DEC_DEVICE_FONTNAMES "PS=NewCenturySchlbk-Bold"
+DEFAULT_CHAR 0
+RELATIVE_SETWIDTH 50
+RELATIVE_WEIGHT 70
+FULL_NAME "New Century Schoolbook Bold"
+ENDPROPERTIES
+CHARS 756
+STARTCHAR char0
+ENCODING 0
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 13 13 1 0
+BITMAP
+AAA8
+0000
+8008
+0000
+8008
+0000
+8008
+0000
+8008
+0000
+8008
+0000
+AAA8
+ENDCHAR
+STARTCHAR space
+ENCODING 32
+SWIDTH 287 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclam
+ENCODING 33
+SWIDTH 296 0
+DWIDTH 6 0
+BBX 4 14 1 0
+BITMAP
+60
+F0
+F0
+F0
+F0
+F0
+60
+60
+60
+00
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR quotedbl
+ENCODING 34
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 5 5 1 9
+BITMAP
+D8
+D8
+D8
+D8
+D8
+ENDCHAR
+STARTCHAR numbersign
+ENCODING 35
+SWIDTH 574 0
+DWIDTH 12 0
+BBX 11 13 0 0
+BITMAP
+0D80
+0D80
+0D80
+7FE0
+7FE0
+1B00
+1B00
+FFC0
+FFC0
+3600
+3600
+3600
+3600
+ENDCHAR
+STARTCHAR dollar
+ENCODING 36
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 18 1 -2
+BITMAP
+0800
+0800
+3E00
+6B80
+C980
+C980
+E800
+F800
+7E00
+3F00
+0F80
+0B80
+C980
+C980
+EB80
+7F00
+0800
+0800
+ENDCHAR
+STARTCHAR percent
+ENCODING 37
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 14 14 0 0
+BITMAP
+38C0
+6740
+C4C0
+C480
+C580
+C900
+7300
+0238
+0664
+04C4
+0CC4
+08C4
+18C8
+1070
+ENDCHAR
+STARTCHAR ampersand
+ENCODING 38
+SWIDTH 852 0
+DWIDTH 17 0
+BBX 16 14 0 0
+BITMAP
+0780
+0CC0
+1840
+18C0
+1D80
+1F00
+0E3E
+3F18
+7790
+E3E0
+E1E0
+E0F1
+F1FE
+3F1C
+ENDCHAR
+STARTCHAR quotesingle
+ENCODING 39
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 2 5 1 9
+BITMAP
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR parenleft
+ENCODING 40
+SWIDTH 389 0
+DWIDTH 6 0
+BBX 5 16 1 -2
+BITMAP
+18
+30
+60
+60
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+60
+60
+30
+18
+ENDCHAR
+STARTCHAR parenright
+ENCODING 41
+SWIDTH 389 0
+DWIDTH 6 0
+BBX 5 16 0 -2
+BITMAP
+C0
+60
+30
+30
+18
+18
+18
+18
+18
+18
+18
+18
+30
+30
+60
+C0
+ENDCHAR
+STARTCHAR asterisk
+ENCODING 42
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 7 7 0 7
+BITMAP
+38
+92
+D6
+38
+D6
+92
+38
+ENDCHAR
+STARTCHAR plus
+ENCODING 43
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 10 0 0
+BITMAP
+0C00
+0C00
+0C00
+0C00
+FFC0
+FFC0
+0C00
+0C00
+0C00
+0C00
+ENDCHAR
+STARTCHAR comma
+ENCODING 44
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 4 7 0 -3
+BITMAP
+60
+F0
+F0
+70
+20
+40
+80
+ENDCHAR
+STARTCHAR hyphen
+ENCODING 45
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 5 2 0 4
+BITMAP
+F8
+F8
+ENDCHAR
+STARTCHAR period
+ENCODING 46
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 4 4 0 0
+BITMAP
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR slash
+ENCODING 47
+SWIDTH 278 0
+DWIDTH 7 0
+BBX 6 14 0 0
+BITMAP
+0C
+0C
+0C
+18
+18
+18
+30
+30
+30
+60
+60
+60
+C0
+C0
+ENDCHAR
+STARTCHAR zero
+ENCODING 48
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1C00
+7700
+6300
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+E380
+6300
+7700
+1C00
+ENDCHAR
+STARTCHAR one
+ENCODING 49
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 7 14 2 0
+BITMAP
+18
+38
+F8
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+FE
+ENDCHAR
+STARTCHAR two
+ENCODING 50
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1E00
+6700
+E380
+E380
+6380
+0380
+0700
+0700
+0E00
+1800
+3000
+6080
+FF80
+FF80
+ENDCHAR
+STARTCHAR three
+ENCODING 51
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1E00
+6700
+E380
+E380
+6380
+0300
+1C00
+0300
+0380
+6380
+E380
+E380
+6700
+3E00
+ENDCHAR
+STARTCHAR four
+ENCODING 52
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+0700
+0F00
+0F00
+1700
+1700
+2700
+2700
+4700
+4700
+8700
+FF80
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR five
+ENCODING 53
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+7F80
+7F00
+4000
+4000
+4000
+7E00
+4700
+0380
+0380
+6380
+E380
+E380
+6700
+3E00
+ENDCHAR
+STARTCHAR six
+ENCODING 54
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1F00
+7380
+6380
+E300
+E000
+EE00
+F700
+E380
+E380
+E380
+E380
+6380
+7300
+1C00
+ENDCHAR
+STARTCHAR seven
+ENCODING 55
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+FF80
+FF80
+FF80
+8300
+0600
+0600
+0C00
+0C00
+1C00
+1C00
+3800
+3800
+3800
+3800
+ENDCHAR
+STARTCHAR eight
+ENCODING 56
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1C00
+6300
+C180
+C180
+E180
+FB00
+7E00
+3F00
+4F80
+C380
+C180
+C180
+E300
+3C00
+ENDCHAR
+STARTCHAR nine
+ENCODING 57
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1C00
+6700
+E300
+E380
+E380
+E380
+E380
+7780
+3B80
+0380
+6380
+E300
+E700
+7C00
+ENDCHAR
+STARTCHAR colon
+ENCODING 58
+SWIDTH 278 0
+DWIDTH 6 0
+BBX 4 9 1 0
+BITMAP
+60
+F0
+F0
+60
+00
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR semicolon
+ENCODING 59
+SWIDTH 278 0
+DWIDTH 6 0
+BBX 4 12 1 -3
+BITMAP
+60
+F0
+F0
+60
+00
+60
+F0
+F0
+70
+20
+40
+80
+ENDCHAR
+STARTCHAR less
+ENCODING 60
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 10 0 0
+BITMAP
+00C0
+03C0
+0F00
+3C00
+F000
+F000
+3C00
+0F00
+03C0
+00C0
+ENDCHAR
+STARTCHAR equal
+ENCODING 61
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 6 1 2
+BITMAP
+FF80
+FF80
+0000
+0000
+FF80
+FF80
+ENDCHAR
+STARTCHAR greater
+ENCODING 62
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 10 0 0
+BITMAP
+C000
+F000
+3C00
+0F00
+03C0
+03C0
+0F00
+3C00
+F000
+C000
+ENDCHAR
+STARTCHAR question
+ENCODING 63
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+1F00
+6780
+E380
+E380
+6380
+0300
+0600
+0C00
+1800
+0000
+1800
+3C00
+3C00
+1800
+ENDCHAR
+STARTCHAR at
+ENCODING 64
+SWIDTH 747 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+07F0
+1C1C
+300C
+63E6
+6666
+CC66
+CC66
+D8CC
+D8CC
+D9D8
+CEF0
+6008
+7870
+1FC0
+ENDCHAR
+STARTCHAR A
+ENCODING 65
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 14 0 0
+BITMAP
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR B
+ENCODING 66
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+FFC0
+71E0
+70E0
+70E0
+70E0
+71C0
+7F80
+70E0
+70F0
+7070
+7070
+7070
+70E0
+FF80
+ENDCHAR
+STARTCHAR C
+ENCODING 67
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+ENDCHAR
+STARTCHAR D
+ENCODING 68
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+ENDCHAR
+STARTCHAR E
+ENCODING 69
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR F
+ENCODING 70
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7320
+7F00
+7300
+7100
+7100
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR G
+ENCODING 71
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 14 1 0
+BITMAP
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR H
+ENCODING 72
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+ENDCHAR
+STARTCHAR I
+ENCODING 73
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 5 14 2 0
+BITMAP
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR J
+ENCODING 74
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+07E0
+01C0
+01C0
+01C0
+01C0
+01C0
+01C0
+01C0
+61C0
+F1C0
+F1C0
+C3C0
+4780
+3E00
+ENDCHAR
+STARTCHAR K
+ENCODING 75
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 14 1 0
+BITMAP
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+ENDCHAR
+STARTCHAR L
+ENCODING 76
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 14 1 0
+BITMAP
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR M
+ENCODING 77
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 17 14 1 0
+BITMAP
+7C0780
+3C0F00
+3E0F00
+2E1F00
+2F1700
+2F1700
+273700
+27A700
+23E700
+23C700
+23C700
+21C700
+718700
+F88F80
+ENDCHAR
+STARTCHAR N
+ENCODING 78
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 1 0
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR O
+ENCODING 79
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR P
+ENCODING 80
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+FFE0
+70F0
+7070
+7070
+7070
+70F0
+71E0
+7F80
+7000
+7000
+7000
+7000
+7000
+FC00
+ENDCHAR
+STARTCHAR Q
+ENCODING 81
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 0 -4
+BITMAP
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F79E
+79DC
+70FC
+3CF8
+0FE0
+0060
+0074
+007C
+0038
+ENDCHAR
+STARTCHAR R
+ENCODING 82
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+ENDCHAR
+STARTCHAR S
+ENCODING 83
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+ENDCHAR
+STARTCHAR T
+ENCODING 84
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+ENDCHAR
+STARTCHAR U
+ENCODING 85
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR V
+ENCODING 86
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 14 0 0
+BITMAP
+F87C
+7038
+7830
+3820
+3820
+3C60
+1C40
+1E40
+0EC0
+0E80
+0780
+0780
+0300
+0300
+ENDCHAR
+STARTCHAR W
+ENCODING 87
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 14 0 0
+BITMAP
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR X
+ENCODING 88
+SWIDTH 722 0
+DWIDTH 17 0
+BBX 16 14 0 0
+BITMAP
+7E3F
+3C1C
+1E18
+0E30
+0F60
+07C0
+03C0
+03E0
+06F0
+0C70
+1878
+303C
+703E
+F87F
+ENDCHAR
+STARTCHAR Y
+ENCODING 89
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 14 1 0
+BITMAP
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR Z
+ENCODING 90
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+0F00
+1E00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+ENDCHAR
+STARTCHAR bracketleft
+ENCODING 91
+SWIDTH 389 0
+DWIDTH 5 0
+BBX 4 16 1 -2
+BITMAP
+F0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+F0
+ENDCHAR
+STARTCHAR backslash
+ENCODING 92
+SWIDTH 606 0
+DWIDTH 9 0
+BBX 8 14 0 0
+BITMAP
+C0
+C0
+60
+60
+30
+30
+18
+18
+0C
+0C
+06
+06
+03
+03
+ENDCHAR
+STARTCHAR bracketright
+ENCODING 93
+SWIDTH 389 0
+DWIDTH 5 0
+BBX 4 16 0 -2
+BITMAP
+F0
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+30
+F0
+ENDCHAR
+STARTCHAR asciicircum
+ENCODING 94
+SWIDTH 606 0
+DWIDTH 9 0
+BBX 8 8 0 6
+BITMAP
+18
+18
+3C
+3C
+66
+66
+C3
+C3
+ENDCHAR
+STARTCHAR underscore
+ENCODING 95
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 10 2 0 -3
+BITMAP
+FFC0
+FFC0
+ENDCHAR
+STARTCHAR grave
+ENCODING 96
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 10
+BITMAP
+C0
+E0
+70
+18
+ENDCHAR
+STARTCHAR a
+ENCODING 97
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 9 0 0
+BITMAP
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR b
+ENCODING 98
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 12 14 -1 0
+BITMAP
+F000
+7000
+7000
+7000
+7000
+7780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+6F80
+ENDCHAR
+STARTCHAR c
+ENCODING 99
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 9 0 0
+BITMAP
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+ENDCHAR
+STARTCHAR d
+ENCODING 100
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+01E0
+00E0
+00E0
+00E0
+00E0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+ENDCHAR
+STARTCHAR e
+ENCODING 101
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 9 0 0
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR f
+ENCODING 102
+SWIDTH 389 0
+DWIDTH 7 0
+BBX 8 14 0 0
+BITMAP
+1E
+37
+77
+70
+70
+FC
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR g
+ENCODING 103
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 15 0 -4
+BITMAP
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR h
+ENCODING 104
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR i
+ENCODING 105
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 5 14 0 0
+BITMAP
+70
+70
+70
+00
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR j
+ENCODING 106
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 7 18 -3 -4
+BITMAP
+0E
+0E
+0E
+00
+00
+1E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+EE
+EC
+78
+ENDCHAR
+STARTCHAR k
+ENCODING 107
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+F000
+7000
+7000
+7000
+7000
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+ENDCHAR
+STARTCHAR l
+ENCODING 108
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 5 14 0 0
+BITMAP
+F0
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR m
+ENCODING 109
+SWIDTH 963 0
+DWIDTH 20 0
+BBX 19 9 0 0
+BITMAP
+F7DF80
+79F3C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+F9F3E0
+ENDCHAR
+STARTCHAR n
+ENCODING 110
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 9 0 0
+BITMAP
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR o
+ENCODING 111
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 9 0 0
+BITMAP
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR p
+ENCODING 112
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 12 13 -1 -4
+BITMAP
+E780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+7780
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR q
+ENCODING 113
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 12 13 0 -4
+BITMAP
+1E60
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EE0
+00E0
+00E0
+00E0
+01F0
+ENDCHAR
+STARTCHAR r
+ENCODING 114
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 9 0 0
+BITMAP
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR s
+ENCODING 115
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 9 0 0
+BITMAP
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR t
+ENCODING 116
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 13 0 0
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+ENDCHAR
+STARTCHAR u
+ENCODING 117
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 9 0 0
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR v
+ENCODING 118
+SWIDTH 611 0
+DWIDTH 9 0
+BBX 10 9 -1 0
+BITMAP
+F9C0
+7080
+7080
+3900
+3900
+1E00
+1E00
+0C00
+0C00
+ENDCHAR
+STARTCHAR w
+ENCODING 119
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 9 -1 0
+BITMAP
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR x
+ENCODING 120
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 9 0 0
+BITMAP
+FCE0
+78C0
+3D00
+1E00
+0E00
+0F00
+1780
+63C0
+E7E0
+ENDCHAR
+STARTCHAR y
+ENCODING 121
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 -4
+BITMAP
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR z
+ENCODING 122
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 9 0 0
+BITMAP
+FF
+CF
+8E
+1C
+38
+39
+71
+F3
+FF
+ENDCHAR
+STARTCHAR braceleft
+ENCODING 123
+SWIDTH 389 0
+DWIDTH 6 0
+BBX 5 16 0 -2
+BITMAP
+18
+20
+60
+60
+60
+60
+60
+C0
+60
+60
+60
+60
+60
+60
+20
+18
+ENDCHAR
+STARTCHAR bar
+ENCODING 124
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 2 14 4 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR braceright
+ENCODING 125
+SWIDTH 389 0
+DWIDTH 6 0
+BBX 5 16 0 -2
+BITMAP
+C0
+20
+30
+30
+30
+30
+30
+18
+30
+30
+30
+30
+30
+30
+20
+C0
+ENDCHAR
+STARTCHAR asciitilde
+ENCODING 126
+SWIDTH 606 0
+DWIDTH 12 0
+BBX 10 3 1 4
+BITMAP
+39C0
+7F80
+E700
+ENDCHAR
+STARTCHAR space
+ENCODING 160
+SWIDTH 287 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR exclamdown
+ENCODING 161
+SWIDTH 296 0
+DWIDTH 7 0
+BBX 4 14 1 -4
+BITMAP
+60
+F0
+F0
+60
+00
+60
+60
+60
+F0
+F0
+F0
+F0
+F0
+60
+ENDCHAR
+STARTCHAR cent
+ENCODING 162
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 13 1 -2
+BITMAP
+0080
+0080
+1F00
+7380
+E380
+E400
+E400
+E800
+E880
+7180
+1E00
+2000
+2000
+ENDCHAR
+STARTCHAR sterling
+ENCODING 163
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+1F00
+3180
+7380
+7380
+7000
+7000
+3800
+FF80
+1C00
+1C00
+1840
+70C0
+9FC0
+EF80
+ENDCHAR
+STARTCHAR currency
+ENCODING 164
+SWIDTH 606 0
+DWIDTH 10 0
+BBX 9 9 0 2
+BITMAP
+DD80
+FF80
+6300
+C180
+C180
+C180
+6300
+FF80
+DD80
+ENDCHAR
+STARTCHAR yen
+ENCODING 165
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 14 1 0
+BITMAP
+F878
+7030
+7820
+3860
+1C40
+1CC0
+0F80
+1FC0
+0700
+1FC0
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR brokenbar
+ENCODING 166
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 2 14 4 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+00
+00
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR section
+ENCODING 167
+SWIDTH 500 0
+DWIDTH 8 0
+BBX 7 16 0 -2
+BITMAP
+78
+CC
+8C
+C0
+70
+7C
+9E
+86
+C2
+F2
+7C
+1C
+04
+C4
+CC
+78
+ENDCHAR
+STARTCHAR dieresis
+ENCODING 168
+SWIDTH 333 0
+DWIDTH 10 0
+BBX 6 2 2 10
+BITMAP
+CC
+CC
+ENDCHAR
+STARTCHAR copyright
+ENCODING 169
+SWIDTH 747 0
+DWIDTH 15 0
+BBX 14 14 0 0
+BITMAP
+0780
+1860
+2010
+47C8
+4CC8
+9844
+9804
+9804
+9804
+4C48
+4788
+2010
+1860
+0780
+ENDCHAR
+STARTCHAR ordfeminine
+ENCODING 170
+SWIDTH 367 0
+DWIDTH 8 0
+BBX 7 8 0 6
+BITMAP
+78
+CC
+3C
+CC
+DC
+6E
+00
+FE
+ENDCHAR
+STARTCHAR guillemotleft
+ENCODING 171
+SWIDTH 500 0
+DWIDTH 9 0
+BBX 8 5 0 3
+BITMAP
+11
+66
+CC
+66
+11
+ENDCHAR
+STARTCHAR logicalnot
+ENCODING 172
+SWIDTH 606 0
+DWIDTH 10 0
+BBX 9 6 0 2
+BITMAP
+FF80
+FF80
+0180
+0180
+0180
+0180
+ENDCHAR
+STARTCHAR hyphen
+ENCODING 173
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 5 2 0 4
+BITMAP
+F8
+F8
+ENDCHAR
+STARTCHAR registered
+ENCODING 174
+SWIDTH 747 0
+DWIDTH 15 0
+BBX 14 14 0 0
+BITMAP
+0780
+1860
+2010
+5F88
+4CC8
+8CC4
+8F84
+8D84
+8CC4
+5EE8
+4008
+2010
+1860
+0780
+ENDCHAR
+STARTCHAR macron
+ENCODING 175
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 2 1 10
+BITMAP
+FC
+FC
+ENDCHAR
+STARTCHAR degree
+ENCODING 176
+SWIDTH 400 0
+DWIDTH 7 0
+BBX 6 6 0 8
+BITMAP
+78
+CC
+84
+84
+CC
+78
+ENDCHAR
+STARTCHAR plusminus
+ENCODING 177
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 11 0 0
+BITMAP
+0C00
+0C00
+0C00
+FFC0
+FFC0
+0C00
+0C00
+0C00
+0000
+FFC0
+FFC0
+ENDCHAR
+STARTCHAR twosuperior
+ENCODING 178
+SWIDTH 344 0
+DWIDTH 6 0
+BBX 6 8 0 6
+BITMAP
+78
+CC
+CC
+18
+30
+60
+C4
+FC
+ENDCHAR
+STARTCHAR threesuperior
+ENCODING 179
+SWIDTH 344 0
+DWIDTH 6 0
+BBX 6 8 0 6
+BITMAP
+78
+CC
+0C
+38
+0C
+CC
+CC
+78
+ENDCHAR
+STARTCHAR acute
+ENCODING 180
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 10
+BITMAP
+18
+38
+70
+C0
+ENDCHAR
+STARTCHAR mu
+ENCODING 181
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 -4
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+7EF0
+6000
+7000
+7000
+2000
+ENDCHAR
+STARTCHAR paragraph
+ENCODING 182
+SWIDTH 747 0
+DWIDTH 14 0
+BBX 13 14 0 0
+BITMAP
+3FF8
+7E70
+FE70
+FE70
+FE70
+FE70
+7E70
+3E70
+0E70
+0E70
+0E70
+0E70
+0E70
+1FF8
+ENDCHAR
+STARTCHAR periodcentered
+ENCODING 183
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 4 4 0 3
+BITMAP
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR cedilla
+ENCODING 184
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 4 4 1 -4
+BITMAP
+40
+70
+30
+E0
+ENDCHAR
+STARTCHAR onesuperior
+ENCODING 185
+SWIDTH 344 0
+DWIDTH 6 0
+BBX 6 8 0 6
+BITMAP
+30
+F0
+30
+30
+30
+30
+30
+FC
+ENDCHAR
+STARTCHAR ordmasculine
+ENCODING 186
+SWIDTH 367 0
+DWIDTH 7 0
+BBX 6 8 0 6
+BITMAP
+78
+CC
+CC
+CC
+CC
+78
+00
+FC
+ENDCHAR
+STARTCHAR guillemotright
+ENCODING 187
+SWIDTH 500 0
+DWIDTH 9 0
+BBX 8 5 0 3
+BITMAP
+88
+66
+33
+66
+88
+ENDCHAR
+STARTCHAR onequarter
+ENCODING 188
+SWIDTH 861 0
+DWIDTH 15 0
+BBX 14 14 0 0
+BITMAP
+3060
+F060
+30C0
+30C0
+3180
+3180
+3318
+FF38
+0678
+06D8
+0D98
+0DFC
+1818
+183C
+ENDCHAR
+STARTCHAR onehalf
+ENCODING 189
+SWIDTH 861 0
+DWIDTH 15 0
+BBX 14 14 0 0
+BITMAP
+3060
+F060
+30C0
+30C0
+3180
+3180
+3378
+FFCC
+06CC
+0618
+0C30
+0C60
+18C4
+18FC
+ENDCHAR
+STARTCHAR threequarters
+ENCODING 190
+SWIDTH 861 0
+DWIDTH 15 0
+BBX 14 14 0 0
+BITMAP
+7860
+CC60
+0CC0
+38C0
+0D80
+CD80
+CF18
+7B38
+0678
+06D8
+0D98
+0DFC
+1818
+183C
+ENDCHAR
+STARTCHAR questiondown
+ENCODING 191
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 14 0 -4
+BITMAP
+0C00
+1E00
+1E00
+0C00
+0000
+0C00
+1800
+3000
+6000
+E300
+E380
+E380
+F300
+7C00
+ENDCHAR
+STARTCHAR Agrave
+ENCODING 192
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 19 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR Aacute
+ENCODING 193
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 19 0 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR Acircumflex
+ENCODING 194
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0380
+07C0
+0C60
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR Atilde
+ENCODING 195
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0620
+0FC0
+1180
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR Adieresis
+ENCODING 196
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 17 0 0
+BITMAP
+0CC0
+0CC0
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR Aring
+ENCODING 197
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0300
+0480
+0480
+0300
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR AE
+ENCODING 198
+SWIDTH 981 0
+DWIDTH 21 0
+BBX 20 14 0 0
+BITMAP
+03FFF0
+00B870
+01B830
+013890
+033890
+063980
+043F80
+0C3980
+1FF880
+103890
+203810
+203830
+603870
+F1FFF0
+ENDCHAR
+STARTCHAR Ccedilla
+ENCODING 199
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 18 1 -4
+BITMAP
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+0400
+0700
+0300
+0E00
+ENDCHAR
+STARTCHAR Egrave
+ENCODING 200
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR Eacute
+ENCODING 201
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR Ecircumflex
+ENCODING 202
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0E00
+1F00
+3180
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR Edieresis
+ENCODING 203
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+1980
+1980
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR Igrave
+ENCODING 204
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 5 19 2 0
+BITMAP
+C0
+E0
+70
+18
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Iacute
+ENCODING 205
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 6 19 2 0
+BITMAP
+0C
+1C
+38
+60
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Icircumflex
+ENCODING 206
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 7 18 1 0
+BITMAP
+38
+7C
+C6
+00
+7C
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR Idieresis
+ENCODING 207
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 6 17 2 0
+BITMAP
+CC
+CC
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Eth
+ENCODING 208
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+7FE0
+3878
+383C
+381C
+381E
+380E
+FE0E
+380E
+380E
+381E
+381C
+383C
+3878
+7FE0
+ENDCHAR
+STARTCHAR Ntilde
+ENCODING 209
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 1 0
+BITMAP
+0310
+07E0
+08C0
+0000
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR Ograve
+ENCODING 210
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 0 0
+BITMAP
+0C00
+0E00
+0700
+0180
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR Oacute
+ENCODING 211
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 0 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR Ocircumflex
+ENCODING 212
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 0 0
+BITMAP
+0380
+07C0
+0C60
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR Otilde
+ENCODING 213
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 0 0
+BITMAP
+0310
+07E0
+08C0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR Odieresis
+ENCODING 214
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 0 0
+BITMAP
+0660
+0660
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR multiply
+ENCODING 215
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 10 0 0
+BITMAP
+C0C0
+E1C0
+7380
+3F00
+1E00
+1E00
+3F00
+7380
+E1C0
+C0C0
+ENDCHAR
+STARTCHAR Oslash
+ENCODING 216
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+0FC8
+38F0
+7078
+7078
+E0BC
+E11C
+E21C
+E21C
+E41C
+E83C
+7038
+7078
+78F0
+8FC0
+ENDCHAR
+STARTCHAR Ugrave
+ENCODING 217
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+0C00
+0E00
+0700
+0180
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR Uacute
+ENCODING 218
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR Ucircumflex
+ENCODING 219
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0380
+07C0
+0C60
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR Udieresis
+ENCODING 220
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0CC0
+0CC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR Yacute
+ENCODING 221
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 19 1 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR Thorn
+ENCODING 222
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+F800
+7000
+7000
+7FC0
+70F0
+7070
+7070
+7070
+7070
+70E0
+7F80
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR germandbls
+ENCODING 223
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+1E00
+3380
+71C0
+71C0
+71C0
+7180
+7700
+71C0
+70E0
+70E0
+70E0
+70E0
+71C0
+F700
+ENDCHAR
+STARTCHAR agrave
+ENCODING 224
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR aacute
+ENCODING 225
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+0600
+0E00
+1C00
+3000
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR acircumflex
+ENCODING 226
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+1C00
+3E00
+6300
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR atilde
+ENCODING 227
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+1880
+3F00
+4600
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR adieresis
+ENCODING 228
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 12 0 0
+BITMAP
+3300
+3300
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR aring
+ENCODING 229
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+0C00
+1200
+1200
+0C00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR ae
+ENCODING 230
+SWIDTH 870 0
+DWIDTH 17 0
+BBX 16 9 0 0
+BITMAP
+3F78
+63CE
+E387
+0787
+3BFF
+E380
+E381
+E7C3
+78FC
+ENDCHAR
+STARTCHAR ccedilla
+ENCODING 231
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 13 0 -4
+BITMAP
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+1000
+1C00
+0C00
+3800
+ENDCHAR
+STARTCHAR egrave
+ENCODING 232
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR eacute
+ENCODING 233
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+0600
+0E00
+1C00
+3000
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR ecircumflex
+ENCODING 234
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+0E00
+1F00
+3180
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR edieresis
+ENCODING 235
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 12 0 0
+BITMAP
+3300
+3300
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR igrave
+ENCODING 236
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 5 14 0 0
+BITMAP
+C0
+E0
+70
+18
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR iacute
+ENCODING 237
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 5 14 0 0
+BITMAP
+18
+38
+70
+C0
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR icircumflex
+ENCODING 238
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 7 13 -1 0
+BITMAP
+38
+7C
+C6
+00
+78
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR idieresis
+ENCODING 239
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 6 12 0 0
+BITMAP
+CC
+CC
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR eth
+ENCODING 240
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+6000
+1B00
+1C00
+6600
+0300
+1F80
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR ntilde
+ENCODING 241
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 0
+BITMAP
+0C40
+1F80
+2300
+0000
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR ograve
+ENCODING 242
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR oacute
+ENCODING 243
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR ocircumflex
+ENCODING 244
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 0
+BITMAP
+0E00
+1F00
+3180
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR otilde
+ENCODING 245
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 0
+BITMAP
+1880
+3F00
+4600
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR odieresis
+ENCODING 246
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 12 0 0
+BITMAP
+1980
+1980
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR divide
+ENCODING 247
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 10 0 0
+BITMAP
+0C00
+0C00
+0000
+0000
+FFC0
+FFC0
+0000
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR oslash
+ENCODING 248
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 11 0 -1
+BITMAP
+0100
+1F00
+7380
+E3C0
+E5C0
+E5C0
+E9C0
+E9C0
+7380
+3E00
+2000
+ENDCHAR
+STARTCHAR ugrave
+ENCODING 249
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uacute
+ENCODING 250
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR ucircumflex
+ENCODING 251
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 0
+BITMAP
+0700
+0F80
+18C0
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR udieresis
+ENCODING 252
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 0
+BITMAP
+1980
+1980
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR yacute
+ENCODING 253
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 -4
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR thorn
+ENCODING 254
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 12 18 -1 -4
+BITMAP
+F000
+7000
+7000
+7000
+7000
+7780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+7780
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR ydieresis
+ENCODING 255
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 -4
+BITMAP
+1980
+1980
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR Amacron
+ENCODING 256
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 17 0 0
+BITMAP
+0FC0
+0FC0
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR amacron
+ENCODING 257
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 12 0 0
+BITMAP
+3F00
+3F00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR Abreve
+ENCODING 258
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0840
+0CC0
+0780
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR abreve
+ENCODING 259
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+2100
+3300
+1E00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR Aogonek
+ENCODING 260
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 -4
+BITMAP
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+0180
+0300
+0340
+0180
+ENDCHAR
+STARTCHAR aogonek
+ENCODING 261
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 13 0 -4
+BITMAP
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+0C00
+1800
+1A00
+0C00
+ENDCHAR
+STARTCHAR Cacute
+ENCODING 262
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+ENDCHAR
+STARTCHAR cacute
+ENCODING 263
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+ENDCHAR
+STARTCHAR Ccircumflex
+ENCODING 264
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0200
+0700
+0F80
+18C0
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+ENDCHAR
+STARTCHAR ccircumflex
+ENCODING 265
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+0800
+1C00
+3E00
+6300
+0000
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+ENDCHAR
+STARTCHAR Cdotaccent
+ENCODING 266
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 17 1 0
+BITMAP
+0600
+0600
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+ENDCHAR
+STARTCHAR cdotaccent
+ENCODING 267
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 12 0 0
+BITMAP
+0C00
+0C00
+0000
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+ENDCHAR
+STARTCHAR Ccaron
+ENCODING 268
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+ENDCHAR
+STARTCHAR ccaron
+ENCODING 269
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+6300
+3E00
+1C00
+0800
+0000
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+ENDCHAR
+STARTCHAR Dcaron
+ENCODING 270
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+ENDCHAR
+STARTCHAR dcaron
+ENCODING 271
+SWIDTH 875 0
+DWIDTH 17 0
+BBX 16 14 0 0
+BITMAP
+01E6
+00EF
+00EF
+00E7
+00E2
+1EE4
+71E8
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+ENDCHAR
+STARTCHAR Dcroat
+ENCODING 272
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+7FE0
+3878
+383C
+381C
+381E
+380E
+FE0E
+380E
+380E
+381E
+381C
+383C
+3878
+7FE0
+ENDCHAR
+STARTCHAR dcroat
+ENCODING 273
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+01E0
+00E0
+00E0
+01F0
+01F0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+ENDCHAR
+STARTCHAR Emacron
+ENCODING 274
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+1F80
+1F80
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR emacron
+ENCODING 275
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 12 0 0
+BITMAP
+3F00
+3F00
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR Ebreve
+ENCODING 276
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+1080
+1980
+0F00
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR ebreve
+ENCODING 277
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+2100
+3300
+1E00
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR Edotaccent
+ENCODING 278
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+0600
+0600
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR edotaccent
+ENCODING 279
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 12 0 0
+BITMAP
+0C00
+0C00
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR Eogonek
+ENCODING 280
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 -4
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0600
+0C00
+0D00
+0600
+ENDCHAR
+STARTCHAR eogonek
+ENCODING 281
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 -4
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0C00
+1800
+1A00
+0C00
+ENDCHAR
+STARTCHAR Ecaron
+ENCODING 282
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR ecaron
+ENCODING 283
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR Gcircumflex
+ENCODING 284
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 19 1 0
+BITMAP
+0200
+0700
+0F80
+18C0
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR gcircumflex
+ENCODING 285
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 20 0 -4
+BITMAP
+0200
+0700
+0F80
+18C0
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR Gbreve
+ENCODING 286
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 18 1 0
+BITMAP
+1080
+1980
+0F00
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR gbreve
+ENCODING 287
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 19 0 -4
+BITMAP
+1080
+1980
+0F00
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR Gdotaccent
+ENCODING 288
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 17 1 0
+BITMAP
+0600
+0600
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR gdotaccent
+ENCODING 289
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 18 0 -4
+BITMAP
+0600
+0600
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR Gcommaaccent
+ENCODING 290
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 22 1 -8
+BITMAP
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+0000
+0300
+0780
+0780
+0380
+0100
+0200
+0400
+ENDCHAR
+STARTCHAR gcommaaccent
+ENCODING 291
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 23 0 -4
+BITMAP
+0100
+0200
+0400
+0E00
+0F00
+0F00
+0600
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR Hcircumflex
+ENCODING 292
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+0100
+0380
+07C0
+0C60
+0000
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+ENDCHAR
+STARTCHAR hcircumflex
+ENCODING 293
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 19 0 0
+BITMAP
+1000
+3800
+7C00
+C600
+0000
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR Hbar
+ENCODING 294
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+FCFC
+7038
+7038
+7038
+FFFC
+FFFC
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+ENDCHAR
+STARTCHAR hbar
+ENCODING 295
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+F000
+7000
+7000
+7C00
+7C00
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR Itilde
+ENCODING 296
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 8 18 1 0
+BITMAP
+31
+7E
+8C
+00
+7C
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR itilde
+ENCODING 297
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 8 13 -1 0
+BITMAP
+31
+7E
+8C
+00
+78
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR Imacron
+ENCODING 298
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 6 17 2 0
+BITMAP
+FC
+FC
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR imacron
+ENCODING 299
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 6 12 -1 0
+BITMAP
+FC
+FC
+00
+78
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR Ibreve
+ENCODING 300
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 6 18 2 0
+BITMAP
+84
+CC
+78
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR ibreve
+ENCODING 301
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 6 13 -1 0
+BITMAP
+84
+CC
+78
+00
+78
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR Iogonek
+ENCODING 302
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 5 18 2 -4
+BITMAP
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+30
+60
+68
+30
+ENDCHAR
+STARTCHAR iogonek
+ENCODING 303
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 5 18 0 -4
+BITMAP
+70
+70
+70
+00
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+30
+60
+68
+30
+ENDCHAR
+STARTCHAR Idotaccent
+ENCODING 304
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 5 17 2 0
+BITMAP
+30
+30
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR dotlessi
+ENCODING 305
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 5 9 0 0
+BITMAP
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR IJ
+ENCODING 306
+SWIDTH 1070 0
+DWIDTH 21 0
+BBX 18 14 2 0
+BITMAP
+F80FC0
+700380
+700380
+700380
+700380
+700380
+700380
+700380
+70C380
+71E380
+71E380
+718780
+708F00
+F87C00
+ENDCHAR
+STARTCHAR ij
+ENCODING 307
+SWIDTH 704 0
+DWIDTH 12 0
+BBX 10 18 0 -4
+BITMAP
+71C0
+71C0
+71C0
+0000
+0000
+F3C0
+71C0
+71C0
+71C0
+71C0
+71C0
+71C0
+71C0
+F9C0
+01C0
+1DC0
+1D80
+0F00
+ENDCHAR
+STARTCHAR Jcircumflex
+ENCODING 308
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 11 19 0 0
+BITMAP
+0100
+0380
+07C0
+0C60
+0000
+07E0
+01C0
+01C0
+01C0
+01C0
+01C0
+01C0
+01C0
+61C0
+F1C0
+F1C0
+C3C0
+4780
+3E00
+ENDCHAR
+STARTCHAR jcircumflex
+ENCODING 309
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 8 18 -3 -4
+BITMAP
+08
+1C
+3E
+63
+00
+1E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+EE
+EC
+78
+ENDCHAR
+STARTCHAR Kcommaaccent
+ENCODING 310
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 22 1 -8
+BITMAP
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+0000
+0180
+03C0
+03C0
+01C0
+0080
+0100
+0200
+ENDCHAR
+STARTCHAR kcommaaccent
+ENCODING 311
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 22 0 -8
+BITMAP
+F000
+7000
+7000
+7000
+7000
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+0000
+0600
+0F00
+0F00
+0700
+0200
+0400
+0800
+ENDCHAR
+STARTCHAR kgreenlandic
+ENCODING 312
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 9 0 0
+BITMAP
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+ENDCHAR
+STARTCHAR Lacute
+ENCODING 313
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 19 1 0
+BITMAP
+0600
+0E00
+1C00
+3000
+0000
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR lacute
+ENCODING 314
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 5 19 0 0
+BITMAP
+18
+38
+70
+C0
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Lcommaaccent
+ENCODING 315
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 22 1 -8
+BITMAP
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+0000
+0C00
+1E00
+1E00
+0E00
+0400
+0800
+1000
+ENDCHAR
+STARTCHAR lcommaaccent
+ENCODING 316
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 5 22 0 -8
+BITMAP
+F0
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+00
+30
+78
+78
+38
+10
+20
+40
+ENDCHAR
+STARTCHAR Lcaron
+ENCODING 317
+SWIDTH 927 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+FC18
+703C
+703C
+701C
+7008
+7010
+7020
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR lcaron
+ENCODING 318
+SWIDTH 575 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+F180
+73C0
+73C0
+71C0
+7080
+7100
+7200
+7000
+7000
+7000
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR Ldot
+ENCODING 319
+SWIDTH 964 0
+DWIDTH 16 0
+BBX 14 14 1 0
+BITMAP
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7018
+703C
+703C
+7038
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR ldot
+ENCODING 320
+SWIDTH 612 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+F000
+7000
+7000
+7000
+7000
+7000
+7000
+7180
+73C0
+73C0
+7180
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR Lslash
+ENCODING 321
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 12 14 -1 0
+BITMAP
+7E00
+3C00
+3C00
+3C00
+3D00
+3E00
+3C00
+3C00
+7C00
+BC10
+3C10
+3C30
+3C70
+7FF0
+ENDCHAR
+STARTCHAR lslash
+ENCODING 322
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 6 14 0 0
+BITMAP
+F0
+70
+70
+70
+74
+78
+70
+F0
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Nacute
+ENCODING 323
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 1 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR nacute
+ENCODING 324
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR Ncommaaccent
+ENCODING 325
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 22 1 -8
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+0000
+0300
+0780
+0780
+0380
+0100
+0200
+0400
+ENDCHAR
+STARTCHAR ncommaaccent
+ENCODING 326
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 -8
+BITMAP
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+0600
+0F00
+0F00
+0700
+0200
+0400
+0800
+ENDCHAR
+STARTCHAR Ncaron
+ENCODING 327
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR ncaron
+ENCODING 328
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR napostrophe
+ENCODING 329
+SWIDTH 914 0
+DWIDTH 18 0
+BBX 17 14 0 0
+BITMAP
+600000
+F00000
+F00000
+700000
+200000
+47BE00
+83CF00
+038700
+038700
+038700
+038700
+038700
+038700
+07CF80
+ENDCHAR
+STARTCHAR Eng
+ENCODING 330
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 1 -4
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F838
+0038
+03B8
+03B0
+01E0
+ENDCHAR
+STARTCHAR eng
+ENCODING 331
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 11 13 0 -4
+BITMAP
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F8E0
+00E0
+0EE0
+0EC0
+0780
+ENDCHAR
+STARTCHAR Omacron
+ENCODING 332
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 0 0
+BITMAP
+07E0
+07E0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR omacron
+ENCODING 333
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 12 0 0
+BITMAP
+1F80
+1F80
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR Obreve
+ENCODING 334
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 0 0
+BITMAP
+0420
+0660
+03C0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR obreve
+ENCODING 335
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 0
+BITMAP
+1080
+1980
+0F00
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR Ohungarumlaut
+ENCODING 336
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 0 0
+BITMAP
+0660
+0660
+0CC0
+0880
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR ohungarumlaut
+ENCODING 337
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+1980
+1980
+3300
+2200
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR OE
+ENCODING 338
+SWIDTH 1000 0
+DWIDTH 22 0
+BBX 21 14 0 0
+BITMAP
+0FFFF8
+3C7C38
+783C18
+783C48
+F03C48
+F03CC0
+F03FC0
+F03CC0
+F03C40
+F03C48
+783C08
+783C18
+3C7C38
+0FFFF8
+ENDCHAR
+STARTCHAR oe
+ENCODING 339
+SWIDTH 907 0
+DWIDTH 19 0
+BBX 18 9 0 0
+BITMAP
+1F1E00
+71F380
+E0E1C0
+E0E1C0
+E0FFC0
+E0E000
+E0E040
+71F0C0
+1F1F00
+ENDCHAR
+STARTCHAR Racute
+ENCODING 340
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+ENDCHAR
+STARTCHAR racute
+ENCODING 341
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 14 0 0
+BITMAP
+06
+0E
+1C
+30
+00
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Rcommaaccent
+ENCODING 342
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 22 1 -8
+BITMAP
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+0000
+0300
+0780
+0780
+0380
+0100
+0200
+0400
+ENDCHAR
+STARTCHAR rcommaaccent
+ENCODING 343
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 17 0 -8
+BITMAP
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+00
+30
+78
+78
+38
+10
+20
+40
+ENDCHAR
+STARTCHAR Rcaron
+ENCODING 344
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+ENDCHAR
+STARTCHAR rcaron
+ENCODING 345
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 14 0 0
+BITMAP
+63
+3E
+1C
+08
+00
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR Sacute
+ENCODING 346
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 19 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+ENDCHAR
+STARTCHAR sacute
+ENCODING 347
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+0600
+0E00
+1C00
+3000
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR Scircumflex
+ENCODING 348
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 19 0 0
+BITMAP
+0400
+0E00
+1F00
+3180
+0000
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+ENDCHAR
+STARTCHAR scircumflex
+ENCODING 349
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+0800
+1C00
+3E00
+6300
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR Scedilla
+ENCODING 350
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 18 0 -4
+BITMAP
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+0800
+0E00
+0600
+1C00
+ENDCHAR
+STARTCHAR scedilla
+ENCODING 351
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 13 0 -4
+BITMAP
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+1000
+1C00
+0C00
+3800
+ENDCHAR
+STARTCHAR Scaron
+ENCODING 352
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 14 0 0
+BITMAP
+6180
+3300
+1E00
+0C00
+0000
+3F80
+7180
+7880
+7E00
+3F00
+0F80
+83C0
+C780
+BF00
+ENDCHAR
+STARTCHAR scaron
+ENCODING 353
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 14 0 0
+BITMAP
+C300
+6600
+3C00
+1800
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR Tcommaaccent
+ENCODING 354
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 -4
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+0800
+0E00
+0600
+1C00
+ENDCHAR
+STARTCHAR tcommaaccent
+ENCODING 355
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 17 0 -4
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+20
+38
+18
+70
+ENDCHAR
+STARTCHAR Tcaron
+ENCODING 356
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+ENDCHAR
+STARTCHAR tcaron
+ENCODING 357
+SWIDTH 646 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+0060
+10F0
+30F0
+3070
+7020
+FC40
+7080
+7000
+7000
+7000
+7000
+7200
+7200
+3C00
+ENDCHAR
+STARTCHAR Tbar
+ENCODING 358
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+1F00
+1F00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+ENDCHAR
+STARTCHAR tbar
+ENCODING 359
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 13 0 0
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+7C
+7C
+72
+72
+3C
+ENDCHAR
+STARTCHAR Utilde
+ENCODING 360
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0620
+0FC0
+1180
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR utilde
+ENCODING 361
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 0
+BITMAP
+0C40
+1F80
+2300
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR Umacron
+ENCODING 362
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0FC0
+0FC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR umacron
+ENCODING 363
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 0
+BITMAP
+1F80
+1F80
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR Ubreve
+ENCODING 364
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0840
+0CC0
+0780
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR ubreve
+ENCODING 365
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 0
+BITMAP
+1080
+1980
+0F00
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR Uring
+ENCODING 366
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+0300
+0480
+0480
+0300
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uring
+ENCODING 367
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+0600
+0900
+0900
+0600
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR Uhungarumlaut
+ENCODING 368
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+0CC0
+0CC0
+1980
+1100
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uhungarumlaut
+ENCODING 369
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+0CC0
+0CC0
+1980
+1100
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR Uogonek
+ENCODING 370
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 -4
+BITMAP
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+0600
+0C00
+0D00
+0600
+ENDCHAR
+STARTCHAR uogonek
+ENCODING 371
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 -4
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+0300
+0600
+0680
+0300
+ENDCHAR
+STARTCHAR Wcircumflex
+ENCODING 372
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 19 0 0
+BITMAP
+008000
+01C000
+03E000
+063000
+000000
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR wcircumflex
+ENCODING 373
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 14 -1 0
+BITMAP
+0100
+0380
+07C0
+0C60
+0000
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR Ycircumflex
+ENCODING 374
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 19 1 0
+BITMAP
+0200
+0700
+0F80
+18C0
+0000
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR ycircumflex
+ENCODING 375
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 -4
+BITMAP
+0800
+1C00
+3E00
+6300
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR Ydieresis
+ENCODING 376
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 14 0 0
+BITMAP
+0CC0
+0CC0
+0000
+0000
+0000
+FCF8
+7870
+3CE0
+1FC0
+0F80
+0780
+0780
+0780
+0FC0
+ENDCHAR
+STARTCHAR Zacute
+ENCODING 377
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+0F00
+1E00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+ENDCHAR
+STARTCHAR zacute
+ENCODING 378
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 14 0 0
+BITMAP
+06
+0E
+1C
+30
+00
+FF
+CF
+8E
+1C
+38
+39
+71
+F3
+FF
+ENDCHAR
+STARTCHAR Zdotaccent
+ENCODING 379
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+0600
+0600
+0000
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+0F00
+1E00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+ENDCHAR
+STARTCHAR zdotaccent
+ENCODING 380
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 12 0 0
+BITMAP
+18
+18
+00
+FF
+CF
+8E
+1C
+38
+39
+71
+F3
+FF
+ENDCHAR
+STARTCHAR Zcaron
+ENCODING 381
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+30C0
+1980
+0F00
+0600
+0000
+FFF0
+C1E0
+83C0
+0780
+0F10
+1E10
+3C30
+7870
+FFF0
+ENDCHAR
+STARTCHAR zcaron
+ENCODING 382
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 14 0 0
+BITMAP
+C3
+66
+3C
+18
+00
+FF
+C7
+8F
+1E
+3C
+79
+F1
+E3
+FF
+ENDCHAR
+STARTCHAR uni0186
+ENCODING 390
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 14 1 0
+BITMAP
+1F00
+63C0
+41E0
+80E0
+80F0
+0070
+0070
+0070
+8070
+80F0
+C0E0
+C1E0
+E3C0
+9F00
+ENDCHAR
+STARTCHAR uni0189
+ENCODING 393
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+7FE0
+3878
+383C
+381C
+381E
+380E
+FE0E
+380E
+380E
+381E
+381C
+383C
+3878
+7FE0
+ENDCHAR
+STARTCHAR uni018E
+ENCODING 398
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+E1C0
+C1C0
+81C0
+91C0
+11C0
+19C0
+1FC0
+19C0
+91C0
+91C0
+C1C0
+E1C0
+FFE0
+ENDCHAR
+STARTCHAR florin
+ENCODING 402
+SWIDTH 574 0
+DWIDTH 12 0
+BBX 11 18 0 -4
+BITMAP
+01C0
+0360
+0760
+0700
+0700
+1FC0
+0E00
+0E00
+0E00
+0E00
+0E00
+1C00
+1C00
+1C00
+1C00
+DC00
+D800
+7000
+ENDCHAR
+STARTCHAR uni0197
+ENCODING 407
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 5 14 2 0
+BITMAP
+F8
+70
+70
+70
+70
+70
+F8
+F8
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni019A
+ENCODING 410
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 5 14 0 0
+BITMAP
+F0
+70
+70
+70
+70
+70
+F8
+F8
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni019D
+ENCODING 413
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 17 18 -1 -4
+BITMAP
+3E0F80
+1F0700
+0F0200
+0F8200
+0BC200
+09E200
+08E200
+087200
+087A00
+083A00
+0E1E00
+0E1E00
+0E0E00
+0E0600
+0E0000
+EE0000
+EC0000
+780000
+ENDCHAR
+STARTCHAR uni019F
+ENCODING 415
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 0 0
+BITMAP
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+FFFE
+FFFE
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR Ohorn
+ENCODING 416
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 18 14 0 0
+BITMAP
+0FE180
+3C7BC0
+783FC0
+701DC0
+F01E80
+E00F00
+E00E00
+E00E00
+E00E00
+F01E00
+701C00
+783C00
+3C7800
+0FE000
+ENDCHAR
+STARTCHAR ohorn
+ENCODING 417
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 14 9 0 0
+BITMAP
+1F18
+71FC
+E0FC
+E0FC
+E0E8
+E0F0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni01A7
+ENCODING 423
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+5F80
+70C0
+6060
+4060
+00E0
+0FE0
+7FC0
+FFC0
+FE00
+E020
+C020
+C060
+60E0
+3FA0
+ENDCHAR
+STARTCHAR uni01A8
+ENCODING 424
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 9 0 0
+BITMAP
+5E00
+6300
+4380
+1F80
+7F00
+F800
+E080
+6180
+3E80
+ENDCHAR
+STARTCHAR uni01AE
+ENCODING 430
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 18 1 -4
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0EE0
+06E0
+03C0
+ENDCHAR
+STARTCHAR Uhorn
+ENCODING 431
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 17 14 1 0
+BITMAP
+F87F00
+703F80
+701780
+701380
+701100
+701200
+701400
+701000
+701000
+701000
+701000
+701000
+382000
+1FC000
+ENDCHAR
+STARTCHAR uhorn
+ENCODING 432
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 15 9 0 0
+BITMAP
+F1EC
+70FE
+70FE
+70EE
+70E4
+70E8
+70F0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni01B5
+ENCODING 437
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+1F00
+1F00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+ENDCHAR
+STARTCHAR uni01B6
+ENCODING 438
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 9 0 0
+BITMAP
+FF
+CF
+8E
+3E
+3E
+39
+71
+F3
+FF
+ENDCHAR
+STARTCHAR uni01BB
+ENCODING 443
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+1E00
+6700
+E380
+E380
+6380
+0380
+FF80
+FF80
+0E00
+1800
+3000
+6080
+FF80
+FF80
+ENDCHAR
+STARTCHAR uni01BC
+ENCODING 444
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 9 14 1 0
+BITMAP
+7F80
+7F00
+4000
+4000
+4000
+7E00
+4700
+0380
+0380
+6380
+E380
+E380
+6700
+3E00
+ENDCHAR
+STARTCHAR uni01C0
+ENCODING 448
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 2 14 4 0
+BITMAP
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR uni01C2
+ENCODING 450
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 14 1 -2
+BITMAP
+0C00
+0C00
+0C00
+0C00
+FF80
+FF80
+0C00
+0C00
+FF80
+FF80
+0C00
+0C00
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni01C3
+ENCODING 451
+SWIDTH 296 0
+DWIDTH 6 0
+BBX 4 14 1 0
+BITMAP
+60
+F0
+F0
+F0
+F0
+F0
+60
+60
+60
+00
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR uni01CD
+ENCODING 461
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 19 0 0
+BITMAP
+0C60
+07C0
+0380
+0100
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni01CE
+ENCODING 462
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+6300
+3E00
+1C00
+0800
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni01CF
+ENCODING 463
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 7 19 1 0
+BITMAP
+C6
+7C
+38
+10
+00
+7C
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR uni01D0
+ENCODING 464
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 7 14 -1 0
+BITMAP
+C6
+7C
+38
+10
+00
+78
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR uni01D1
+ENCODING 465
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 0 0
+BITMAP
+0C60
+07C0
+0380
+0100
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni01D2
+ENCODING 466
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni01D3
+ENCODING 467
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni01D4
+ENCODING 468
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni01D5
+ENCODING 469
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 20 1 0
+BITMAP
+0FC0
+0FC0
+0000
+0CC0
+0CC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni01D6
+ENCODING 470
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 15 0 0
+BITMAP
+1F80
+1F80
+0000
+1980
+1980
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni01D7
+ENCODING 471
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 22 1 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0CC0
+0CC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni01D8
+ENCODING 472
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+1980
+1980
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni01D9
+ENCODING 473
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 22 1 0
+BITMAP
+0C60
+07C0
+0380
+0100
+0000
+0CC0
+0CC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni01DA
+ENCODING 474
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 0
+BITMAP
+3180
+1F00
+0E00
+0400
+0000
+1980
+1980
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni01DB
+ENCODING 475
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 22 1 0
+BITMAP
+0C00
+0E00
+0700
+0180
+0000
+0CC0
+0CC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni01DC
+ENCODING 476
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+1980
+1980
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni01DD
+ENCODING 477
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 9 0 0
+BITMAP
+3E00
+C380
+81C0
+01C0
+FFC0
+E1C0
+E1C0
+7380
+1E00
+ENDCHAR
+STARTCHAR uni01DE
+ENCODING 478
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 20 0 0
+BITMAP
+0FC0
+0FC0
+0000
+0CC0
+0CC0
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni01DF
+ENCODING 479
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 15 0 0
+BITMAP
+3F00
+3F00
+0000
+3300
+3300
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni01E0
+ENCODING 480
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 20 0 0
+BITMAP
+0FC0
+0FC0
+0000
+0300
+0300
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni01E1
+ENCODING 481
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 15 0 0
+BITMAP
+3F00
+3F00
+0000
+0C00
+0C00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni01E2
+ENCODING 482
+SWIDTH 981 0
+DWIDTH 21 0
+BBX 20 17 0 0
+BITMAP
+007E00
+007E00
+000000
+03FFF0
+00B870
+01B830
+013890
+033890
+063980
+043F80
+0C3980
+1FF880
+103890
+203810
+203830
+603870
+F1FFF0
+ENDCHAR
+STARTCHAR uni01E3
+ENCODING 483
+SWIDTH 870 0
+DWIDTH 17 0
+BBX 16 12 0 0
+BITMAP
+07E0
+07E0
+0000
+3F78
+63CE
+E387
+0787
+3BFF
+E380
+E381
+E7C3
+78FC
+ENDCHAR
+STARTCHAR uni01E4
+ENCODING 484
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 14 14 1 0
+BITMAP
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+787C
+3CFC
+0F90
+ENDCHAR
+STARTCHAR uni01E5
+ENCODING 485
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 15 0 -4
+BITMAP
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+FFE0
+FFE0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR Gcaron
+ENCODING 486
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR gcaron
+ENCODING 487
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 20 0 -4
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR uni01E8
+ENCODING 488
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 19 1 0
+BITMAP
+18C0
+0F80
+0700
+0200
+0000
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+ENDCHAR
+STARTCHAR uni01E9
+ENCODING 489
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 19 0 0
+BITMAP
+C600
+7C00
+3800
+1000
+0000
+F000
+7000
+7000
+7000
+7000
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+ENDCHAR
+STARTCHAR uni01EA
+ENCODING 490
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 0 -4
+BITMAP
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+0180
+0300
+0340
+0180
+ENDCHAR
+STARTCHAR uni01EB
+ENCODING 491
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 -4
+BITMAP
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+0600
+0C00
+0D00
+0600
+ENDCHAR
+STARTCHAR uni01EC
+ENCODING 492
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 21 0 -4
+BITMAP
+07E0
+07E0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+0180
+0300
+0340
+0180
+ENDCHAR
+STARTCHAR uni01ED
+ENCODING 493
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 -4
+BITMAP
+1F80
+1F80
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+0600
+0C00
+0D00
+0600
+ENDCHAR
+STARTCHAR uni01F0
+ENCODING 496
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 8 18 -3 -4
+BITMAP
+63
+3E
+1C
+08
+00
+1E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+EE
+EC
+78
+ENDCHAR
+STARTCHAR uni01F4
+ENCODING 500
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR uni01F5
+ENCODING 501
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 20 0 -4
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR uni01F8
+ENCODING 504
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 1 0
+BITMAP
+0C00
+0E00
+0700
+0180
+0000
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR uni01F9
+ENCODING 505
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR Aringacute
+ENCODING 506
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 23 0 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0300
+0480
+0480
+0300
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR aringacute
+ENCODING 507
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 19 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+0C00
+1200
+1200
+0C00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR AEacute
+ENCODING 508
+SWIDTH 981 0
+DWIDTH 21 0
+BBX 20 19 0 0
+BITMAP
+000600
+000E00
+001C00
+003000
+000000
+03FFF0
+00B870
+01B830
+013890
+033890
+063980
+043F80
+0C3980
+1FF880
+103890
+203810
+203830
+603870
+F1FFF0
+ENDCHAR
+STARTCHAR aeacute
+ENCODING 509
+SWIDTH 870 0
+DWIDTH 17 0
+BBX 16 14 0 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+3F78
+63CE
+E387
+0787
+3BFF
+E380
+E381
+E7C3
+78FC
+ENDCHAR
+STARTCHAR Oslashacute
+ENCODING 510
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0FC8
+38F0
+7078
+7078
+E0BC
+E11C
+E21C
+E21C
+E41C
+E83C
+7038
+7078
+78F0
+8FC0
+ENDCHAR
+STARTCHAR oslashacute
+ENCODING 511
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 16 0 -1
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+0100
+1F00
+7380
+E3C0
+E5C0
+E5C0
+E9C0
+E9C0
+7380
+3E00
+2000
+ENDCHAR
+STARTCHAR uni0200
+ENCODING 512
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 19 0 0
+BITMAP
+1980
+1980
+0CC0
+0440
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni0201
+ENCODING 513
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+6600
+6600
+3300
+1100
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni0202
+ENCODING 514
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0780
+0CC0
+0840
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni0203
+ENCODING 515
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+1E00
+3300
+2100
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni0204
+ENCODING 516
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+3300
+3300
+1980
+0880
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni0205
+ENCODING 517
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 14 0 0
+BITMAP
+6600
+6600
+3300
+1100
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni0206
+ENCODING 518
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0F00
+1980
+1080
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni0207
+ENCODING 519
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+1E00
+3300
+2100
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni0208
+ENCODING 520
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 7 19 1 0
+BITMAP
+CC
+CC
+66
+22
+00
+7C
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR uni0209
+ENCODING 521
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 7 14 -2 0
+BITMAP
+CC
+CC
+66
+22
+00
+3C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+3E
+ENDCHAR
+STARTCHAR uni020A
+ENCODING 522
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 6 18 2 0
+BITMAP
+78
+CC
+84
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni020B
+ENCODING 523
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 6 13 -1 0
+BITMAP
+78
+CC
+84
+00
+78
+38
+38
+38
+38
+38
+38
+38
+7C
+ENDCHAR
+STARTCHAR uni020C
+ENCODING 524
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 0 0
+BITMAP
+0CC0
+0CC0
+0660
+0220
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni020D
+ENCODING 525
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+3300
+3300
+1980
+0880
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni020E
+ENCODING 526
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 18 0 0
+BITMAP
+03C0
+0660
+0420
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni020F
+ENCODING 527
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 0
+BITMAP
+0F00
+1980
+1080
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni0210
+ENCODING 528
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+1980
+1980
+0CC0
+0440
+0000
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+ENDCHAR
+STARTCHAR uni0211
+ENCODING 529
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 14 0 0
+BITMAP
+CC
+CC
+66
+22
+00
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni0212
+ENCODING 530
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0F00
+1980
+1080
+0000
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+ENDCHAR
+STARTCHAR uni0213
+ENCODING 531
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 13 0 0
+BITMAP
+3C
+66
+42
+00
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni0214
+ENCODING 532
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+1980
+1980
+0CC0
+0440
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni0215
+ENCODING 533
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 0
+BITMAP
+3300
+3300
+1980
+0880
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni0216
+ENCODING 534
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 0
+BITMAP
+0780
+0CC0
+0840
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni0217
+ENCODING 535
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 0
+BITMAP
+0F00
+1980
+1080
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR Scommaaccent
+ENCODING 536
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 22 0 -8
+BITMAP
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+0000
+0C00
+1E00
+1E00
+0E00
+0400
+0800
+1000
+ENDCHAR
+STARTCHAR scommaaccent
+ENCODING 537
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 17 0 -8
+BITMAP
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+0000
+1800
+3C00
+3C00
+1C00
+0800
+1000
+2000
+ENDCHAR
+STARTCHAR Tcommaaccent
+ENCODING 538
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 22 1 -8
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+0000
+0600
+0F00
+0F00
+0700
+0200
+0400
+0800
+ENDCHAR
+STARTCHAR tcommaaccent
+ENCODING 539
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 21 0 -8
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+00
+30
+78
+78
+38
+10
+20
+40
+ENDCHAR
+STARTCHAR uni021E
+ENCODING 542
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 19 1 0
+BITMAP
+0C60
+07C0
+0380
+0100
+0000
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+ENDCHAR
+STARTCHAR uni021F
+ENCODING 543
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 19 0 0
+BITMAP
+C600
+7C00
+3800
+1000
+0000
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR uni0226
+ENCODING 550
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 17 0 0
+BITMAP
+0300
+0300
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni0227
+ENCODING 551
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 12 0 0
+BITMAP
+0C00
+0C00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni0228
+ENCODING 552
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 -4
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0800
+0E00
+0600
+1C00
+ENDCHAR
+STARTCHAR uni0229
+ENCODING 553
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 -4
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0800
+0E00
+0600
+1C00
+ENDCHAR
+STARTCHAR uni022A
+ENCODING 554
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 20 0 0
+BITMAP
+07E0
+07E0
+0000
+0660
+0660
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni022B
+ENCODING 555
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 15 0 0
+BITMAP
+1F80
+1F80
+0000
+1980
+1980
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni022C
+ENCODING 556
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 21 0 0
+BITMAP
+07E0
+07E0
+0000
+0310
+07E0
+08C0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni022D
+ENCODING 557
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 0
+BITMAP
+3F00
+3F00
+0000
+1880
+3F00
+4600
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni022E
+ENCODING 558
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 0 0
+BITMAP
+0180
+0180
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni022F
+ENCODING 559
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 12 0 0
+BITMAP
+0600
+0600
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni0230
+ENCODING 560
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 20 0 0
+BITMAP
+07E0
+07E0
+0000
+0180
+0180
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni0231
+ENCODING 561
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 15 0 0
+BITMAP
+1F80
+1F80
+0000
+0600
+0600
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni0232
+ENCODING 562
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 17 1 0
+BITMAP
+1F80
+1F80
+0000
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR uni0233
+ENCODING 563
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 -4
+BITMAP
+3F00
+3F00
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR uni0250
+ENCODING 592
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 9 0 0
+BITMAP
+F780
+79C0
+71C0
+71C0
+7700
+7800
+70C0
+71C0
+3F80
+ENDCHAR
+STARTCHAR uni0254
+ENCODING 596
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 9 0 0
+BITMAP
+7C00
+E700
+C380
+0380
+0380
+0380
+8380
+C700
+3C00
+ENDCHAR
+STARTCHAR uni0258
+ENCODING 600
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 9 0 0
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+01C0
+81C0
+C380
+3E00
+ENDCHAR
+STARTCHAR uni0259
+ENCODING 601
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 9 0 0
+BITMAP
+3E00
+C380
+81C0
+01C0
+FFC0
+E1C0
+E1C0
+7380
+1E00
+ENDCHAR
+STARTCHAR uni025F
+ENCODING 607
+SWIDTH 389 0
+DWIDTH 7 0
+BBX 8 14 0 -5
+BITMAP
+1F
+0E
+0E
+0E
+0E
+0E
+0E
+0E
+3F
+0E
+0E
+EE
+EC
+78
+ENDCHAR
+STARTCHAR uni0265
+ENCODING 613
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 -5
+BITMAP
+F9F0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EE0
+00E0
+00E0
+00E0
+00E0
+00F0
+ENDCHAR
+STARTCHAR uni0275
+ENCODING 629
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 9 0 0
+BITMAP
+1F00
+71C0
+E0E0
+FFE0
+FFE0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni0279
+ENCODING 633
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 9 0 0
+BITMAP
+1F
+0E
+0E
+0E
+0E
+0E
+CE
+DE
+EF
+ENDCHAR
+STARTCHAR uni0287
+ENCODING 647
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 13 0 0
+BITMAP
+78
+9C
+9C
+1C
+1C
+1C
+1C
+1C
+7E
+1C
+18
+18
+10
+ENDCHAR
+STARTCHAR uni0288
+ENCODING 648
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 8 17 0 -4
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+70
+70
+70
+70
+77
+37
+1E
+ENDCHAR
+STARTCHAR uni0289
+ENCODING 649
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 9 0 0
+BITMAP
+F1E0
+70E0
+70E0
+FFF0
+FFF0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni028C
+ENCODING 652
+SWIDTH 611 0
+DWIDTH 9 0
+BBX 10 9 -1 0
+BITMAP
+0C00
+0C00
+1E00
+1E00
+2700
+2700
+4380
+4380
+E7C0
+ENDCHAR
+STARTCHAR uni028D
+ENCODING 653
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 9 -1 0
+BITMAP
+0C30
+0C30
+1E78
+1E78
+279C
+279C
+438E
+438E
+E7DF
+ENDCHAR
+STARTCHAR uni028E
+ENCODING 654
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 13 0 0
+BITMAP
+01C0
+02E0
+0460
+0400
+0E00
+0E00
+1700
+1700
+2380
+2380
+41C0
+41C0
+E3E0
+ENDCHAR
+STARTCHAR uni029E
+ENCODING 670
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 14 0 -5
+BITMAP
+FDF0
+78E0
+3CE0
+1EE0
+0FE0
+06E0
+04E0
+18E0
+7CE0
+00E0
+00E0
+00E0
+00E0
+00F0
+ENDCHAR
+STARTCHAR uni02BB
+ENCODING 699
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 4 7 0 7
+BITMAP
+10
+20
+40
+E0
+F0
+F0
+60
+ENDCHAR
+STARTCHAR afii57929
+ENCODING 700
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 4 7 0 7
+BITMAP
+60
+F0
+F0
+70
+20
+40
+80
+ENDCHAR
+STARTCHAR afii64937
+ENCODING 701
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 4 7 0 7
+BITMAP
+60
+F0
+F0
+E0
+40
+20
+10
+ENDCHAR
+STARTCHAR circumflex
+ENCODING 710
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 7 4 0 10
+BITMAP
+10
+38
+7C
+C6
+ENDCHAR
+STARTCHAR caron
+ENCODING 711
+SWIDTH 333 0
+DWIDTH 10 0
+BBX 7 4 1 10
+BITMAP
+C6
+7C
+38
+10
+ENDCHAR
+STARTCHAR uni02C8
+ENCODING 712
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 2 5 1 9
+BITMAP
+C0
+C0
+C0
+C0
+C0
+ENDCHAR
+STARTCHAR macron
+ENCODING 713
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 2 1 10
+BITMAP
+FC
+FC
+ENDCHAR
+STARTCHAR uni02CA
+ENCODING 714
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 10
+BITMAP
+18
+38
+70
+C0
+ENDCHAR
+STARTCHAR uni02CB
+ENCODING 715
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 10
+BITMAP
+C0
+E0
+70
+18
+ENDCHAR
+STARTCHAR uni02CD
+ENCODING 717
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 2 1 -3
+BITMAP
+FC
+FC
+ENDCHAR
+STARTCHAR uni02CE
+ENCODING 718
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 -5
+BITMAP
+C0
+E0
+70
+18
+ENDCHAR
+STARTCHAR uni02CF
+ENCODING 719
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 -5
+BITMAP
+18
+38
+70
+C0
+ENDCHAR
+STARTCHAR breve
+ENCODING 728
+SWIDTH 333 0
+DWIDTH 8 0
+BBX 6 3 1 10
+BITMAP
+84
+CC
+78
+ENDCHAR
+STARTCHAR dotaccent
+ENCODING 729
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 2 2 2 10
+BITMAP
+C0
+C0
+ENDCHAR
+STARTCHAR ring
+ENCODING 730
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 4 4 1 10
+BITMAP
+60
+90
+90
+60
+ENDCHAR
+STARTCHAR ogonek
+ENCODING 731
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 4 4 1 -4
+BITMAP
+60
+C0
+D0
+60
+ENDCHAR
+STARTCHAR tilde
+ENCODING 732
+SWIDTH 333 0
+DWIDTH 10 0
+BBX 8 3 1 10
+BITMAP
+31
+7E
+8C
+ENDCHAR
+STARTCHAR hungarumlaut
+ENCODING 733
+SWIDTH 333 0
+DWIDTH 9 0
+BBX 7 4 1 10
+BITMAP
+66
+66
+CC
+88
+ENDCHAR
+STARTCHAR uni02EE
+ENCODING 750
+SWIDTH 481 0
+DWIDTH 10 0
+BBX 9 7 0 7
+BITMAP
+6300
+F780
+F780
+7380
+2100
+4200
+8400
+ENDCHAR
+STARTCHAR uni037E
+ENCODING 894
+SWIDTH 278 0
+DWIDTH 6 0
+BBX 4 12 1 -3
+BITMAP
+60
+F0
+F0
+60
+00
+60
+F0
+F0
+70
+20
+40
+80
+ENDCHAR
+STARTCHAR tonos
+ENCODING 900
+SWIDTH 333 0
+DWIDTH 7 0
+BBX 5 4 1 10
+BITMAP
+18
+38
+70
+C0
+ENDCHAR
+STARTCHAR dieresistonos
+ENCODING 901
+SWIDTH 333 0
+DWIDTH 10 0
+BBX 6 7 2 10
+BITMAP
+0C
+1C
+38
+60
+00
+CC
+CC
+ENDCHAR
+STARTCHAR anoteleia
+ENCODING 903
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 4 4 0 3
+BITMAP
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR mu
+ENCODING 956
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 -4
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+7EF0
+6000
+7000
+7000
+2000
+ENDCHAR
+STARTCHAR uni1E00
+ENCODING 7680
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 19 0 -5
+BITMAP
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+0000
+0180
+0240
+0240
+0180
+ENDCHAR
+STARTCHAR uni1E01
+ENCODING 7681
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 14 0 -5
+BITMAP
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+0000
+0C00
+1200
+1200
+0C00
+ENDCHAR
+STARTCHAR uni1E02
+ENCODING 7682
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 17 1 0
+BITMAP
+0600
+0600
+0000
+FFC0
+71E0
+70E0
+70E0
+70E0
+71C0
+7F80
+70E0
+70F0
+7070
+7070
+7070
+70E0
+FF80
+ENDCHAR
+STARTCHAR uni1E03
+ENCODING 7683
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 12 17 -1 0
+BITMAP
+1800
+1800
+0000
+F000
+7000
+7000
+7000
+7000
+7780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+6F80
+ENDCHAR
+STARTCHAR uni1E04
+ENCODING 7684
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 17 1 -3
+BITMAP
+FFC0
+71E0
+70E0
+70E0
+70E0
+71C0
+7F80
+70E0
+70F0
+7070
+7070
+7070
+70E0
+FF80
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E05
+ENCODING 7685
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 12 17 -1 -3
+BITMAP
+F000
+7000
+7000
+7000
+7000
+7780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+6F80
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E06
+ENCODING 7686
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 17 1 -3
+BITMAP
+FFC0
+71E0
+70E0
+70E0
+70E0
+71C0
+7F80
+70E0
+70F0
+7070
+7070
+7070
+70E0
+FF80
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E07
+ENCODING 7687
+SWIDTH 648 0
+DWIDTH 12 0
+BBX 12 17 -1 -3
+BITMAP
+F000
+7000
+7000
+7000
+7000
+7780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+6F80
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E08
+ENCODING 7688
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 12 23 1 -4
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E000
+F010
+7010
+7820
+3C60
+0F80
+0400
+0700
+0300
+0E00
+ENDCHAR
+STARTCHAR uni1E09
+ENCODING 7689
+SWIDTH 556 0
+DWIDTH 10 0
+BBX 9 18 0 -4
+BITMAP
+0600
+0E00
+1C00
+3000
+0000
+1F00
+7380
+E180
+E000
+E000
+E000
+E080
+7180
+1E00
+1000
+1C00
+0C00
+3800
+ENDCHAR
+STARTCHAR uni1E0A
+ENCODING 7690
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0300
+0300
+0000
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+ENDCHAR
+STARTCHAR uni1E0B
+ENCODING 7691
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 17 0 0
+BITMAP
+0180
+0180
+0000
+01E0
+00E0
+00E0
+00E0
+00E0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+ENDCHAR
+STARTCHAR uni1E0C
+ENCODING 7692
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E0D
+ENCODING 7693
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 17 0 -3
+BITMAP
+01E0
+00E0
+00E0
+00E0
+00E0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E0E
+ENCODING 7694
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+0000
+0FC0
+0FC0
+ENDCHAR
+STARTCHAR uni1E0F
+ENCODING 7695
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 17 0 -3
+BITMAP
+01E0
+00E0
+00E0
+00E0
+00E0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E10
+ENCODING 7696
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 -4
+BITMAP
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+0400
+0700
+0300
+0E00
+ENDCHAR
+STARTCHAR uni1E11
+ENCODING 7697
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 18 0 -4
+BITMAP
+01E0
+00E0
+00E0
+00E0
+00E0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+0400
+0700
+0300
+0E00
+ENDCHAR
+STARTCHAR uni1E12
+ENCODING 7698
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 -5
+BITMAP
+FFC0
+70F0
+7078
+7038
+703C
+701C
+701C
+701C
+701C
+703C
+7038
+7078
+70F0
+FFC0
+0000
+0200
+0700
+0F80
+18C0
+ENDCHAR
+STARTCHAR uni1E13
+ENCODING 7699
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 19 0 -5
+BITMAP
+01E0
+00E0
+00E0
+00E0
+00E0
+1EE0
+71E0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71E0
+1EF0
+0000
+0200
+0700
+0F80
+18C0
+ENDCHAR
+STARTCHAR uni1E14
+ENCODING 7700
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 22 1 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+1F80
+1F80
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni1E15
+ENCODING 7701
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 17 0 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+3F00
+3F00
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni1E16
+ENCODING 7702
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 22 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+1F80
+1F80
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni1E17
+ENCODING 7703
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 17 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+3F00
+3F00
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni1E18
+ENCODING 7704
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 19 1 -5
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0000
+0400
+0E00
+1F00
+3180
+ENDCHAR
+STARTCHAR uni1E19
+ENCODING 7705
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 14 0 -5
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0000
+0800
+1C00
+3E00
+6300
+ENDCHAR
+STARTCHAR uni1E1A
+ENCODING 7706
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 -4
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0000
+1880
+3F00
+4600
+ENDCHAR
+STARTCHAR uni1E1B
+ENCODING 7707
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 -4
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0000
+1880
+3F00
+4600
+ENDCHAR
+STARTCHAR uni1E1C
+ENCODING 7708
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 22 1 -4
+BITMAP
+2100
+3300
+1E00
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0800
+0E00
+0600
+1C00
+ENDCHAR
+STARTCHAR uni1E1D
+ENCODING 7709
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 17 0 -4
+BITMAP
+2100
+3300
+1E00
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0800
+0E00
+0600
+1C00
+ENDCHAR
+STARTCHAR uni1E1E
+ENCODING 7710
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+0600
+0600
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7320
+7F00
+7300
+7100
+7100
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR uni1E1F
+ENCODING 7711
+SWIDTH 389 0
+DWIDTH 7 0
+BBX 8 17 0 0
+BITMAP
+18
+18
+00
+1E
+37
+77
+70
+70
+FC
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni1E20
+ENCODING 7712
+SWIDTH 833 0
+DWIDTH 15 0
+BBX 13 17 1 0
+BITMAP
+1F80
+1F80
+0000
+0F90
+3C70
+7830
+7030
+F010
+E010
+E000
+E000
+E0F8
+F070
+7070
+7870
+3CF0
+0F90
+ENDCHAR
+STARTCHAR uni1E21
+ENCODING 7713
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 11 18 0 -4
+BITMAP
+1F80
+1F80
+0000
+0060
+00E0
+3F00
+7380
+6180
+6180
+7380
+3F00
+6000
+7F80
+3FC0
+C1C0
+C0C0
+E180
+7F00
+ENDCHAR
+STARTCHAR uni1E22
+ENCODING 7714
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0300
+0300
+0000
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+ENDCHAR
+STARTCHAR uni1E23
+ENCODING 7715
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 0
+BITMAP
+1800
+1800
+0000
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR uni1E24
+ENCODING 7716
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E25
+ENCODING 7717
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 -3
+BITMAP
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E26
+ENCODING 7718
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0CC0
+0CC0
+0000
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+ENDCHAR
+STARTCHAR uni1E27
+ENCODING 7719
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 0
+BITMAP
+6600
+6600
+0000
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR uni1E28
+ENCODING 7720
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 18 1 -4
+BITMAP
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+0200
+0380
+0180
+0700
+ENDCHAR
+STARTCHAR uni1E29
+ENCODING 7721
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 18 0 -4
+BITMAP
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0400
+0700
+0300
+0E00
+ENDCHAR
+STARTCHAR uni1E2A
+ENCODING 7722
+SWIDTH 870 0
+DWIDTH 16 0
+BBX 14 18 1 -4
+BITMAP
+FCFC
+7038
+7038
+7038
+7038
+7038
+7FF8
+7038
+7038
+7038
+7038
+7038
+7038
+FCFC
+0000
+0840
+0CC0
+0780
+ENDCHAR
+STARTCHAR uni1E2B
+ENCODING 7723
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 18 0 -4
+BITMAP
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+1080
+1980
+0F00
+ENDCHAR
+STARTCHAR uni1E2C
+ENCODING 7724
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 8 18 0 -4
+BITMAP
+3E
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+3E
+00
+31
+7E
+8C
+ENDCHAR
+STARTCHAR uni1E2D
+ENCODING 7725
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 8 18 -2 -4
+BITMAP
+1C
+1C
+1C
+00
+00
+3C
+1C
+1C
+1C
+1C
+1C
+1C
+1C
+3E
+00
+31
+7E
+8C
+ENDCHAR
+STARTCHAR uni1E2E
+ENCODING 7726
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 6 22 2 0
+BITMAP
+0C
+1C
+38
+60
+00
+CC
+CC
+00
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni1E2F
+ENCODING 7727
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 6 17 0 0
+BITMAP
+0C
+1C
+38
+60
+00
+CC
+CC
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni1E30
+ENCODING 7728
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+ENDCHAR
+STARTCHAR uni1E31
+ENCODING 7729
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 19 0 0
+BITMAP
+0C00
+1C00
+3800
+6000
+0000
+F000
+7000
+7000
+7000
+7000
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+ENDCHAR
+STARTCHAR uni1E32
+ENCODING 7730
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 17 1 -3
+BITMAP
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1E33
+ENCODING 7731
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 17 0 -3
+BITMAP
+F000
+7000
+7000
+7000
+7000
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E34
+ENCODING 7732
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 17 1 -3
+BITMAP
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+0000
+07E0
+07E0
+ENDCHAR
+STARTCHAR uni1E35
+ENCODING 7733
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 12 17 0 -3
+BITMAP
+F000
+7000
+7000
+7000
+7000
+73E0
+7180
+7200
+7600
+7F00
+7780
+73C0
+71E0
+FBF0
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E36
+ENCODING 7734
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 17 1 -3
+BITMAP
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E37
+ENCODING 7735
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 5 17 0 -3
+BITMAP
+F0
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E38
+ENCODING 7736
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 20 1 -3
+BITMAP
+7E00
+7E00
+0000
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E39
+ENCODING 7737
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 6 20 -1 -3
+BITMAP
+FC
+FC
+00
+78
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+7C
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E3A
+ENCODING 7738
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 17 1 -3
+BITMAP
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+0000
+3F00
+3F00
+ENDCHAR
+STARTCHAR uni1E3B
+ENCODING 7739
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 6 17 0 -3
+BITMAP
+F0
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+00
+FC
+FC
+ENDCHAR
+STARTCHAR uni1E3C
+ENCODING 7740
+SWIDTH 722 0
+DWIDTH 12 0
+BBX 11 19 1 -5
+BITMAP
+FC00
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7000
+7020
+7020
+7060
+70E0
+FFE0
+0000
+0400
+0E00
+1F00
+3180
+ENDCHAR
+STARTCHAR uni1E3D
+ENCODING 7741
+SWIDTH 352 0
+DWIDTH 6 0
+BBX 7 19 -1 -5
+BITMAP
+78
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+38
+7C
+00
+10
+38
+7C
+C6
+ENDCHAR
+STARTCHAR uni1E3E
+ENCODING 7742
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 17 19 1 0
+BITMAP
+003000
+007000
+00E000
+018000
+000000
+7C0780
+3C0F00
+3E0F00
+2E1F00
+2F1700
+2F1700
+273700
+27A700
+23E700
+23C700
+23C700
+21C700
+718700
+F88F80
+ENDCHAR
+STARTCHAR uni1E3F
+ENCODING 7743
+SWIDTH 963 0
+DWIDTH 20 0
+BBX 19 14 0 0
+BITMAP
+003000
+007000
+00E000
+018000
+000000
+F7DF80
+79F3C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+F9F3E0
+ENDCHAR
+STARTCHAR uni1E40
+ENCODING 7744
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 17 17 1 0
+BITMAP
+00C000
+00C000
+000000
+7C0780
+3C0F00
+3E0F00
+2E1F00
+2F1700
+2F1700
+273700
+27A700
+23E700
+23C700
+23C700
+21C700
+718700
+F88F80
+ENDCHAR
+STARTCHAR uni1E41
+ENCODING 7745
+SWIDTH 963 0
+DWIDTH 20 0
+BBX 19 12 0 0
+BITMAP
+00C000
+00C000
+000000
+F7DF80
+79F3C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+F9F3E0
+ENDCHAR
+STARTCHAR uni1E42
+ENCODING 7746
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 17 17 1 -3
+BITMAP
+7C0780
+3C0F00
+3E0F00
+2E1F00
+2F1700
+2F1700
+273700
+27A700
+23E700
+23C700
+23C700
+21C700
+718700
+F88F80
+000000
+00C000
+00C000
+ENDCHAR
+STARTCHAR uni1E43
+ENCODING 7747
+SWIDTH 963 0
+DWIDTH 20 0
+BBX 19 12 0 -3
+BITMAP
+F7DF80
+79F3C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+F9F3E0
+000000
+006000
+006000
+ENDCHAR
+STARTCHAR uni1E44
+ENCODING 7748
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 1 0
+BITMAP
+0300
+0300
+0000
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR uni1E45
+ENCODING 7749
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 0
+BITMAP
+0600
+0600
+0000
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+ENDCHAR
+STARTCHAR uni1E46
+ENCODING 7750
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 1 -3
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E47
+ENCODING 7751
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 -3
+BITMAP
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E48
+ENCODING 7752
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 1 -3
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+0000
+0FC0
+0FC0
+ENDCHAR
+STARTCHAR uni1E49
+ENCODING 7753
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 -3
+BITMAP
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E4A
+ENCODING 7754
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 19 1 -5
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+2F08
+2788
+2388
+21C8
+21E8
+20E8
+2078
+2078
+7038
+F818
+0000
+0100
+0380
+07C0
+0C60
+ENDCHAR
+STARTCHAR uni1E4B
+ENCODING 7755
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 -5
+BITMAP
+F7C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+0200
+0700
+0F80
+18C0
+ENDCHAR
+STARTCHAR uni1E4C
+ENCODING 7756
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 23 0 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+0310
+07E0
+08C0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1E4D
+ENCODING 7757
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+1880
+3F00
+4600
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1E4E
+ENCODING 7758
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 21 0 0
+BITMAP
+0660
+0660
+0000
+0310
+07E0
+08C0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1E4F
+ENCODING 7759
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 0
+BITMAP
+3300
+3300
+0000
+1880
+3F00
+4600
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1E50
+ENCODING 7760
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 22 0 0
+BITMAP
+0600
+0700
+0380
+00C0
+0000
+07E0
+07E0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1E51
+ENCODING 7761
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 17 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+1F80
+1F80
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1E52
+ENCODING 7762
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 22 0 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+07E0
+07E0
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1E53
+ENCODING 7763
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 17 0 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+1F80
+1F80
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1E54
+ENCODING 7764
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 12 19 1 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+FFE0
+70F0
+7070
+7070
+7070
+70F0
+71E0
+7F80
+7000
+7000
+7000
+7000
+7000
+FC00
+ENDCHAR
+STARTCHAR uni1E55
+ENCODING 7765
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 12 18 -1 -4
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+E780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+7780
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR uni1E56
+ENCODING 7766
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 12 17 1 0
+BITMAP
+0600
+0600
+0000
+FFE0
+70F0
+7070
+7070
+7070
+70F0
+71E0
+7F80
+7000
+7000
+7000
+7000
+7000
+FC00
+ENDCHAR
+STARTCHAR uni1E57
+ENCODING 7767
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 12 16 -1 -4
+BITMAP
+0600
+0600
+0000
+E780
+78E0
+7070
+7070
+7070
+7070
+7070
+78E0
+7780
+7000
+7000
+7000
+F800
+ENDCHAR
+STARTCHAR uni1E58
+ENCODING 7768
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 17 1 0
+BITMAP
+0600
+0600
+0000
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+ENDCHAR
+STARTCHAR uni1E59
+ENCODING 7769
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 12 0 0
+BITMAP
+18
+18
+00
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+ENDCHAR
+STARTCHAR uni1E5A
+ENCODING 7770
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E5B
+ENCODING 7771
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 12 0 -3
+BITMAP
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E5C
+ENCODING 7772
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 20 1 -3
+BITMAP
+0FC0
+0FC0
+0000
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E5D
+ENCODING 7773
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 15 0 -3
+BITMAP
+7E
+7E
+00
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E5E
+ENCODING 7774
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+FFE0
+70F0
+7070
+7070
+70F0
+71E0
+7F80
+71C0
+71E0
+70E0
+70E0
+70F0
+7074
+F878
+0000
+0FC0
+0FC0
+ENDCHAR
+STARTCHAR uni1E5F
+ENCODING 7775
+SWIDTH 519 0
+DWIDTH 9 0
+BBX 8 12 0 -3
+BITMAP
+F7
+7B
+73
+70
+70
+70
+70
+70
+F8
+00
+FC
+FC
+ENDCHAR
+STARTCHAR uni1E60
+ENCODING 7776
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 17 0 0
+BITMAP
+0C00
+0C00
+0000
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+ENDCHAR
+STARTCHAR uni1E61
+ENCODING 7777
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 12 0 0
+BITMAP
+1800
+1800
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR uni1E62
+ENCODING 7778
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 17 0 -3
+BITMAP
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E63
+ENCODING 7779
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 12 0 -3
+BITMAP
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR uni1E64
+ENCODING 7780
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 22 0 0
+BITMAP
+0600
+0600
+0000
+0300
+0700
+0E00
+1800
+0000
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+ENDCHAR
+STARTCHAR uni1E65
+ENCODING 7781
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 17 0 0
+BITMAP
+0C00
+0C00
+0000
+0600
+0E00
+1C00
+3000
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR uni1E66
+ENCODING 7782
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 10 17 0 0
+BITMAP
+0C00
+0C00
+0000
+6180
+3300
+1E00
+0C00
+0000
+3F80
+7180
+7880
+7E00
+3F00
+0F80
+83C0
+C780
+BF00
+ENDCHAR
+STARTCHAR uni1E67
+ENCODING 7783
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 17 0 0
+BITMAP
+1800
+1800
+0000
+C300
+6600
+3C00
+1800
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+ENDCHAR
+STARTCHAR uni1E68
+ENCODING 7784
+SWIDTH 667 0
+DWIDTH 12 0
+BBX 11 20 0 -3
+BITMAP
+0C00
+0C00
+0000
+3F40
+61C0
+C0C0
+C040
+E000
+FE00
+7FC0
+7FE0
+0FE0
+80E0
+8060
+C060
+E0C0
+BF80
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E69
+ENCODING 7785
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 15 0 -3
+BITMAP
+1800
+1800
+0000
+3D00
+6300
+E100
+FC00
+7F00
+0F80
+8380
+C300
+BE00
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR uni1E6A
+ENCODING 7786
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 0
+BITMAP
+0600
+0600
+0000
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+ENDCHAR
+STARTCHAR uni1E6B
+ENCODING 7787
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 16 0 0
+BITMAP
+30
+30
+00
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+ENDCHAR
+STARTCHAR uni1E6C
+ENCODING 7788
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 -3
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1E6D
+ENCODING 7789
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 16 0 -3
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1E6E
+ENCODING 7790
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 17 1 -3
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E6F
+ENCODING 7791
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 16 0 -3
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+00
+FC
+FC
+ENDCHAR
+STARTCHAR uni1E70
+ENCODING 7792
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 19 1 -5
+BITMAP
+FFE0
+CE60
+CE60
+8E20
+8E20
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+0E00
+1F00
+0000
+0400
+0E00
+1F00
+3180
+ENDCHAR
+STARTCHAR uni1E71
+ENCODING 7793
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 18 0 -5
+BITMAP
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+00
+10
+38
+7C
+C6
+ENDCHAR
+STARTCHAR uni1E72
+ENCODING 7794
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+0000
+1980
+1980
+ENDCHAR
+STARTCHAR uni1E73
+ENCODING 7795
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 -3
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+0000
+1980
+1980
+ENDCHAR
+STARTCHAR uni1E74
+ENCODING 7796
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 18 1 -4
+BITMAP
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+0000
+0C40
+1F80
+2300
+ENDCHAR
+STARTCHAR uni1E75
+ENCODING 7797
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 13 0 -4
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+0000
+0C40
+1F80
+2300
+ENDCHAR
+STARTCHAR uni1E76
+ENCODING 7798
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 19 1 -5
+BITMAP
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+0000
+0200
+0700
+0F80
+18C0
+ENDCHAR
+STARTCHAR uni1E77
+ENCODING 7799
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 14 0 -5
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+0000
+0200
+0700
+0F80
+18C0
+ENDCHAR
+STARTCHAR uni1E78
+ENCODING 7800
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 23 1 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0620
+0FC0
+1180
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni1E79
+ENCODING 7801
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 18 0 0
+BITMAP
+0180
+0380
+0700
+0C00
+0000
+0C40
+1F80
+2300
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni1E7A
+ENCODING 7802
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 20 1 0
+BITMAP
+0CC0
+0CC0
+0000
+0FC0
+0FC0
+0000
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+ENDCHAR
+STARTCHAR uni1E7B
+ENCODING 7803
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 15 0 0
+BITMAP
+1980
+1980
+0000
+1F80
+1F80
+0000
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni1E7C
+ENCODING 7804
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0620
+0FC0
+1180
+0000
+F87C
+7038
+7830
+3820
+3820
+3C60
+1C40
+1E40
+0EC0
+0E80
+0780
+0780
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E7D
+ENCODING 7805
+SWIDTH 611 0
+DWIDTH 9 0
+BBX 10 13 -1 0
+BITMAP
+1880
+3F00
+4600
+0000
+F9C0
+7080
+7080
+3900
+3900
+1E00
+1E00
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E7E
+ENCODING 7806
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 17 0 -3
+BITMAP
+F87C
+7038
+7830
+3820
+3820
+3C60
+1C40
+1E40
+0EC0
+0E80
+0780
+0780
+0300
+0300
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1E7F
+ENCODING 7807
+SWIDTH 611 0
+DWIDTH 9 0
+BBX 10 12 -1 -3
+BITMAP
+F9C0
+7080
+7080
+3900
+3900
+1E00
+1E00
+0C00
+0C00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR Wgrave
+ENCODING 7808
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 19 0 0
+BITMAP
+030000
+038000
+01C000
+006000
+000000
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR wgrave
+ENCODING 7809
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 14 -1 0
+BITMAP
+0600
+0700
+0380
+00C0
+0000
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR Wacute
+ENCODING 7810
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 19 0 0
+BITMAP
+003000
+007000
+00E000
+018000
+000000
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR wacute
+ENCODING 7811
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 14 -1 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR Wdieresis
+ENCODING 7812
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 17 0 0
+BITMAP
+033000
+033000
+000000
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR wdieresis
+ENCODING 7813
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 12 -1 0
+BITMAP
+0CC0
+0CC0
+0000
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR uni1E86
+ENCODING 7814
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 17 0 0
+BITMAP
+00C000
+00C000
+000000
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR uni1E87
+ENCODING 7815
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 12 -1 0
+BITMAP
+0300
+0300
+0000
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR uni1E88
+ENCODING 7816
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 17 0 -3
+BITMAP
+FBF3E0
+71E1C0
+70E180
+78E100
+38F100
+39F300
+3D7200
+1D3A00
+1F3E00
+1E3C00
+0E1C00
+0E1C00
+0C1800
+040800
+000000
+00C000
+00C000
+ENDCHAR
+STARTCHAR uni1E89
+ENCODING 7817
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 12 -1 -3
+BITMAP
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1E8A
+ENCODING 7818
+SWIDTH 722 0
+DWIDTH 17 0
+BBX 16 17 0 0
+BITMAP
+0180
+0180
+0000
+7E3F
+3C1C
+1E18
+0E30
+0F60
+07C0
+03C0
+03E0
+06F0
+0C70
+1878
+303C
+703E
+F87F
+ENDCHAR
+STARTCHAR uni1E8B
+ENCODING 7819
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 12 0 0
+BITMAP
+0C00
+0C00
+0000
+FCE0
+78C0
+3D00
+1E00
+0E00
+0F00
+1780
+63C0
+E7E0
+ENDCHAR
+STARTCHAR uni1E8C
+ENCODING 7820
+SWIDTH 722 0
+DWIDTH 17 0
+BBX 16 17 0 0
+BITMAP
+0660
+0660
+0000
+7E3F
+3C1C
+1E18
+0E30
+0F60
+07C0
+03C0
+03E0
+06F0
+0C70
+1878
+303C
+703E
+F87F
+ENDCHAR
+STARTCHAR uni1E8D
+ENCODING 7821
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 12 0 0
+BITMAP
+3300
+3300
+0000
+FCE0
+78C0
+3D00
+1E00
+0E00
+0F00
+1780
+63C0
+E7E0
+ENDCHAR
+STARTCHAR uni1E8E
+ENCODING 7822
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 17 1 0
+BITMAP
+0600
+0600
+0000
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR uni1E8F
+ENCODING 7823
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 -4
+BITMAP
+0C00
+0C00
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR uni1E90
+ENCODING 7824
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 19 1 0
+BITMAP
+0400
+0E00
+1F00
+3180
+0000
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+0F00
+1E00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+ENDCHAR
+STARTCHAR uni1E91
+ENCODING 7825
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 14 0 0
+BITMAP
+08
+1C
+3E
+63
+00
+FF
+CF
+8E
+1C
+38
+39
+71
+F3
+FF
+ENDCHAR
+STARTCHAR uni1E92
+ENCODING 7826
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 17 1 -3
+BITMAP
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+0F00
+1E00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1E93
+ENCODING 7827
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 12 0 -3
+BITMAP
+FF
+CF
+8E
+1C
+38
+39
+71
+F3
+FF
+00
+18
+18
+ENDCHAR
+STARTCHAR uni1E94
+ENCODING 7828
+SWIDTH 667 0
+DWIDTH 13 0
+BBX 11 17 1 -3
+BITMAP
+FFE0
+E1E0
+C1C0
+83C0
+8780
+0700
+0F00
+1E00
+1C00
+3C20
+7820
+7060
+F0E0
+FFE0
+0000
+3F00
+3F00
+ENDCHAR
+STARTCHAR uni1E95
+ENCODING 7829
+SWIDTH 537 0
+DWIDTH 10 0
+BBX 8 12 0 -3
+BITMAP
+FF
+CF
+8E
+1C
+38
+39
+71
+F3
+FF
+00
+7E
+7E
+ENDCHAR
+STARTCHAR uni1E96
+ENCODING 7830
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 17 0 -3
+BITMAP
+F000
+7000
+7000
+7000
+7000
+77C0
+79E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+F9F0
+0000
+1F80
+1F80
+ENDCHAR
+STARTCHAR uni1E97
+ENCODING 7831
+SWIDTH 426 0
+DWIDTH 8 0
+BBX 7 16 0 0
+BITMAP
+CC
+CC
+00
+10
+30
+30
+70
+FC
+70
+70
+70
+70
+70
+72
+72
+3C
+ENDCHAR
+STARTCHAR uni1E98
+ENCODING 7832
+SWIDTH 889 0
+DWIDTH 15 0
+BBX 16 14 -1 0
+BITMAP
+0300
+0480
+0480
+0300
+0000
+FBE7
+71C2
+71C2
+39E4
+39E4
+1E78
+1E78
+0C30
+0C30
+ENDCHAR
+STARTCHAR uni1E99
+ENCODING 7833
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 -4
+BITMAP
+0C00
+1200
+1200
+0C00
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR uni1EA0
+ENCODING 7840
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 17 0 -3
+BITMAP
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1EA1
+ENCODING 7841
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 12 0 -3
+BITMAP
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EA4
+ENCODING 7844
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 23 0 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0380
+07C0
+0C60
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni1EA5
+ENCODING 7845
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 18 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+1C00
+3E00
+6300
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni1EA6
+ENCODING 7846
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 23 0 0
+BITMAP
+0C00
+0E00
+0700
+0180
+0000
+0380
+07C0
+0C60
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni1EA7
+ENCODING 7847
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 18 0 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+1C00
+3E00
+6300
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni1EAA
+ENCODING 7850
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 22 0 0
+BITMAP
+0310
+07E0
+08C0
+0000
+0380
+07C0
+0C60
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni1EAB
+ENCODING 7851
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 17 0 0
+BITMAP
+1880
+3F00
+4600
+0000
+1C00
+3E00
+6300
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni1EAC
+ENCODING 7852
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 22 0 -3
+BITMAP
+0200
+0700
+0F80
+18C0
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1EAD
+ENCODING 7853
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 17 0 -3
+BITMAP
+0400
+0E00
+1F00
+3180
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EAE
+ENCODING 7854
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 23 0 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0840
+0CC0
+0780
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni1EAF
+ENCODING 7855
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 18 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+2100
+3300
+1E00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni1EB0
+ENCODING 7856
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 23 0 0
+BITMAP
+0C00
+0E00
+0700
+0180
+0000
+0840
+0CC0
+0780
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni1EB1
+ENCODING 7857
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 18 0 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+2100
+3300
+1E00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni1EB4
+ENCODING 7860
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 22 0 0
+BITMAP
+0620
+0FC0
+1180
+0000
+0840
+0CC0
+0780
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni1EB5
+ENCODING 7861
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 17 0 0
+BITMAP
+1880
+3F00
+4600
+0000
+2100
+3300
+1E00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+ENDCHAR
+STARTCHAR uni1EB6
+ENCODING 7862
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 21 0 -3
+BITMAP
+0840
+0CC0
+0780
+0000
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1EB7
+ENCODING 7863
+SWIDTH 611 0
+DWIDTH 11 0
+BBX 10 16 0 -3
+BITMAP
+2100
+3300
+1E00
+0000
+7F00
+E380
+C380
+0780
+3B80
+E380
+E380
+E780
+7BC0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EB8
+ENCODING 7864
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 17 1 -3
+BITMAP
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EB9
+ENCODING 7865
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 12 0 -3
+BITMAP
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EBC
+ENCODING 7868
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 18 1 0
+BITMAP
+0C40
+1F80
+2300
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni1EBD
+ENCODING 7869
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 13 0 0
+BITMAP
+1880
+3F00
+4600
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni1EBE
+ENCODING 7870
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 23 1 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+0E00
+1F00
+3180
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni1EBF
+ENCODING 7871
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 18 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+0E00
+1F00
+3180
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni1EC0
+ENCODING 7872
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 23 1 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+0E00
+1F00
+3180
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni1EC1
+ENCODING 7873
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 18 0 0
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+0E00
+1F00
+3180
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni1EC4
+ENCODING 7876
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 22 1 0
+BITMAP
+0C40
+1F80
+2300
+0000
+0E00
+1F00
+3180
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+ENDCHAR
+STARTCHAR uni1EC5
+ENCODING 7877
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 17 0 0
+BITMAP
+0C40
+1F80
+2300
+0000
+0E00
+1F00
+3180
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+ENDCHAR
+STARTCHAR uni1EC6
+ENCODING 7878
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 22 1 -3
+BITMAP
+0400
+0E00
+1F00
+3180
+0000
+FFE0
+70E0
+7060
+7120
+7120
+7300
+7F00
+7300
+7100
+7120
+7020
+7060
+70E0
+FFE0
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1EC7
+ENCODING 7879
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 10 17 0 -3
+BITMAP
+0400
+0E00
+1F00
+3180
+0000
+1E00
+7380
+E1C0
+E1C0
+FFC0
+E000
+E040
+70C0
+1F00
+0000
+0C00
+0C00
+ENDCHAR
+STARTCHAR uni1ECA
+ENCODING 7882
+SWIDTH 444 0
+DWIDTH 9 0
+BBX 5 17 2 -3
+BITMAP
+F8
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+70
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1ECB
+ENCODING 7883
+SWIDTH 370 0
+DWIDTH 6 0
+BBX 5 17 0 -3
+BITMAP
+70
+70
+70
+00
+00
+F0
+70
+70
+70
+70
+70
+70
+70
+F8
+00
+30
+30
+ENDCHAR
+STARTCHAR uni1ECC
+ENCODING 7884
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 17 0 -3
+BITMAP
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1ECD
+ENCODING 7885
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 12 0 -3
+BITMAP
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1ED0
+ENCODING 7888
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 23 0 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+0380
+07C0
+0C60
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1ED1
+ENCODING 7889
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 0
+BITMAP
+0300
+0700
+0E00
+1800
+0000
+0E00
+1F00
+3180
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1ED2
+ENCODING 7890
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 23 0 0
+BITMAP
+0600
+0700
+0380
+00C0
+0000
+0380
+07C0
+0C60
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1ED3
+ENCODING 7891
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+0E00
+1F00
+3180
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1ED6
+ENCODING 7894
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 22 0 0
+BITMAP
+0310
+07E0
+08C0
+0000
+0380
+07C0
+0C60
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+ENDCHAR
+STARTCHAR uni1ED7
+ENCODING 7895
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 17 0 0
+BITMAP
+0C40
+1F80
+2300
+0000
+0E00
+1F00
+3180
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1ED8
+ENCODING 7896
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 22 0 -3
+BITMAP
+0100
+0380
+07C0
+0C60
+0000
+0FE0
+3C78
+783C
+701C
+F01E
+E00E
+E00E
+E00E
+E00E
+F01E
+701C
+783C
+3C78
+0FE0
+0000
+0180
+0180
+ENDCHAR
+STARTCHAR uni1ED9
+ENCODING 7897
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 17 0 -3
+BITMAP
+0400
+0E00
+1F00
+3180
+0000
+1F00
+71C0
+E0E0
+E0E0
+E0E0
+E0E0
+E0E0
+71C0
+1F00
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1EDA
+ENCODING 7898
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 18 19 0 0
+BITMAP
+001800
+003800
+007000
+00C000
+000000
+0FE180
+3C7BC0
+783FC0
+701DC0
+F01E80
+E00F00
+E00E00
+E00E00
+E00E00
+F01E00
+701C00
+783C00
+3C7800
+0FE000
+ENDCHAR
+STARTCHAR uni1EDB
+ENCODING 7899
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 14 14 0 0
+BITMAP
+00C0
+01C0
+0380
+0600
+0000
+1F18
+71FC
+E0FC
+E0FC
+E0E8
+E0F0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1EDC
+ENCODING 7900
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 18 19 0 0
+BITMAP
+018000
+01C000
+00E000
+003000
+000000
+0FE180
+3C7BC0
+783FC0
+701DC0
+F01E80
+E00F00
+E00E00
+E00E00
+E00E00
+F01E00
+701C00
+783C00
+3C7800
+0FE000
+ENDCHAR
+STARTCHAR uni1EDD
+ENCODING 7901
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 14 14 0 0
+BITMAP
+0600
+0700
+0380
+00C0
+0000
+1F18
+71FC
+E0FC
+E0FC
+E0E8
+E0F0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1EE0
+ENCODING 7904
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 18 18 0 0
+BITMAP
+00C400
+01F800
+023000
+000000
+0FE180
+3C7BC0
+783FC0
+701DC0
+F01E80
+E00F00
+E00E00
+E00E00
+E00E00
+F01E00
+701C00
+783C00
+3C7800
+0FE000
+ENDCHAR
+STARTCHAR uni1EE1
+ENCODING 7905
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 14 13 0 0
+BITMAP
+0310
+07E0
+08C0
+0000
+1F18
+71FC
+E0FC
+E0FC
+E0E8
+E0F0
+E0E0
+71C0
+1F00
+ENDCHAR
+STARTCHAR uni1EE2
+ENCODING 7906
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 18 17 0 -3
+BITMAP
+0FE180
+3C7BC0
+783FC0
+701DC0
+F01E80
+E00F00
+E00E00
+E00E00
+E00E00
+F01E00
+701C00
+783C00
+3C7800
+0FE000
+000000
+018000
+018000
+ENDCHAR
+STARTCHAR uni1EE3
+ENCODING 7907
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 14 12 0 -3
+BITMAP
+1F18
+71FC
+E0FC
+E0FC
+E0E8
+E0F0
+E0E0
+71C0
+1F00
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1EE4
+ENCODING 7908
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 14 17 1 -3
+BITMAP
+F87C
+7038
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+7010
+3820
+1FC0
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1EE5
+ENCODING 7909
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 12 12 0 -3
+BITMAP
+F1E0
+70E0
+70E0
+70E0
+70E0
+70E0
+70E0
+79E0
+3EF0
+0000
+0600
+0600
+ENDCHAR
+STARTCHAR uni1EE8
+ENCODING 7912
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 17 19 1 0
+BITMAP
+003000
+007000
+00E000
+018000
+000000
+F87F00
+703F80
+701780
+701380
+701100
+701200
+701400
+701000
+701000
+701000
+701000
+701000
+382000
+1FC000
+ENDCHAR
+STARTCHAR uni1EE9
+ENCODING 7913
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 15 14 0 0
+BITMAP
+0060
+00E0
+01C0
+0300
+0000
+F1EC
+70FE
+70FE
+70EE
+70E4
+70E8
+70F0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni1EEA
+ENCODING 7914
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 17 19 1 0
+BITMAP
+030000
+038000
+01C000
+006000
+000000
+F87F00
+703F80
+701780
+701380
+701100
+701200
+701400
+701000
+701000
+701000
+701000
+701000
+382000
+1FC000
+ENDCHAR
+STARTCHAR uni1EEB
+ENCODING 7915
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 15 14 0 0
+BITMAP
+0600
+0700
+0380
+00C0
+0000
+F1EC
+70FE
+70FE
+70EE
+70E4
+70E8
+70F0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni1EEE
+ENCODING 7918
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 17 18 1 0
+BITMAP
+018800
+03F000
+046000
+000000
+F87F00
+703F80
+701780
+701380
+701100
+701200
+701400
+701000
+701000
+701000
+701000
+701000
+382000
+1FC000
+ENDCHAR
+STARTCHAR uni1EEF
+ENCODING 7919
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 15 13 0 0
+BITMAP
+0310
+07E0
+08C0
+0000
+F1EC
+70FE
+70FE
+70EE
+70E4
+70E8
+70F0
+79E0
+3EF0
+ENDCHAR
+STARTCHAR uni1EF0
+ENCODING 7920
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 17 17 1 -3
+BITMAP
+F87F00
+703F80
+701780
+701380
+701100
+701200
+701400
+701000
+701000
+701000
+701000
+701000
+382000
+1FC000
+000000
+030000
+030000
+ENDCHAR
+STARTCHAR uni1EF1
+ENCODING 7921
+SWIDTH 685 0
+DWIDTH 13 0
+BBX 15 12 0 -3
+BITMAP
+F1EC
+70FE
+70FE
+70EE
+70E4
+70E8
+70F0
+79E0
+3EF0
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR Ygrave
+ENCODING 7922
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 19 1 0
+BITMAP
+1800
+1C00
+0E00
+0300
+0000
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR ygrave
+ENCODING 7923
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 18 0 -4
+BITMAP
+3000
+3800
+1C00
+0600
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR uni1EF4
+ENCODING 7924
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 17 1 -3
+BITMAP
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+0000
+0300
+0300
+ENDCHAR
+STARTCHAR uni1EF5
+ENCODING 7925
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 16 0 -7
+BITMAP
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+0000
+1800
+1800
+ENDCHAR
+STARTCHAR uni1EF8
+ENCODING 7928
+SWIDTH 722 0
+DWIDTH 15 0
+BBX 13 18 1 0
+BITMAP
+0C40
+1F80
+2300
+0000
+F878
+7030
+7820
+3860
+3C40
+1CC0
+1F80
+0F80
+0F00
+0700
+0700
+0700
+0700
+0F80
+ENDCHAR
+STARTCHAR uni1EF9
+ENCODING 7929
+SWIDTH 611 0
+DWIDTH 12 0
+BBX 11 17 0 -4
+BITMAP
+1880
+3F00
+4600
+0000
+F8E0
+7040
+7040
+3880
+3880
+1D00
+1D00
+0E00
+0E00
+0400
+C400
+E800
+7000
+ENDCHAR
+STARTCHAR uni2000
+ENCODING 8192
+SWIDTH 500 0
+DWIDTH 9 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2001
+ENCODING 8193
+SWIDTH 1000 0
+DWIDTH 19 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2002
+ENCODING 8194
+SWIDTH 500 0
+DWIDTH 9 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2003
+ENCODING 8195
+SWIDTH 1000 0
+DWIDTH 19 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2004
+ENCODING 8196
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2005
+ENCODING 8197
+SWIDTH 250 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2006
+ENCODING 8198
+SWIDTH 167 0
+DWIDTH 3 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2007
+ENCODING 8199
+SWIDTH 574 0
+DWIDTH 11 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2008
+ENCODING 8200
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2009
+ENCODING 8201
+SWIDTH 200 0
+DWIDTH 4 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni200A
+ENCODING 8202
+SWIDTH 100 0
+DWIDTH 2 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni200B
+ENCODING 8203
+SWIDTH 0 0
+DWIDTH 0 0
+BBX 1 1 0 0
+BITMAP
+00
+ENDCHAR
+STARTCHAR uni2010
+ENCODING 8208
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 5 2 0 4
+BITMAP
+F8
+F8
+ENDCHAR
+STARTCHAR uni2011
+ENCODING 8209
+SWIDTH 333 0
+DWIDTH 6 0
+BBX 5 2 0 4
+BITMAP
+F8
+F8
+ENDCHAR
+STARTCHAR figuredash
+ENCODING 8210
+SWIDTH 500 0
+DWIDTH 9 0
+BBX 9 2 0 4
+BITMAP
+FF80
+FF80
+ENDCHAR
+STARTCHAR endash
+ENCODING 8211
+SWIDTH 500 0
+DWIDTH 9 0
+BBX 9 2 0 4
+BITMAP
+FF80
+FF80
+ENDCHAR
+STARTCHAR emdash
+ENCODING 8212
+SWIDTH 1000 0
+DWIDTH 18 0
+BBX 18 2 0 4
+BITMAP
+FFFFC0
+FFFFC0
+ENDCHAR
+STARTCHAR afii00208
+ENCODING 8213
+SWIDTH 1000 0
+DWIDTH 18 0
+BBX 18 2 0 4
+BITMAP
+FFFFC0
+FFFFC0
+ENDCHAR
+STARTCHAR quoteleft
+ENCODING 8216
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 4 7 0 7
+BITMAP
+10
+20
+40
+E0
+F0
+F0
+60
+ENDCHAR
+STARTCHAR quoteright
+ENCODING 8217
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 4 7 0 7
+BITMAP
+60
+F0
+F0
+70
+20
+40
+80
+ENDCHAR
+STARTCHAR quotesinglbase
+ENCODING 8218
+SWIDTH 241 0
+DWIDTH 6 0
+BBX 4 7 1 -3
+BITMAP
+60
+F0
+F0
+70
+20
+40
+80
+ENDCHAR
+STARTCHAR quotereversed
+ENCODING 8219
+SWIDTH 241 0
+DWIDTH 5 0
+BBX 4 7 0 7
+BITMAP
+60
+F0
+F0
+E0
+40
+20
+10
+ENDCHAR
+STARTCHAR quotedblleft
+ENCODING 8220
+SWIDTH 481 0
+DWIDTH 10 0
+BBX 9 7 0 7
+BITMAP
+1080
+2100
+4200
+E700
+F780
+F780
+6300
+ENDCHAR
+STARTCHAR quotedblright
+ENCODING 8221
+SWIDTH 481 0
+DWIDTH 10 0
+BBX 9 7 0 7
+BITMAP
+6300
+F780
+F780
+7380
+2100
+4200
+8400
+ENDCHAR
+STARTCHAR quotedblbase
+ENCODING 8222
+SWIDTH 481 0
+DWIDTH 11 0
+BBX 9 7 1 -3
+BITMAP
+6300
+F780
+F780
+7380
+2100
+4200
+8400
+ENDCHAR
+STARTCHAR uni201F
+ENCODING 8223
+SWIDTH 481 0
+DWIDTH 10 0
+BBX 9 7 0 7
+BITMAP
+6300
+F780
+F780
+E700
+4200
+2100
+1080
+ENDCHAR
+STARTCHAR dagger
+ENCODING 8224
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 16 0 -2
+BITMAP
+1C00
+1C00
+0800
+C980
+FF80
+C980
+0800
+1C00
+1C00
+0800
+0800
+0800
+0800
+0800
+0800
+0800
+ENDCHAR
+STARTCHAR daggerdbl
+ENCODING 8225
+SWIDTH 500 0
+DWIDTH 10 0
+BBX 9 16 0 -2
+BITMAP
+1C00
+1C00
+0800
+C980
+FF80
+C980
+0800
+1C00
+1C00
+0800
+C980
+FF80
+C980
+0800
+1C00
+1C00
+ENDCHAR
+STARTCHAR bullet
+ENCODING 8226
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 6 6 2 4
+BITMAP
+78
+FC
+FC
+FC
+FC
+78
+ENDCHAR
+STARTCHAR ellipsis
+ENCODING 8230
+SWIDTH 1000 0
+DWIDTH 18 0
+BBX 16 4 1 0
+BITMAP
+6186
+F3CF
+F3CF
+6186
+ENDCHAR
+STARTCHAR perthousand
+ENCODING 8240
+SWIDTH 1000 0
+DWIDTH 22 0
+BBX 21 15 0 -1
+BITMAP
+38C000
+674000
+C4C000
+C48000
+C58000
+C90000
+730000
+023870
+0664C8
+04C588
+0CC588
+08C588
+18C990
+1070E0
+100000
+ENDCHAR
+STARTCHAR guilsinglleft
+ENCODING 8249
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 4 5 0 3
+BITMAP
+30
+60
+C0
+60
+30
+ENDCHAR
+STARTCHAR guilsinglright
+ENCODING 8250
+SWIDTH 333 0
+DWIDTH 5 0
+BBX 4 5 0 3
+BITMAP
+C0
+60
+30
+60
+C0
+ENDCHAR
+STARTCHAR fraction
+ENCODING 8260
+SWIDTH 167 0
+DWIDTH 3 0
+BBX 8 14 -3 0
+BITMAP
+03
+03
+06
+06
+0C
+0C
+18
+18
+30
+30
+60
+60
+C0
+C0
+ENDCHAR
+STARTCHAR oneinferior
+ENCODING 8321
+SWIDTH 344 0
+DWIDTH 6 0
+BBX 6 8 0 -4
+BITMAP
+30
+F0
+30
+30
+30
+30
+30
+FC
+ENDCHAR
+STARTCHAR twoinferior
+ENCODING 8322
+SWIDTH 344 0
+DWIDTH 6 0
+BBX 6 8 0 -4
+BITMAP
+78
+CC
+CC
+18
+30
+60
+C4
+FC
+ENDCHAR
+STARTCHAR threeinferior
+ENCODING 8323
+SWIDTH 344 0
+DWIDTH 6 0
+BBX 6 8 0 -4
+BITMAP
+78
+CC
+0C
+38
+0C
+CC
+CC
+78
+ENDCHAR
+STARTCHAR uni20A5
+ENCODING 8357
+SWIDTH 963 0
+DWIDTH 20 0
+BBX 19 14 0 -2
+BITMAP
+001800
+001800
+001800
+F7FF80
+79F3C0
+70F1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+70E1C0
+F9F3E0
+018000
+018000
+ENDCHAR
+STARTCHAR uni20A6
+ENCODING 8358
+SWIDTH 833 0
+DWIDTH 16 0
+BBX 15 14 1 0
+BITMAP
+F83E
+7C1C
+3C08
+3E08
+3FF8
+3FF8
+2388
+21C8
+3FF8
+3FF8
+2078
+2078
+7038
+F818
+ENDCHAR
+STARTCHAR uni20A9
+ENCODING 8361
+SWIDTH 981 0
+DWIDTH 19 0
+BBX 19 14 0 0
+BITMAP
+FBF3E0
+71E1C0
+70E180
+78E100
+3FFD00
+3FFF00
+3D7200
+1D3A00
+1FFE00
+1FFC00
+0E1C00
+0E1C00
+0C1800
+040800
+ENDCHAR
+STARTCHAR Euro
+ENCODING 8364
+SWIDTH 778 0
+DWIDTH 14 0
+BBX 14 14 -1 0
+BITMAP
+03E4
+0F1C
+1E0C
+1C0C
+FF84
+FF84
+3800
+3800
+FF80
+FF84
+1C04
+1E08
+0F18
+03E0
+ENDCHAR
+STARTCHAR uni20AD
+ENCODING 8365
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 14 1 0
+BITMAP
+FC7C
+7030
+7060
+70C0
+7180
+7300
+FFFE
+FFFE
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+ENDCHAR
+STARTCHAR uni2103
+ENCODING 8451
+SWIDTH 1158 0
+DWIDTH 21 0
+BBX 20 14 0 0
+BITMAP
+780F90
+CC3C70
+847830
+847030
+CCF010
+78E010
+00E000
+00E000
+00E000
+00F010
+007010
+007820
+003C60
+000F80
+ENDCHAR
+STARTCHAR uni2109
+ENCODING 8457
+SWIDTH 1102 0
+DWIDTH 20 0
+BBX 19 14 0 0
+BITMAP
+78FFE0
+CC70E0
+847060
+847120
+CC7120
+787320
+007F00
+007300
+007100
+007100
+007000
+007000
+007000
+00F800
+ENDCHAR
+STARTCHAR trademark
+ENCODING 8482
+SWIDTH 1000 0
+DWIDTH 20 0
+BBX 19 8 0 6
+BITMAP
+FFF1E0
+9971C0
+185AC0
+185AC0
+185AC0
+184CC0
+184CC0
+3CEDE0
+ENDCHAR
+STARTCHAR uni212A
+ENCODING 8490
+SWIDTH 815 0
+DWIDTH 16 0
+BBX 15 14 1 0
+BITMAP
+FC7C
+7030
+7060
+70C0
+7180
+7300
+7780
+7FC0
+7BC0
+71E0
+70F0
+70F8
+707C
+FCFE
+ENDCHAR
+STARTCHAR uni212B
+ENCODING 8491
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 18 0 0
+BITMAP
+0300
+0480
+0480
+0300
+0300
+0300
+0780
+0780
+0F80
+09C0
+09C0
+19E0
+10E0
+3FE0
+20F0
+6070
+4078
+E0FC
+ENDCHAR
+STARTCHAR uni2132
+ENCODING 8498
+SWIDTH 722 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+03E0
+01C0
+01C0
+01C0
+11C0
+11C0
+19C0
+1FC0
+99C0
+91C0
+91C0
+C1C0
+E1C0
+FFE0
+ENDCHAR
+STARTCHAR universal
+ENCODING 8704
+SWIDTH 759 0
+DWIDTH 14 0
+BBX 14 14 0 0
+BITMAP
+E0FC
+4078
+6070
+20F0
+3FE0
+10E0
+19E0
+09C0
+09C0
+0F80
+0780
+0780
+0300
+0300
+ENDCHAR
+STARTCHAR existential
+ENCODING 8707
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+E1C0
+C1C0
+91C0
+91C0
+19C0
+1FC0
+19C0
+11C0
+91C0
+81C0
+C1C0
+E1C0
+FFE0
+ENDCHAR
+STARTCHAR uni2204
+ENCODING 8708
+SWIDTH 759 0
+DWIDTH 13 0
+BBX 11 14 1 0
+BITMAP
+FFE0
+E1C0
+C1C0
+93C0
+93C0
+1BC0
+1FC0
+1FC0
+17C0
+9DC0
+8DC0
+CDC0
+F9C0
+FFE0
+ENDCHAR
+STARTCHAR minus
+ENCODING 8722
+SWIDTH 606 0
+DWIDTH 10 0
+BBX 9 2 0 4
+BITMAP
+FF80
+FF80
+ENDCHAR
+STARTCHAR fraction
+ENCODING 8725
+SWIDTH 167 0
+DWIDTH 3 0
+BBX 8 14 -3 0
+BITMAP
+03
+03
+06
+06
+0C
+0C
+18
+18
+30
+30
+60
+60
+C0
+C0
+ENDCHAR
+STARTCHAR periodcentered
+ENCODING 8729
+SWIDTH 278 0
+DWIDTH 5 0
+BBX 4 4 0 3
+BITMAP
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR uni2236
+ENCODING 8758
+SWIDTH 278 0
+DWIDTH 6 0
+BBX 4 9 1 0
+BITMAP
+60
+F0
+F0
+60
+00
+60
+F0
+F0
+60
+ENDCHAR
+STARTCHAR uni2259
+ENCODING 8793
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 11 1 2
+BITMAP
+0800
+1C00
+3E00
+6300
+0000
+FF80
+FF80
+0000
+0000
+FF80
+FF80
+ENDCHAR
+STARTCHAR uni225A
+ENCODING 8794
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 11 1 2
+BITMAP
+6300
+3E00
+1C00
+0800
+0000
+FF80
+FF80
+0000
+0000
+FF80
+FF80
+ENDCHAR
+STARTCHAR notequal
+ENCODING 8800
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 14 1 -2
+BITMAP
+0300
+0300
+0300
+0600
+FF80
+FF80
+0C00
+0C00
+FF80
+FF80
+1800
+1800
+3000
+3000
+ENDCHAR
+STARTCHAR equivalence
+ENCODING 8801
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 8 0 1
+BITMAP
+FF80
+FF80
+0000
+FF80
+FF80
+0000
+FF80
+FF80
+ENDCHAR
+STARTCHAR uni2262
+ENCODING 8802
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 9 14 0 -2
+BITMAP
+0300
+0300
+0300
+FF80
+FF80
+0600
+FF80
+FF80
+0C00
+FF80
+FF80
+1800
+3000
+3000
+ENDCHAR
+STARTCHAR lessequal
+ENCODING 8804
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 13 0 -3
+BITMAP
+00C0
+03C0
+0F00
+3C00
+F000
+F000
+3C00
+0F00
+03C0
+00C0
+0000
+FFC0
+FFC0
+ENDCHAR
+STARTCHAR greaterequal
+ENCODING 8805
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 13 0 -3
+BITMAP
+C000
+F000
+3C00
+0F00
+03C0
+03C0
+0F00
+3C00
+F000
+C000
+0000
+FFC0
+FFC0
+ENDCHAR
+STARTCHAR uni226E
+ENCODING 8814
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 14 0 -2
+BITMAP
+0300
+0300
+03C0
+07C0
+0F00
+3E00
+FC00
+FC00
+3C00
+1F00
+1BC0
+18C0
+3000
+3000
+ENDCHAR
+STARTCHAR uni226F
+ENCODING 8815
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 14 0 -2
+BITMAP
+0300
+0300
+C300
+F600
+3E00
+0F00
+0FC0
+0FC0
+0F00
+3C00
+F800
+D800
+3000
+3000
+ENDCHAR
+STARTCHAR uni2270
+ENCODING 8816
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 14 0 -3
+BITMAP
+0300
+03C0
+03C0
+0F00
+3E00
+F600
+FC00
+3C00
+0F00
+1BC0
+18C0
+1800
+FFC0
+FFC0
+ENDCHAR
+STARTCHAR uni2271
+ENCODING 8817
+SWIDTH 606 0
+DWIDTH 11 0
+BBX 10 14 0 -3
+BITMAP
+0300
+C300
+F300
+3E00
+0F00
+07C0
+0FC0
+0F00
+3C00
+F800
+D800
+1800
+FFC0
+FFC0
+ENDCHAR
+STARTCHAR fi
+ENCODING -1
+SWIDTH 685 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+0F80
+39C0
+31C0
+7000
+7000
+FFC0
+71C0
+71C0
+71C0
+71C0
+71C0
+71C0
+71C0
+FBE0
+ENDCHAR
+STARTCHAR fl
+ENCODING -1
+SWIDTH 685 0
+DWIDTH 12 0
+BBX 11 14 0 0
+BITMAP
+1EC0
+33C0
+71C0
+71C0
+71C0
+FFC0
+71C0
+71C0
+71C0
+71C0
+71C0
+71C0
+71C0
+FBE0
+ENDCHAR
+ENDFONT
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id:$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief BattFS: a filesystem for embedded platforms (implementation).
+ */
+
+#include "battfs.h"
+
+#include <cfg/debug.h>
+#include <cfg/macros.h> /* MIN, MAX */
+#include <mware/byteorder.h> /* cpu_to_xx */
+
+
+#include <string.h> /* memset, memmove */
+
+
+/**
+ * Convert from memory representation to disk structure.
+ * \note filesystem is in little-endian format.
+ */
+INLINE void battfs_to_disk(struct BattFsPageHeader *hdr, uint8_t *buf)
+{
+ STATIC_ASSERT(BATTFS_HEADER_LEN == 12);
+ buf[0] = hdr->inode;
+
+ buf[1] = hdr->fill;
+ buf[2] = hdr->fill >> 8;
+
+ buf[3] = hdr->pgoff;
+ buf[4] = hdr->pgoff >> 8;
+
+ /*
+ * Mark is at least 1 bit longer than page address.
+ * Needed to take care of wraparonds.
+ */
+ buf[5] = hdr->mark;
+ buf[6] = hdr->mark >> 8;
+
+ /*
+ * First bit used by mark, last 2 bits used by seq.
+ * Since only 2 pages with the same inode and pgoff
+ * can exist at the same time, 2 bit for seq are enough.
+ * Unused bits are set to 1.
+ */
+ buf[7] = ((hdr->mark >> 16) & 0x01) | (hdr->seq << 6) | ~(BV(7) | BV(6) | BV(0));
+
+ /*
+ * This field must be the before the last one!
+ */
+ buf[8] = hdr->fcs_free;
+ buf[9] = hdr->fcs_free >> 8;
+
+ /*
+ * This field must be the last one!
+ * This is needed because if the page is only partially
+ * written, we can use this to detect it.
+ */
+ buf[10] = hdr->fcs;
+ buf[11] = hdr->fcs >> 8;
+}
+
+/**
+ * Convert from disk structure to memory representation.
+ * \note filesystem is in little-endian format.
+ */
+INLINE void disk_to_battfs(uint8_t *buf, struct BattFsPageHeader *hdr)
+{
+ STATIC_ASSERT(BATTFS_HEADER_LEN == 12);
+ hdr->inode = buf[0];
+ hdr->fill = buf[2] << 8 | buf[1];
+ hdr->pgoff = buf[4] << 8 | buf[3];
+ hdr->mark = (mark_t)(buf[7] & 0x01) << 16 | buf[6] << 8 | buf[5];
+ hdr->seq = buf[7] >> 6;
+ hdr->fcs_free = buf[9] << 8 | buf[8];
+ hdr->fcs = buf[11] << 8 | buf[10];
+}
+
+/**
+ * Compute the fcs of the header.
+ */
+static fcs_t computeFcs(struct BattFsPageHeader *hdr)
+{
+ uint8_t buf[BATTFS_HEADER_LEN];
+ fcs_t cks;
+
+ battfs_to_disk(hdr, buf);
+ rotating_init(&cks);
+ /* fcs is at the end of whole header */
+ rotating_update(buf, BATTFS_HEADER_LEN - sizeof(fcs_t), &cks);
+ return cks;
+}
+
+/**
+ * Compute the fcs of the header marked as free.
+ */
+static fcs_t computeFcsFree(struct BattFsPageHeader *hdr)
+{
+ uint8_t buf[BATTFS_HEADER_LEN];
+ fcs_t cks;
+
+ battfs_to_disk(hdr, buf);
+ rotating_init(&cks);
+ /* fcs_free is just before fcs of whole header */
+ rotating_update(buf, BATTFS_HEADER_LEN - 2 * sizeof(fcs_t), &cks);
+ return cks;
+}
+
+
+/**
+ * Read header of page \a page.
+ * \return true on success, false otherwise.
+ * \note \a hdr is dirtyed even on errors.
+ */
+static bool battfs_readHeader(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr)
+{
+ uint8_t buf[BATTFS_HEADER_LEN];
+ /*
+ * Read header from disk.
+ * Header is actually a footer, and so
+ * resides at page end.
+ */
+ if (disk->read(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN)
+ != BATTFS_HEADER_LEN)
+ {
+ TRACEMSG("Error: page[%d]\n", page);
+ return false;
+ }
+
+ /* Fill header */
+ disk_to_battfs(buf, hdr);
+
+ return true;
+}
+
+/**
+ * Write header of page \a page.
+ * \return true on success, false otherwise.
+ * \note \a hdr is dirtyed even on errors.
+ */
+static bool battfs_writeHeader(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr)
+{
+ uint8_t buf[BATTFS_HEADER_LEN];
+
+ /* Fill buffer */
+ battfs_to_disk(hdr, buf);
+
+ /*
+ * write header to disk.
+ * Header is actually a footer, and so
+ * resides at page end.
+ */
+ if (disk->write(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN)
+ != BATTFS_HEADER_LEN)
+ {
+ TRACEMSG("Error: page[%d]\n", page);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Count the number of pages from
+ * inode 0 to \a inode in \a filelen_table.
+ */
+static pgcnt_t countPages(pgoff_t *filelen_table, inode_t inode)
+{
+ pgcnt_t cnt = 0;
+
+ for (inode_t i = 0; i < inode; i++)
+ cnt += filelen_table[i];
+
+ return cnt;
+}
+
+/**
+ * Move all pages in page allocation array from \a src to \a src + \a offset.
+ * The number of pages moved is page_count - MAX(dst, src).
+ */
+static void movePages(struct BattFsSuper *disk, pgcnt_t src, int offset)
+{
+ pgcnt_t dst = src + offset;
+ memmove(&disk->page_array[dst], &disk->page_array[src], (disk->page_count - MAX(dst, src)) * sizeof(pgcnt_t));
+
+ if (offset < 0)
+ {
+ /* Fill empty space in array with sentinel */
+ for (pgcnt_t page = disk->page_count + offset; page < disk->page_count; page++)
+ disk->page_array[page] = PAGE_UNSET_SENTINEL;
+ }
+}
+
+/**
+ * Insert \a page into page allocation array of \a disk,
+ * using \a mark to compute position.
+ */
+static void insertFreePage(struct BattFsSuper *disk, mark_t mark, pgcnt_t page)
+{
+ ASSERT(mark - disk->free_start < disk->free_next - disk->free_start);
+
+ pgcnt_t free_pos = disk->page_count - disk->free_next + mark;
+ ASSERT(free_pos < disk->page_count);
+
+ TRACEMSG("mark:%u, page:%u, free_start:%u, free_next:%u, free_pos:%u\n",
+ mark, page, disk->free_start, disk->free_next, free_pos);
+
+ ASSERT(disk->page_array[free_pos] == PAGE_UNSET_SENTINEL);
+ disk->page_array[free_pos] = page;
+}
+
+/**
+ * Mark \a page of \a disk as free.
+ * \note free_next of \a disk is used as \a page free marker
+ * and is increased by 1.
+ */
+static bool battfs_markFree(struct BattFsSuper *disk, struct BattFsPageHeader *hdr, pgcnt_t page)
+{
+ uint8_t buf[BATTFS_HEADER_LEN];
+
+ hdr->mark = disk->free_next;
+ hdr->fcs_free = computeFcsFree(hdr);
+ battfs_to_disk(hdr, buf);
+
+ if (!disk->write(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN))
+ {
+ TRACEMSG("error marking page [%d]\n", page);
+ return false;
+ }
+ else
+ {
+ disk->free_next++;
+ return true;
+ }
+}
+
+/**
+ * Determine free_start and free_next blocks for \a disk
+ * using \a minl, \a maxl, \a minh, \a maxh.
+ *
+ * Mark_t is a type that has at least 1 bit more than
+ * pgaddr_t. So all free blocks can be numbered using
+ * at most half numbers of a mark_t type.
+ * The free blocks algorithm increments by 1 the disk->free_next
+ * every time a page becomes free. So the free block sequence is
+ * guaranteed to be countiguous.
+ * Only wrap arounds may happen, but due to half size sequence limitation,
+ * there are only 4 possible situations:
+ *
+ * \verbatim
+ * |------lower half------|-------upper half-------|
+ *
+ * 1) |------minl*****maxl---|------------------------|
+ * 2) |------minl********maxl|minh******maxh----------|
+ * 3) |----------------------|----minh*******maxh-----|
+ * 4) |minl******maxl--------|------------minh****maxh|
+ * \endverbatim
+ *
+ * Situations 1 and 3 are easy to detect, while 2 and 4 require more care.
+ */
+static void findFreeStartNext(struct BattFsSuper *disk, mark_t minl, mark_t maxl, mark_t minh, mark_t maxh)
+{
+ /* Determine free_start & free_next */
+ if (maxl >= minl)
+ {
+ /* Valid interval found in lower half */
+ if (maxh >= minh)
+ {
+ /* Valid interval also found in upper half */
+ if (maxl == minh - 1)
+ {
+ /* Interval starts in lower half and ends in upper */
+ disk->free_start = minl;
+ disk->free_next = maxh;
+ }
+ else
+ {
+ /* Interval starts in upper half and ends in lower */
+ ASSERT(minl == 0);
+ ASSERT(maxh == (MAX_PAGE_ADDR | MARK_HALF_SIZE));
+
+ disk->free_start = minh;
+ disk->free_next = maxl;
+ }
+ }
+ else
+ {
+ /*
+ * Upper interval is invalid.
+ * Use lower values.
+ */
+
+ disk->free_start = minl;
+ disk->free_next = maxl;
+ }
+ }
+ else if (maxh >= minh)
+ {
+ /*
+ * Lower interval is invalid.
+ * Use upper values.
+ */
+ disk->free_start = minh;
+ disk->free_next = maxh;
+ }
+ else
+ {
+ /*
+ * No valid interval found.
+ * Hopefully the disk is brand new (or full).
+ */
+ TRACEMSG("No valid marked free block found, new disk or disk full\n");
+ disk->free_start = 0;
+ disk->free_next = -1; //to be increased later
+ }
+
+ /* free_next should contain the first usable address */
+ disk->free_next++;
+
+ TRACEMSG("Free markers:\n minl %u\n maxl %u\n minh %u\n maxh %u\n free_start %u\n free_next %u\n",
+ minl, maxl, minh, maxh, disk->free_start, disk->free_next);
+}
+
+/**
+ * Count number of pages per file on \a disk.
+ * This information is registered in \a filelen_table.
+ * Array index represent file inode, while value contained
+ * is the number of pages used by that file.
+ *
+ * \return true if ok, false on disk read errors.
+ * \note The whole disk is scanned once.
+ */
+static bool countDiskFilePages(struct BattFsSuper *disk, pgoff_t *filelen_table)
+{
+ BattFsPageHeader hdr;
+ mark_t minl, maxl, minh, maxh;
+
+ /* Initialize min and max counters to keep trace od free blocks */
+ minl = MAX_PAGE_ADDR;
+ maxl = 0;
+ minh = MAX_PAGE_ADDR | MARK_HALF_SIZE;
+ maxh = 0 | MARK_HALF_SIZE;
+
+
+ /* Count the number of disk page per file */
+ for (pgcnt_t page = 0; page < disk->page_count; page++)
+ {
+ if (!battfs_readHeader(disk, page, &hdr))
+ return false;
+
+ /* Check header FCS */
+ if (hdr.fcs == computeFcs(&hdr))
+ {
+ ASSERT(hdr.mark == MARK_PAGE_VALID);
+ ASSERT(hdr.fcs_free == FCS_FREE_VALID);
+ ASSERT(hdr.fill <= disk->page_size - BATTFS_HEADER_LEN);
+
+ /* Page is valid and is owned by a file */
+ filelen_table[hdr.inode]++;
+
+ /* Keep trace of free space */
+ disk->free_bytes += disk->page_size - BATTFS_HEADER_LEN - hdr.fill;
+ }
+ else
+ {
+ /* Increase free space */
+ disk->free_bytes += disk->page_size - BATTFS_HEADER_LEN;
+
+ /* Check if page is marked free */
+ if (hdr.fcs_free == computeFcsFree(&hdr))
+ {
+ /*
+ * This page is a valid and marked free page.
+ * Update min and max free page markers.
+ */
+ if (hdr.mark < MARK_HALF_SIZE)
+ {
+ minl = MIN(minl, hdr.mark);
+ maxl = MAX(maxl, hdr.mark);
+ }
+ else
+ {
+ minh = MIN(minh, hdr.mark);
+ maxh = MAX(maxh, hdr.mark);
+ }
+ }
+ else
+ TRACEMSG("page [%d] invalid, keeping as free\n", page);
+ }
+ }
+ findFreeStartNext(disk, minl, maxl, minh, maxh);
+ return true;
+}
+
+/**
+ * Fill page allocation array of \a disk
+ * using file lenghts in \a filelen_table.
+ *
+ * The page allocation array is an array containings all file infos.
+ * Is ordered by file, and within each file is ordered by page offset
+ * inside file.
+ * e.g. : at page array[0] you will find page address of the first page
+ * of the first file (if present).
+ * Free blocks are allocated after the last file, starting from invalid ones
+ * and continuing with the marked free ones.
+ *
+ * \return true if ok, false on disk read errors.
+ * \note The whole disk is scanned once.
+ */
+static bool fillPageArray(struct BattFsSuper *disk, pgoff_t *filelen_table)
+{
+ BattFsPageHeader hdr;
+ /* Fill page allocation array */
+ for (pgcnt_t page = 0; page < disk->page_count; page++)
+ {
+ if (!battfs_readHeader(disk, page, &hdr))
+ return false;
+
+ /* Check header FCS */
+ if (hdr.fcs == computeFcs(&hdr))
+ {
+ /* Page is valid and is owned by a file */
+ ASSERT(hdr.mark == MARK_PAGE_VALID);
+ ASSERT(hdr.fcs_free == FCS_FREE_VALID);
+
+ /* Compute array position */
+ pgcnt_t array_pos = countPages(filelen_table, hdr.inode);
+ array_pos += hdr.pgoff;
+
+ /* Check if position is already used by another page of the same file */
+ if (LIKELY(disk->page_array[array_pos] == PAGE_UNSET_SENTINEL))
+ disk->page_array[array_pos] = page;
+ else
+ {
+ BattFsPageHeader hdr_old;
+
+ if (!battfs_readHeader(disk, disk->page_array[array_pos], &hdr_old))
+ return false;
+
+ /* Check header FCS */
+ ASSERT(hdr_old.fcs == computeFcs(&hdr_old));
+
+ /* Only the very same page with a different seq number can be here */
+ ASSERT(hdr.inode == hdr_old.inode);
+ ASSERT(hdr.pgoff == hdr_old.pgoff);
+ ASSERT(hdr.mark == hdr_old.mark);
+ ASSERT(hdr.fcs_free == hdr_old.fcs_free);
+ ASSERT(hdr.seq != hdr_old.seq);
+
+ pgcnt_t new_page, old_page;
+ fill_t old_fill;
+
+ /* Fancy check to handle seq wraparound (2 bits only) */
+ if (((hdr.seq - hdr_old.seq) & 0x03) < 2)
+ {
+ /* Current header is newer than the previuos one */
+ old_page = disk->page_array[array_pos];
+ new_page = page;
+ old_fill = hdr_old.fill;
+ }
+ else
+ {
+ /* Previous header is newer than the current one */
+ old_page = page;
+ new_page = disk->page_array[array_pos];
+ old_fill = hdr.fill;
+ }
+
+ /* Set new page */
+ disk->page_array[array_pos] = new_page;
+
+ /* Add free space */
+ disk->free_bytes += old_fill;
+
+ /* Shift all array one position to the left, overwriting duplicate page */
+ array_pos -= hdr.pgoff;
+ array_pos += filelen_table[hdr.inode];
+ movePages(disk, array_pos, -1);
+
+ /* Decrease file page count */
+ filelen_table[hdr.inode]--;
+
+ /* Add old page to free pages pool */
+ if (!battfs_markFree(disk, &hdr, old_page))
+ return false;
+
+ insertFreePage(disk, hdr.mark, old_page);
+ }
+ }
+ else
+ {
+ /* Check if page is free */
+ if (hdr.fcs_free != computeFcsFree(&hdr))
+ /* Page is not a valid marked page, insert at list beginning */
+ hdr.mark = --disk->free_start;
+
+ insertFreePage(disk, hdr.mark, page);
+ }
+ }
+ return true;
+}
+
+/**
+ * Initialize and mount disk described by
+ * \a disk.
+ * \return false on errors, true otherwise.
+ */
+bool battfs_init(struct BattFsSuper *disk)
+{
+ pgoff_t filelen_table[BATTFS_MAX_FILES];
+
+ /* Sanity check */
+ ASSERT(disk->open);
+
+ /* Init disk device */
+ if (!disk->open(disk))
+ {
+ TRACEMSG("open error\n");
+ return false;
+ }
+
+ /* Disk open must set all of these */
+ ASSERT(disk->read);
+ ASSERT(disk->write);
+ ASSERT(disk->erase);
+ ASSERT(disk->close);
+ ASSERT(disk->page_size);
+ ASSERT(disk->page_count);
+ ASSERT(disk->page_count < PAGE_UNSET_SENTINEL - 1);
+ ASSERT(disk->page_array);
+
+ memset(filelen_table, 0, BATTFS_MAX_FILES * sizeof(pgoff_t));
+
+ disk->free_bytes = 0;
+ disk->disk_size = (disk_size_t)(disk->page_size - BATTFS_HEADER_LEN) * disk->page_count;
+
+ /* Count pages per file */
+ if (!countDiskFilePages(disk, filelen_table))
+ {
+ TRACEMSG("error counting file pages\n");
+ return false;
+ }
+
+ /* Once here, we have filelen_table filled with file lengths */
+
+ /* Fill page array with sentinel */
+ for (pgcnt_t page = 0; page < disk->page_count; page++)
+ disk->page_array[page] = PAGE_UNSET_SENTINEL;
+
+ /* Fill page allocation array using filelen_table */
+ if (!fillPageArray(disk, filelen_table))
+ {
+ TRACEMSG("error filling page array\n");
+ return false;
+ }
+
+ /* Init list for opened files. */
+ LIST_INIT(&disk->file_opened_list);
+ return true;
+}
+
+/**
+ * Flush file \a fd.
+ * \return 0 if ok, EOF on errors.
+ */
+static int battfs_flush(struct KFile *fd)
+{
+ (void)fd;
+ #warning TODO
+ return 0;
+}
+
+/**
+ * Close file \a fd.
+ * \return 0 if ok, EOF on errors.
+ */
+static int battfs_fileclose(struct KFile *fd)
+{
+ KFileBattFs *fdb = KFILEBATTFS(fd);
+
+ battfs_flush(fd);
+ REMOVE(&fdb->link);
+ return 0;
+}
+
+/**
+ * Read from file \a fd \a size bytes in \a buf.
+ * \return The number of bytes read.
+ */
+static size_t battfs_read(struct KFile *fd, void *_buf, size_t size)
+{
+ KFileBattFs *fdb = KFILEBATTFS(fd);
+ uint8_t *buf = (uint8_t *)_buf;
+
+ size_t total_read = 0;
+ pgoff_t pg_offset;
+ pgaddr_t addr_offset;
+ pgaddr_t read_len;
+
+ size = MIN(size, fd->size - fd->seek_pos);
+
+ while (size)
+ {
+ pg_offset = fd->seek_pos / (fdb->disk->page_size - BATTFS_HEADER_LEN);
+ addr_offset = fd->seek_pos % (fdb->disk->page_size - BATTFS_HEADER_LEN);
+ read_len = MIN(size, (size_t)(fdb->disk->page_size - BATTFS_HEADER_LEN - addr_offset));
+
+ /* Read from disk */
+ if (fdb->disk->read(fdb->disk, fdb->start[pg_offset], addr_offset, buf, read_len) != read_len)
+ {
+ #warning TODO set error?
+ }
+
+ size -= read_len;
+ fd->seek_pos += read_len;
+ total_read += read_len;
+ buf += read_len;
+ }
+ return total_read;
+}
+
+
+/**
+ * Search file \a inode in \a disk using a binary search.
+ * \return pointer to file start in disk->page_array
+ * if file exists, NULL otherwise.
+ */
+static pgcnt_t *findFile(BattFsSuper *disk, inode_t inode)
+{
+ BattFsPageHeader hdr;
+ pgcnt_t first = 0, page, last = disk->page_count -1;
+ fcs_t fcs;
+
+ while (first <= last)
+ {
+ page = (first + last) / 2;
+
+ if (!battfs_readHeader(disk, disk->page_array[page], &hdr))
+ return NULL;
+
+ fcs = computeFcs(&hdr);
+ if (hdr.fcs == fcs && hdr.inode == inode)
+ return (&disk->page_array[page]) - hdr.pgoff;
+ else if (hdr.fcs == fcs && hdr.inode < inode)
+ first = page + 1;
+ else
+ last = page - 1;
+ }
+
+ return NULL;
+}
+
+/**
+ * \return true if file \a inode exists on \a disk, false otherwise.
+ */
+bool battfs_fileExists(BattFsSuper *disk, inode_t inode)
+{
+ return findFile(disk, inode) != NULL;
+}
+
+/**
+ * Count size of file \a inode on \a disk, starting at pointer \a start
+ * in disk->page_array. Size is written in \a size.
+ * \return true if all s ok, false on disk read errors.
+ */
+static bool countFileSize(BattFsSuper *disk, pgcnt_t *start, inode_t inode, file_size_t *size)
+{
+ *size = 0;
+ BattFsPageHeader hdr;
+
+ for (;;)
+ {
+ if (!battfs_readHeader(disk, *start++, &hdr))
+ return false;
+ if (hdr.fcs == computeFcs(&hdr) && hdr.inode == inode)
+ *size += hdr.fill;
+ else
+ return true;
+ }
+}
+
+/**
+ * Open file \a inode from \a disk in \a mode.
+ * File context is stored in \a fd.
+ * \return true if ok, false otherwise.
+ */
+bool battfs_fileopen(BattFsSuper *disk, KFileBattFs *fd, inode_t inode, filemode_t mode)
+{
+ Node *n;
+
+ memset(fd, 0, sizeof(*fd));
+
+ /* Search file start point in disk page array */
+ fd->start = findFile(disk, inode);
+ if (fd->start == NULL)
+ {
+ if (!(mode & BATTFS_CREATE))
+ return false;
+
+ /* File does not exist, create it */
+ BattFsPageHeader hdr;
+ hdr.inode = inode;
+ hdr.seq = 0;
+ hdr.fill = 0;
+ hdr.pgoff = 0;
+ hdr.mark = MARK_PAGE_VALID;
+ hdr.fcs_free = FCS_FREE_VALID;
+ hdr.fcs = computeFcs(&hdr);
+ #warning TODO: get a free block and write on disk!
+ }
+
+ /* Fill file size */
+ if (!countFileSize(disk, fd->start, inode, &fd->fd.size))
+ return false;
+
+ /* Reset seek position */
+ fd->fd.seek_pos = 0;
+
+ /* Insert file handle in list, ordered by inode, ascending. */
+ FOREACH_NODE(n, &disk->file_opened_list)
+ {
+ KFileBattFs *file = containerof(n, KFileBattFs, link);
+ if (file->inode >= inode)
+ break;
+ }
+ INSERT_BEFORE(&fd->link, n);
+
+ /* Fill in data */
+ fd->inode = inode;
+ fd->mode = mode;
+ fd->disk = disk;
+
+ fd->fd.close = battfs_fileclose;
+ fd->fd.flush = battfs_flush;
+ fd->fd.read = battfs_read;
+ fd->fd.reopen = kfile_genericReopen;
+ fd->fd.seek = kfile_genericSeek;
+
+#warning TODO battfs_write, battfs_error, battfs_clearerr
+#if 0
+ fd->fd.write = battfs_write;
+ fd->fd.error = battfs_error;
+ fd->fd.clearerr = battfs_clearerr;
+#endif
+
+ DB(fd->fd._type = KFT_BATTFS);
+
+ return true;
+}
+
+/**
+ * Close \a disk.
+ */
+bool battfs_close(struct BattFsSuper *disk)
+{
+ Node *n;
+ int res = 0;
+
+ /* Close all open files */
+ FOREACH_NODE(n, &disk->file_opened_list)
+ {
+ KFileBattFs *file = containerof(n, KFileBattFs, link);
+ res += battfs_fileclose(&file->fd);
+ }
+
+ /* Close disk */
+ return disk->close(disk) && (res == 0);
+}
+
+
+bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff, mark_t mark)
+{
+ BattFsPageHeader hdr;
+
+ hdr.inode = inode;
+ hdr.seq = seq;
+ hdr.fill = fill;
+ hdr.pgoff = pgoff;
+ hdr.mark = MARK_PAGE_VALID;
+ hdr.fcs_free = FCS_FREE_VALID;
+ hdr.fcs = computeFcs(&hdr);
+ if (mark != MARK_PAGE_VALID)
+ {
+ hdr.mark = mark;
+ hdr.fcs_free = computeFcsFree(&hdr);
+ }
+
+ if (!battfs_writeHeader(disk, page, &hdr))
+ {
+ TRACEMSG("error writing hdr\n");
+ return false;
+ }
+
+ return true;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief BattFS: a filesystem for embedded platforms (interface).
+ * TODO: Add detailed filesystem description.
+ */
+
+#ifndef FS_BATTFS_H
+#define FS_BATTFS_H
+
+#include <cfg/compiler.h> // uintXX_t; STATIC_ASSERT
+#include <cpu/types.h> // CPU_BITS_PER_CHAR
+#include <algo/rotating_hash.h>
+#include <mware/list.h>
+#include <kern/kfile.h>
+
+typedef uint16_t fill_t; ///< Type for keeping trace of space filled inside a page
+typedef fill_t pgaddr_t; ///< Type for addressing space inside a page
+typedef uint16_t pgcnt_t; ///< Type for counting pages on disk
+typedef pgcnt_t pgoff_t; ///< Type for counting pages inside a file
+typedef uint32_t mark_t; ///< Type for marking pages as free
+typedef uint8_t inode_t; ///< Type for file inodes
+typedef uint8_t seq_t; ///< Type for page seq number
+typedef rotating_t fcs_t; ///< Type for header FCS.
+
+/**
+ * Size required for free block allocation is at least 1 bit more
+ * than page addressing.
+ */
+STATIC_ASSERT(sizeof(mark_t) > sizeof(pgcnt_t));
+
+/**
+ * BattFS page header, used to represent a page
+ * header in memory.
+ * To see how this is stored on disk:
+ * \see battfs_to_disk
+ * \see disk_to_battfs
+ */
+typedef struct BattFsPageHeader
+{
+ inode_t inode; ///< File inode (file identifier).
+ seq_t seq; ///< Page sequence number.
+ fill_t fill; ///< Filled bytes in page.
+ pgoff_t pgoff; ///< Page offset inside file.
+ mark_t mark; ///< Marker used to keep trace of free/used pages.
+
+ /**
+ * FCS (Frame Check Sequence) of the page header once the page
+ * as been marked as free.
+ */
+ fcs_t fcs_free;
+
+ /**
+ * FCS (Frame Check Sequence) of the page header.
+ */
+ fcs_t fcs;
+} BattFsPageHeader;
+
+/**
+ * Size of the header once saved on disk.
+ * \see battfs_to_disk
+ * \see disk_to_battfs
+ */
+#define BATTFS_HEADER_LEN 12
+
+/**
+ * Marks for valid pages.
+ * Simply set to 1 all field bits.
+ * \{
+ */
+#define MARK_PAGE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t) + 1)) - 1)
+#define FCS_FREE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(fcs_t))) - 1)
+/* \} */
+
+
+/**
+ * Half-size of free page marker.
+ * Used to keep trace of free marker wrap-arounds.
+ */
+#define MARK_HALF_SIZE (1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t) + 1))
+
+/**
+ * Maximum page address.
+ */
+#define MAX_PAGE_ADDR ((1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t))) - 1)
+
+/**
+ * Max number of files.
+ */
+#define BATTFS_MAX_FILES (1 << (CPU_BITS_PER_CHAR * sizeof(inode_t)))
+
+/* Fwd decl */
+struct BattFsSuper;
+
+/**
+ * Sentinel used to keep trace of unset pages in disk->page_array.
+ */
+#define PAGE_UNSET_SENTINEL ((1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t))) - 1)
+
+/**
+ * Type interface for disk init function.
+ * \return true if all is ok, false otherwise.
+ */
+typedef bool (*disk_open_t) (struct BattFsSuper *d);
+
+/**
+ * Type interface for disk page read function.
+ * \a page is the page address, \a addr the address inside the page,
+ * \a size the lenght to be read.
+ * \return the number of bytes read.
+ */
+typedef size_t (*disk_page_read_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t);
+
+/**
+ * Type interface for disk page write function.
+ * \a page is the page address, \a addr the address inside the page,
+ * \a size the lenght to be written.
+ * \return the number of bytes written.
+ */
+typedef size_t (*disk_page_write_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, const void *buf, size_t);
+
+/**
+ * Type interface for disk page erase function.
+ * \a page is the page address.
+ * \return true if all is ok, false otherwise.
+ */
+typedef bool (*disk_page_erase_t) (struct BattFsSuper *d, pgcnt_t page);
+
+/**
+ * Type interface for disk deinit function.
+ * \return true if all is ok, false otherwise.
+ */
+typedef bool (*disk_close_t) (struct BattFsSuper *d);
+
+
+typedef uint32_t disk_size_t; ///< Type for disk sizes.
+
+/**
+ * Context used to describe a disk.
+ * This context structure will be used to access disk.
+ * Must be initialized by hw memory driver.
+ */
+typedef struct BattFsSuper
+{
+ disk_open_t open; ///< Disk init.
+ disk_page_read_t read; ///< Page read.
+ disk_page_write_t write; ///< Page write.
+ disk_page_erase_t erase; ///< Page erase.
+ disk_close_t close; ///< Disk deinit.
+
+ pgaddr_t page_size; ///< Size of a disk page, in bytes.
+ pgcnt_t page_count; ///< Number of pages on disk.
+
+ /**
+ * Page allocation array.
+ * This array must be allocated somewhere and
+ * must have enough space for page_count elements.
+ * Is used by the filesystem to represent
+ * the entire disk in memory.
+ */
+ pgcnt_t *page_array;
+
+ /**
+ * Lowest free page counter.
+ * This is the counter of the first availble free page.
+ */
+ mark_t free_start;
+
+ /**
+ * Highest free page counter.
+ * This value is the next to be used to mark a block as free.
+ */
+ mark_t free_next;
+
+ disk_size_t disk_size; ///< Size of the disk, in bytes (page_count * page_size).
+ disk_size_t free_bytes; ///< Free space on the disk.
+
+ List file_opened_list; ///< List used to keep trace of open files.
+ /* TODO add other fields. */
+} BattFsSuper;
+
+typedef uint8_t filemode_t; ///< Type for file open modes.
+typedef uint32_t file_size_t; ///< Type for file sizes.
+
+/**
+ * Modes for battfs_fileopen.
+ * \{
+ */
+#define BATTFS_CREATE BV(0) ///< Create file if does not exist
+#define BATTFS_RD BV(1) ///< Open file for reading
+#define BATTFS_WR BV(2) ///< Open file fir writing
+/*/}*/
+
+
+/**
+ * Describe a BattFs file usign a KFile.
+ */
+typedef struct KFileBattFs
+{
+ KFile fd; ///< KFile context
+ Node link; ///< Link for inserting in opened file list
+ inode_t inode; ///< inode of the opened file
+ BattFsSuper *disk; ///< Disk context
+ filemode_t mode; ///< File open mode
+ pgcnt_t *start; ///< Pointer to page_array file start position.
+} KFileBattFs;
+
+/**
+ * Id for battfs file descriptors.
+ */
+#define KFT_BATTFS MAKE_ID('B', 'T', 'F', 'S')
+
+/**
+ * Macro used to cast a KFile to a KFileBattFs.
+ * Also perform dynamic type check.
+ */
+INLINE KFileBattFs * KFILEBATTFS(KFile *fd)
+{
+ ASSERT(fd->_type == KFT_BATTFS);
+ return (KFileBattFs *)fd;
+}
+
+bool battfs_init(struct BattFsSuper *d);
+bool battfs_close(struct BattFsSuper *disk);
+
+bool battfs_fileExists(BattFsSuper *disk, inode_t inode);
+bool battfs_fileopen(BattFsSuper *disk, KFileBattFs *fd, inode_t inode, filemode_t mode);
+
+bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff, mark_t mark);
+
+#endif /* FS_BATTFS_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Bitmap manipulation routines.
+ */
+
+#include "gfx.h"
+#include "gfx_p.h"
+
+#include <cfg/debug.h> /* ASSERT() */
+#include <cpu/attr.h> /* CPU_HARVARD */
+#include <cfg/macros.h> /* MIN() */
+#include <appconfig.h> /* CONFIG_GFX_CLIPPING */
+
+#include <string.h> /* memset() */
+
+#if CONFIG_GFX_TEXT
+#include <gfx/font.h> /* default_font */
+#endif
+
+
+/**
+ * Initialize a Bitmap structure with the provided parameters.
+ *
+ * \note The pen position is reset to the origin.
+ */
+void gfx_bitmapInit(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h)
+{
+ bm->raster = raster;
+ bm->width = w;
+ bm->height = h;
+ #if (CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB)
+ bm->stride = (w + 7) / 8;
+ #elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
+ bm->stride = w;
+ #else
+ #error Unknown value of CONFIG_BITMAP_FMT
+ #endif /* CONFIG_BITMAP_FMT */
+ bm->penX = 0;
+ bm->penY = 0;
+
+#if CONFIG_GFX_TEXT
+ gfx_setFont(bm, &default_font);
+ bm->styles = 0;
+#endif
+
+#if CONFIG_GFX_CLIPPING
+ bm->cr.xmin = 0;
+ bm->cr.ymin = 0;
+ bm->cr.xmax = w;
+ bm->cr.ymax = h;
+#endif /* CONFIG_GFX_CLIPPING */
+}
+
+
+/**
+ * Clear the whole bitmap surface to the background color.
+ *
+ * \note This function does \b not update the current pen position.
+ * \note This function bypasses the current clipping area.
+ */
+void gfx_bitmapClear(Bitmap *bm)
+{
+ memset(bm->raster, 0, RAST_SIZE(bm->width, bm->height));
+}
+
+
+#if CPU_HARVARD
+
+#include <avr/pgmspace.h> /* FIXME: memcpy_P() */
+
+/**
+ * Copy a raster picture located in program memory in the bitmap.
+ * The size of the raster to copy *must* be the same of the raster bitmap.
+ *
+ * \note This function does \b not update the current pen position
+ */
+void gfx_blit_P(Bitmap *bm, const pgm_uint8_t *raster)
+{
+ memcpy_P(bm->raster, raster, RAST_SIZE(bm->width, bm->height));
+}
+#endif /* CPU_HARVARD */
+
+#if CONFIG_GFX_CLIPPING
+ /**
+ * Clip destination coordinates inside a clipping range.
+ *
+ * This macro helps a drawing operation to adjust its
+ * destination X and Y coordinates inside the destination
+ * clipping range.
+ *
+ * The source start coordinate is adjusted as well
+ * when destination start clipping occurs.
+ */
+ #define gfx_clip(dmin, dmax, smin, cmin, cmax) \
+ do { \
+ if ((dmin) < (cmin)) \
+ { \
+ (smin) += (cmin) - (dmin); \
+ (dmin) = (cmin); \
+ } \
+ (dmax) = MIN((dmax), (cmax)); \
+ } while(0)
+
+#else /* !CONFIG_GFX_CLIPPING */
+
+ #define gfx_clip(dmin, dmax, smin, cmin, cmax) do { } while (0)
+
+#endif /* !CONFIG_GFX_CLIPPING */
+
+
+/**
+ * Copy a rectangular area of a bitmap on another bitmap.
+ *
+ * Blitting is a common copy operation involving two bitmaps.
+ * A rectangular area of the source bitmap is copied bit-wise
+ * to a different position in the destination bitmap.
+ *
+ * \note Using the same bitmap for \a src and \a dst is unsupported.
+ *
+ * \param dst Bitmap where the operation writes.
+ * \param rect The (xmin;ymin) coordinates provide the top/left offset
+ * for drawing in the destination bitmap. If the source
+ * bitmap is larger than the rectangle, drawing is clipped.
+ * \param src Bitmap containing the source pixels.
+ * \param srcx Starting X offset in the source bitmap.
+ * \param srcy Starting Y offset in the source bitmap.
+ */
+void gfx_blit(Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy)
+{
+ coord_t dxmin, dymin, dxmax, dymax;
+ coord_t dx, dy, sx, sy;
+
+ /*
+ * Pre-clip coordinates inside src->width/height.
+ */
+ dxmin = rect->xmin;
+ dymin = rect->ymin;
+ dxmax = MIN(rect->xmax, rect->xmin + src->width);
+ dymax = MIN(rect->ymax, rect->ymin + src->height);
+
+ /* Perform regular clipping */
+ gfx_clip(dxmin, dxmax, srcx, dst->cr.xmin, dst->cr.xmax);
+ gfx_clip(dymin, dymax, srcy, dst->cr.ymin, dst->cr.ymax);
+
+ //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax);
+ //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax);
+
+ /* TODO: make it not as dog slow as this */
+ for (dx = dxmin, sx = srcx; dx < dxmax; ++dx, ++sx)
+ for (dy = dymin, sy = srcy; dy < dymax; ++dy, ++sy)
+ BM_DRAWPIXEL(dst, dx, dy, BM_READPIXEL(src, sx, sy));
+}
+
+/**
+ * Blit a raster to a Bitmap.
+ *
+ * \todo Merge this function into gfx_blit()
+ *
+ * \see gfx_blit()
+ */
+void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin,
+ const uint8_t *raster, coord_t w, coord_t h, coord_t stride)
+{
+ coord_t dxmax = dxmin + w, dymax = dymin + h;
+ coord_t sxmin = 0, symin = 0;
+ coord_t dx, dy, sx, sy;
+
+ /* Perform regular clipping */
+ gfx_clip(dxmin, dxmax, sxmin, dst->cr.xmin, dst->cr.xmax);
+ gfx_clip(dymin, dymax, symin, dst->cr.ymin, dst->cr.ymax);
+
+ //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax);
+ //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax);
+
+ /* TODO: make it not as dog slow as this */
+ for (dx = dxmin, sx = sxmin; dx < dxmax; ++dx, ++sx)
+ for (dy = dymin, sy = symin; dy < dymax; ++dy, ++sy)
+ BM_DRAWPIXEL(dst, dx, dy, RAST_READPIXEL(raster, sx, sy, stride));
+}
+
+/**
+ * Blit an Image to a Bitmap.
+ *
+ * \see gfx_blit()
+ */
+void gfx_blitImage(Bitmap *dst, coord_t dxmin, coord_t dymin, const Image *image)
+{
+ ASSERT(image);
+
+ gfx_blitRaster(dst, dxmin, dymin,
+ image->raster, image->width, image->height, image->stride);
+}
+
+
+#if CONFIG_GFX_CLIPPING || CONFIG_GFX_VCOORDS
+
+/**
+ * Set the bitmap clipping rectangle to the specified coordinates.
+ *
+ * All drawing performed on the bitmap will be clipped inside this
+ * rectangle.
+ *
+ * The clipping rectangle is also used as a bounding box for the
+ * logical view of the virtual coordinate system.
+ *
+ * \note Following the convention used for all other operations, the
+ * top-left pixels of the rectangle are included, while the
+ * bottom-right pixels are considered outside the clipping region.
+ *
+ * \see gfx_setViewRect
+ */
+void gfx_setClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy)
+{
+ ASSERT(minx < maxx);
+ ASSERT(miny < maxy);
+ ASSERT(miny >= 0);
+ ASSERT(minx >= 0);
+ ASSERT(maxx <= bm->width);
+ ASSERT(maxy <= bm->height);
+
+ bm->cr.xmin = minx;
+ bm->cr.ymin = miny;
+ bm->cr.xmax = maxx;
+ bm->cr.ymax = maxy;
+
+// kprintf("cr.xmin = %d, cr.ymin = %d, cr.xmax = %d, cr.ymax = %d\n",
+// bm->cr.xMin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);
+}
+
+#endif /* CONFIG_GFX_CLIPPING */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Simple charts on top of mware/gfx routines (implementation).
+ *
+ * Sample usage:
+ *
+ * \code
+ * bm = chart_init(0, ymax, N_POINTS_CURVE, ymin);
+ *
+ * chart_drawCurve(bm, curve_y, curve_points + 1);
+ * gfx_setViewRect(bm, xmin, ymax, xmax, ymin);
+ * chart_drawDots(bm, samples_x, samples_y, samples_cnt);
+ *
+ * print_bitmap(bm);
+ * \endcode
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.3 2005/11/27 23:33:29 bernie
+ *#* Reorder includes.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:11:35 bernie
+ *#* Move graphics stuff from mware/ to gfx/.
+ *#*
+ *#* Revision 1.7 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.6 2004/11/16 21:04:23 bernie
+ *#* Update to new naming scheme in mware/gfx.c.
+ *#*
+ *#* Revision 1.5 2004/09/14 20:56:39 bernie
+ *#* Make more generic and adapt to new gfx functions.
+ *#*
+ *#* Revision 1.3 2004/08/11 19:39:12 bernie
+ *#* Use chart_x_t and chart_y_t for the input dataset.
+ *#*
+ *#* Revision 1.1 2004/08/04 03:16:30 bernie
+ *#* Import simple chart drawing code.
+ *#*
+ *#*/
+
+#include "charts.h"
+#include <gfx/gfx.h>
+
+
+#ifndef CONFIG_CHART_ARROWS
+#define CONFIG_CHART_ARROWS 0
+#endif
+
+
+void chart_init(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord_t ymax)
+{
+ /* Clear the chart area */
+ gfx_rectClear(bm, xmin, ymin, xmax, ymax);
+
+ gfx_setClipRect(bm, xmin + CHART_BORDERLEFT, ymin + CHART_BORDERTOP,
+ xmax - CHART_BORDERRIGHT, ymax - CHART_BORDERBOTTOM);
+
+ chart_drawAxis(bm);
+}
+
+
+void chart_setScale(Bitmap *bm, chart_x_t xmin, chart_y_t ymin, chart_x_t xmax, chart_y_t ymax)
+{
+ gfx_setViewRect(bm, xmin, ymin, xmax, ymax);
+}
+
+
+/**
+ * Draw the chart axes
+ */
+void chart_drawAxis(Bitmap *bm)
+{
+#if CONFIG_CHART_ARROWS
+
+ /* Draw axis */
+ gfx_moveTo(bm, bm->cr.xmin, bm->cr.ymin + 4);
+ gfx_lineTo(bm, bm->cr.xmin, bm->cr.ymax - 1);
+ gfx_lineTo(bm, bm->cr.xmax - 4 - 1, bm->cr.ymax - 1);
+
+ /* Draw up arrow */
+ gfx_moveTo(bm, bm->cr.xmin - 2, bm->cr.ymin + 3);
+ gfx_lineTo(bm, bm->cr.xmin + 2, bm->cr.ymin + 3);
+ gfx_lineTo(bm, bm->cr.xmin, bm->cr.ymin);
+ gfx_lineTo(bm, bm->cr.xmin - 2, bm->cr.ymin + 3);
+
+ /* Draw right arrow */
+ gfx_moveTo(bm, bm->cr.xmax - 4, bm->cr.ymax - 3);
+ gfx_lineTo(bm, bm->cr.xmax - 4, bm->cr.ymax + 1);
+ gfx_lineTo(bm, bm->cr.xmax - 1, bm->cr.ymax - 1);
+ gfx_lineTo(bm, bm->cr.xmax - 4, bm->cr.ymax - 3);
+
+#else /* CONFIG_CHART_ARROWS */
+
+ /* Draw a box around the chart */
+ gfx_rectDraw(bm, bm->cr.xmin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);
+
+#endif /* CONFIG_CHART_ARROWS */
+
+ //CHECK_WALL(wall_before_raster, WALL_SIZE);
+ //CHECK_WALL(wall_after_raster, WALL_SIZE);
+}
+
+
+/**
+ * Draw a set of \a curve_cnt connected segments, whose Y coordinates
+ * are identified by the \a curve_y array and X-coordinates are
+ * are evenly spaced by one virtual unit.
+ */
+void chart_drawCurve(Bitmap *bm, const chart_y_t *curve_y, int curve_cnt)
+{
+ int i;
+
+ gfx_moveTo(bm, gfx_transformX(bm, 0), gfx_transformY(bm, curve_y[0]));
+
+ for (i = 1; i < curve_cnt; i++)
+ gfx_lineTo(bm, gfx_transformX(bm, i), gfx_transformY(bm, curve_y[i]));
+
+ //CHECK_WALL(wall_before_raster, WALL_SIZE);
+ //CHECK_WALL(wall_after_raster, WALL_SIZE);
+}
+
+
+/**
+ * Disegna dei dot in corrispondenza delle coppie (dotsx[i];dotsy[i])
+ * Se dotsx e' NULL, i punti vengono disegnati ad intervalli regolari.
+ */
+void chart_drawDots(Bitmap *bm, const chart_x_t *dots_x, const chart_y_t *dots_y, int cnt)
+{
+ int i;
+ coord_t x, y;
+
+ for (i = 0; i < cnt; i++)
+ {
+ if (dots_x)
+ x = gfx_transformX(bm, dots_x[i]);
+ else
+ x = gfx_transformX(bm, i);
+
+ y = gfx_transformY(bm, dots_y[i]);
+
+ /* Draw tick over the curve */
+ gfx_rectFill(bm,
+ x - TICKS_WIDTH / 2, y - TICKS_HEIGHT / 2,
+ x + (TICKS_WIDTH + 1) / 2, y + (TICKS_HEIGHT + 1) / 2);
+
+ /* Draw vertical line from the curve to the X-axis */
+ //gfx_drawLine(bm, x, y, x, bm->cr.ymax - 1);
+ }
+
+ //CHECK_WALL(wall_before_raster, WALL_SIZE);
+ //CHECK_WALL(wall_after_raster, WALL_SIZE);
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Simple charts on top of mware/gfx routines (interface).
+ *
+ * Configuration:
+ * - \c CONFIG_CHART_TYPE_X: type for the input dataset of X-coordinates
+ * - \c CONFIG_CHART_TYPE_Y: type for the input dataset of Y-coordinates
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.5 2006/08/01 12:23:03 bernie
+ *#* Indentation fix.
+ *#*
+ *#* Revision 1.4 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.3 2005/11/27 23:36:18 bernie
+ *#* Use appconfig.h instead of cfg/config.h.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:11:35 bernie
+ *#* Move graphics stuff from mware/ to gfx/.
+ *#*
+ *#* Revision 1.7 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.6 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.5 2004/09/14 20:56:39 bernie
+ *#* Make more generic and adapt to new gfx functions.
+ *#*
+ *#* Revision 1.3 2004/08/11 19:39:12 bernie
+ *#* Use chart_x_t and chart_y_t for the input dataset.
+ *#*
+ *#* Revision 1.1 2004/08/04 03:16:30 bernie
+ *#* Import simple chart drawing code.
+ *#*
+ *#*/
+#ifndef GFX_CHARTS_H
+#define GFX_CHARTS_H
+
+#include <gfx/gfx.h> /* vcoord_t */
+#include <appconfig.h> /* CONFIG_ stuff */
+
+/**
+ * \name Width/height of the small ticks drawn over the axes
+ * \{
+ */
+#define TICKS_HEIGHT 2
+#define TICKS_WIDTH 2
+/*\}*/
+
+/**
+ * \name Chart frame dimensions
+ * \{
+ */
+#define CHART_BORDERTOP 0
+#define CHART_BORDERBOTTOM 0
+#define CHART_BORDERLEFT 0
+#define CHART_BORDERRIGHT 0
+/*\}*/
+
+#ifndef CONFIG_CHART_TYPE_X
+#define CONFIG_CHART_TYPE_X vcoord_t
+#endif
+#ifndef CONFIG_CHART_TYPE_Y
+#define CONFIG_CHART_TYPE_Y vcoord_t
+#endif
+
+
+typedef CONFIG_CHART_TYPE_X chart_x_t;
+typedef CONFIG_CHART_TYPE_Y chart_y_t;
+
+
+/* Public function protos */
+void chart_init(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord_t ymax);
+void chart_setScale(Bitmap *bm, chart_x_t xmin, chart_y_t ymin, chart_x_t xmax, chart_y_t ymax);
+void chart_drawAxis(Bitmap *bm);
+void chart_drawCurve(Bitmap *bm, const chart_y_t *curve_y, int curve_cnt);
+void chart_drawDots(Bitmap *bm, const chart_x_t *dots_x, const chart_y_t *dots_y, int cnt);
+
+#endif /* GFX_CHARTS_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ * \author Massimiliano Corsini <chad@develer.com>
+ *
+ *
+ * \brief Low-level drawing routines.
+ *
+ * This file contains the implementation of the low-level drawing routines
+ * to draw fill rectangle, fill triangle and so on.
+ *
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2006/07/19 13:00:01 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.10 2005/10/15 15:03:43 rasky
+ *#* Remove per-pixel clipping from line().
+ *#* Use clipLine() also for a-scope.
+ *#*
+ *#* Revision 1.9 2005/10/14 15:21:32 eldes
+ *#* Implement the cohen-sutherland clipping on the buffer
+ *#*
+ *#* Revision 1.8 2005/09/27 13:28:10 rasky
+ *#* Add clipping capabilities to line()
+ *#* Fix off-by-one computation of rectangles of drawing.
+ *#*
+ *#* Revision 1.7 2005/09/27 10:41:35 rasky
+ *#* Import line-drawing routine from Devlib
+ *#*
+ *#* Revision 1.6 2005/09/19 16:36:05 chad
+ *#* Fix doxygen autobrief
+ *#*
+ *#* Revision 1.5 2005/07/06 12:51:47 chad
+ *#* Make the fillRectangle() independent of the order of the points of the rectangle
+ *#*
+ *#* Revision 1.4 2005/06/17 15:06:36 chad
+ *#* Remove conversion warning
+ *#*
+ *#* Revision 1.3 2005/06/17 15:04:47 chad
+ *#* Add line clipping capability
+ *#*
+ *#* Revision 1.2 2005/06/15 14:04:43 chad
+ *#* Add line routine
+ *#*
+ *#* Revision 1.1 2005/06/15 13:34:34 chad
+ *#* Low-level drawing routines
+ *#*
+ *#*/
+
+// Qt-specific headers
+#include <qpoint.h>
+
+
+/**
+ * Low-level routine to draw a line.
+ *
+ * This routine is based on the Bresenham Line-Drawing Algorithm.
+ *
+ * The \a stride represents the width of the image buffer.
+ * (\a x1, \a y1) are the coordinates of the starting point.
+ * (\a x2, \a y2) are the coordinates of the ending point.
+ *
+ * The line has no anti-alias, and clipping is not performed. The line
+ * must be fully contained in the buffer (use clipLine() if you need
+ * to clip it).
+ */
+void line(unsigned char *buf,
+ unsigned long bufw, unsigned long bufh, unsigned long stride,
+ int x1, int y1, int x2, int y2, unsigned char color)
+{
+ int x, y, e, len, adx, ady, signx, signy;
+
+ if (x2 > x1)
+ {
+ /* left to right */
+ signx = +1;
+ adx = x2 - x1;
+ }
+ else
+ {
+ /* right to left */
+ signx = -1;
+ adx = x1 - x2;
+ }
+
+ if (y2 > y1)
+ {
+ /* top to bottom */
+ signy = +1;
+ ady = y2 - y1;
+ }
+ else
+ {
+ /* bottom to top */
+ signy = -1;
+ ady = y1 - y2;
+ }
+
+ x = x1;
+ y = y1;
+
+ if (adx > ady)
+ {
+ /* X-major line (octants 1/4/5/8) */
+ len = adx;
+ e = -adx;
+ while (len--)
+ {
+ /* Sanity check */
+ assert(y >= 0 && y < static_cast<int>(bufh) &&
+ x >= 0 && x < static_cast<int>(bufw));
+ buf[y * stride + x] = color;
+ x += signx;
+ e += ady;
+ if (e >= 0)
+ {
+ y += signy;
+ e -= adx;
+ }
+ }
+ }
+ else
+ {
+ /* Y-major line (octants 2/3/6/7) */
+ len = ady;
+ e = -ady;
+ while (len--)
+ {
+ /* Sanity check */
+ assert(y >= 0 && y < static_cast<int>(bufh) &&
+ x >= 0 && x < static_cast<int>(bufw));
+ buf[y * stride + x] = color;
+ y += signy;
+ e += adx;
+ if (e >= 0)
+ {
+ x += signx;
+ e -= ady;
+ }
+ }
+ }
+}
+
+/// Helper routine for clipLine().
+static int region(int x, int y, int w, int h)
+{
+ int code = 0;
+
+ if (y >= h)
+ code |= 1; // top
+ else if (y < 0)
+ code |= 2; // bottom
+
+ if (x >= w)
+ code |= 4; // right
+ else if (x < 0)
+ code |= 8; // left
+
+ return code;
+}
+
+/**
+ * Low-level routine to draw a line, clipped to the buffer extents.
+ *
+ * This routine executes the clipping, and then invokes line().
+ * Parameters are the same of line(). The clipping is performed
+ * using the Cohen-Sutherland algorithm, which is very fast.
+ */
+void clipLine(unsigned char *buf,
+ unsigned long w, unsigned long h, unsigned long stride,
+ int x1, int y1, int x2, int y2, unsigned char color)
+{
+ int code1 = region(x1, y1, w, h);
+ int code2 = region(x2, y2, w, h);
+
+ // Loop while there is at least one point outside
+ while (code1 | code2)
+ {
+ // Check for line totally outside
+ if (code1 & code2)
+ return;
+
+ int c = code1 ? code1 : code2;
+ int x, y;
+
+ if (c & 1) // top
+ {
+ x = x1 + (x2 - x1) * (h - y1) / (y2 - y1);
+ y = h - 1;
+ }
+ else if (c & 2) //bottom
+ {
+ x = x1 + (x2 - x1) * -y1 / (y2 - y1);
+ y = 0;
+ }
+ else if (c & 4) //right
+ {
+ y = y1 + (y2 - y1) * (w - x1) / (x2 - x1);
+ x = w - 1;
+ }
+ else //left
+ {
+ y = y1 + (y2 - y1) * -x1 / (x2 - x1);
+ x = 0;
+ }
+
+ if (c == code1) // first endpoint was clipped
+ {
+ x1 = x; y1 = y;
+ code1 = region(x1, y1, w, h);
+ }
+ else //second endpoint was clipped
+ {
+ x2 = x; y2 = y;
+ code2 = region(x2, y2, w, h);
+ }
+ }
+
+ line(buf, w, h, stride, x1, y1, x2, y2, color);
+}
+
+
+/**
+ * Low-level routine to draw a filled rectangle.
+ *
+ * The triangle is filled with the given color.
+ *
+ * The \a stride represents the width of the image buffer.
+ * The points \a p1 and \a p2 are two opposite corners of the
+ * rectangle.
+ */
+void fillRectangle(unsigned char *buf, unsigned long stride,
+ QPoint p1, QPoint p2, unsigned char color)
+{
+ QPoint ul; // upper-left corner
+ QPoint lr; // lower-right corner
+
+ if (p2.x() > p1.x())
+ {
+ ul.setX(p1.x());
+ lr.setX(p2.x());
+ }
+ else
+ {
+ ul.setX(p2.x());
+ lr.setX(p1.x());
+ }
+
+ if (p2.y() > p1.y())
+ {
+ ul.setY(p1.y());
+ lr.setY(p2.y());
+ }
+ else
+ {
+ ul.setY(p2.y());
+ lr.setY(p1.y());
+ }
+
+ int width = lr.x() - ul.x();
+ unsigned long offset = ul.x() + ul.y()*stride;
+
+ for (int h = ul.y(); h < lr.y(); h++)
+ {
+ memset(buf+offset, color, width);
+ offset += stride;
+ }
+}
+
+/**
+ * Low-level routines to draw a filled triangle.
+ *
+ * The triangle is filled with the given \a color.
+ * The \a stride represents the width of the image buffer (\a buf).
+ *
+ * The routine use fixed-point arithmetic.
+ */
+void fillTriangle(unsigned char* buf, unsigned long stride,
+ QPoint v1, QPoint v2, QPoint v3, unsigned char color)
+{
+ int altezza[3];
+
+ // Sort by vertical coordinate
+ if (v1.y() > v2.y())
+ std::swap(v1, v2);
+ if (v1.y() > v3.y())
+ std::swap(v1, v3);
+ if (v2.y() > v3.y())
+ std::swap(v2, v3);
+
+ altezza[0] = v3.y() - v1.y();
+ if (!altezza[0])
+ return;
+
+ int sezioni = 2;
+ int sezione = 1;
+
+ buf += v1.y() * stride;
+
+ altezza[1] = v2.y() - v1.y();
+ altezza[2] = v3.y() - v2.y();
+
+ int sinistra = v1.x();
+ int destra = sinistra;
+
+ if (v1.y() == v2.y())
+ {
+ if (v1.x() < v2.x())
+ destra = v2.x();
+ else
+ sinistra = v2.x();
+ }
+
+ sinistra <<= 16;
+ destra <<= 16;
+
+ int stmp1, stmp2, stmp3;
+
+ stmp1 = (altezza[1] << 16) / altezza[0];
+ int lunghezza = stmp1 * (v3.x() - v1.x()) + ((v1.x() - v2.x()) << 16);
+
+ if (!lunghezza )
+ return;
+
+ int delta_sinistra[2];
+ int delta_destra[2];
+
+ stmp1 = ((v3.x() - v1.x()) << 16) / altezza[0];
+
+ if (altezza[1])
+ stmp2 = ((v2.x() - v1.x()) << 16) / altezza[1];
+ if (altezza[2])
+ stmp3 = ((v3.x() - v2.x()) << 16) / altezza[2];
+
+ if (lunghezza < 0) // Il secondo vertice ~J a destra
+ {
+ delta_sinistra[0] = stmp1;
+ delta_sinistra[1] = stmp1;
+ delta_destra[0] = stmp2;
+ delta_destra[1] = stmp3;
+ }
+ else // Il secondo vertice ~J a sinistra
+ {
+ delta_sinistra[0] = stmp2;
+ delta_sinistra[1] = stmp3;
+ delta_destra[0] = stmp1;
+ delta_destra[1] = stmp1;
+ }
+
+ int len2 = lunghezza;
+
+ do
+ {
+ while (altezza [sezione])
+ {
+ unsigned char* curpos = buf + ((sinistra )>> 16);
+ lunghezza = ((destra ) >> 16) - ((sinistra ) >> 16);
+ assert(lunghezza >= 0);
+ if (lunghezza)
+ memset(curpos, color, lunghezza);
+ buf += stride;
+ destra += delta_destra[sezione - 1];
+ sinistra += delta_sinistra[sezione - 1];
+ altezza[sezione]--;
+ }
+ if (len2 < 0)
+ destra = v2.x() << 16;
+ else
+ sinistra = v2.x() << 16;
+ sezione++;
+ } while (--sezioni);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Font 8x6 IBM-PC 8bit
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2006/05/27 22:31:34 bernie
+ *#* Switch to a smaller default fount.
+ *#*
+ *#* Revision 1.5 2006/03/13 02:06:04 bernie
+ *#* FONT_HAS_GLYPH(): New macro.
+ *#*
+ *#* Revision 1.4 2006/02/15 09:10:15 bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
+ *#* Revision 1.3 2006/02/10 12:29:05 bernie
+ *#* Add multiple font support in bitmaps.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:11:35 bernie
+ *#* Move graphics stuff from mware/ to gfx/.
+ *#*
+ *#* Revision 1.6 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.5 2005/03/01 23:26:45 bernie
+ *#* Use new CPU-neutral program-memory API.
+ *#*
+ *#* Revision 1.4 2004/12/31 16:42:55 bernie
+ *#* Sanitize for non-Harvard processors.
+ *#*
+ *#* Revision 1.3 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 15:43:16 bernie
+ *#* Import mware modules.
+ *#*
+ *#* Revision 1.2 2004/03/24 15:48:53 bernie
+ *#* Remove Copyright messages from Doxygen output
+ *#*
+ *#* Revision 1.1 2004/01/13 12:15:28 aleph
+ *#* Move font table in program memory; add font.h
+ *#*
+ *#*/
+#ifndef GFX_FONT_H
+#define GFX_FONT_H
+
+#include <cfg/compiler.h> /* uint8_t */
+#include <mware/pgm.h> /* PROGMEM */
+
+typedef struct Font
+{
+ /**
+ * Pointer to glyph data.
+ *
+ * Data is an array of at most 256 glyphs packed together.
+ * Raster format must be the same of the bitmap.
+ */
+ const PROGMEM uint8_t *glyph;
+
+ uint8_t width; /**< Pixel width of character cell. */
+ uint8_t height; /**< Pixel height of character cell. */
+
+ uint8_t first; /**< First encoded character in glyph array. */
+ uint8_t last; /**< Last encoded character in glyph array (inclusive). */
+
+ /** Array of glyph offsets in bytes. NULL for fixed-width fonts. */
+ const PROGMEM uint16_t *offset;
+ const PROGMEM uint8_t *widths;
+
+} Font;
+
+
+/** Return true if glyph \a c is available in \a font. */
+#define FONT_HAS_GLYPH(font, c) ((c) >= (font)->first && (c) <= (font)->last)
+
+
+/** The default font. */
+#define default_font font_luBS14
+extern const struct Font default_font;
+
+#endif /* GFX_FONT_H */
--- /dev/null
+/* Generated by convbdf on Fri Feb 10 01:05:15 CET 2006. */
+#include "font.h"
+
+/* Font information:
+
+ name: -Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1
+ pixel size: 20
+ ascent: 16
+ descent: 4
+*/
+
+/* Font character bitmap data. */
+static const PROGMEM uint8_t font_10x20_glyphs[] = {
+
+/* Character (0x00):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | *** *** |
+ | * * |
+ | * * |
+ | |
+ | |
+ | * * |
+ | * * |
+ | * * |
+ | |
+ | |
+ | * * |
+ | * * |
+ | *** *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0073, 0x0080,
+0x0040, 0x0080,
+0x0040, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0040, 0x0080,
+0x0040, 0x0080,
+0x0040, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0040, 0x0080,
+0x0040, 0x0080,
+0x0073, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x01):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | **** |
+ | ****** |
+ | ******** |
+ | ******** |
+ | ****** |
+ | **** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x003f, 0x0000,
+0x007f, 0x0080,
+0x007f, 0x0080,
+0x003f, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x02):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ | * * * * * |
+ |* * * * * |
+ +----------------+ */
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+0x0055, 0x0040,
+0x00aa, 0x0080,
+
+/* Character (0x03):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x007e, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x0000, 0x0000,
+0x001f, 0x0080,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x04):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | ***** |
+ | ** |
+ | ** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ***** |
+ | ** |
+ | ** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007c, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0078, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x000f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000f, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x05):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | **** |
+ | |
+ | ***** |
+ | ** ** |
+ | ** ** |
+ | ***** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003c, 0x0000,
+0x0066, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0066, 0x0000,
+0x003c, 0x0000,
+0x0000, 0x0000,
+0x001f, 0x0000,
+0x0019, 0x0080,
+0x0019, 0x0080,
+0x001f, 0x0000,
+0x001e, 0x0000,
+0x001b, 0x0000,
+0x0019, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x06):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ***** |
+ | |
+ | ***** |
+ | ** |
+ | ** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x003e, 0x0000,
+0x0000, 0x0000,
+0x000f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000f, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x07):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x08):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ******** |
+ | ** |
+ | ** |
+ | |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x09):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | ** ** |
+ | *** ** |
+ | ****** |
+ | ****** |
+ | ** *** |
+ | ** ** |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ***** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0066, 0x0000,
+0x0076, 0x0000,
+0x007e, 0x0000,
+0x007e, 0x0000,
+0x006e, 0x0000,
+0x0066, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x0a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | **** |
+ | ** |
+ | ** |
+ | |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x003c, 0x0000,
+0x003c, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0000, 0x0000,
+0x001f, 0x0080,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x0b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ |***** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x00f8, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x0c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ |***** |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00f8, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x0d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ****** |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000f, 0x00c0,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x0e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | ****** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x000f, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x0f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ |********** |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x00ff, 0x00c0,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x10):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ |********** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x00ff, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x11):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ |********** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x12):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ |********** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x13):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ |********** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x14):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ |********** |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x00c0,
+
+/* Character (0x15):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | ****** |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x000f, 0x00c0,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x16):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ |***** |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x00f8, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x17):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ |********** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x00ff, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x18):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ |********** |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x00c0,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x19):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ | * |
+ +----------------+ */
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+0x0008, 0x0000,
+
+/* Character (0x1a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | *** |
+ |*** |
+ | *** |
+ | *** |
+ | *** |
+ | |
+ | |
+ |********* |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0003, 0x0080,
+0x000e, 0x0000,
+0x0038, 0x0000,
+0x00e0, 0x0000,
+0x0038, 0x0000,
+0x000e, 0x0000,
+0x0003, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x1b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ |*** |
+ | *** |
+ | *** |
+ | *** |
+ | *** |
+ | *** |
+ |*** |
+ | |
+ | |
+ |********* |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00e0, 0x0000,
+0x0038, 0x0000,
+0x000e, 0x0000,
+0x0003, 0x0080,
+0x000e, 0x0000,
+0x0038, 0x0000,
+0x00e0, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x00ff, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x1c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ******** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x1d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | ** |
+ | ** |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x007f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x1e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ***** |
+ | * * ** ** |
+ | *** *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000f, 0x0000,
+0x0019, 0x0080,
+0x0019, 0x0080,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x007e, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x007c, 0x0000,
+0x0056, 0x00c0,
+0x0073, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x1f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x20):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x21):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x22):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | * * |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0012, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x23):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ******** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ******** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000d, 0x0080,
+0x000d, 0x0080,
+0x000d, 0x0080,
+0x003f, 0x00c0,
+0x001b, 0x0000,
+0x001b, 0x0000,
+0x001b, 0x0000,
+0x007f, 0x0080,
+0x0036, 0x0000,
+0x0036, 0x0000,
+0x0036, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x24):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ****** |
+ | ** ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** ** |
+ | ****** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x003f, 0x0000,
+0x006d, 0x0080,
+0x006c, 0x0000,
+0x006c, 0x0000,
+0x006c, 0x0000,
+0x003f, 0x0000,
+0x000d, 0x0080,
+0x000d, 0x0080,
+0x000d, 0x0080,
+0x006d, 0x0080,
+0x003f, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x25):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | *** ** |
+ | ** ** ** |
+ | ** **** |
+ | *** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** *** |
+ | **** ** |
+ | ** ** ** |
+ | ** *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0039, 0x0080,
+0x006d, 0x0080,
+0x006f, 0x0000,
+0x003b, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x001b, 0x0080,
+0x001e, 0x00c0,
+0x0036, 0x00c0,
+0x0033, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x26):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | *** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ** |
+ | *** |
+ | ** ** |
+ | ** ** ** |
+ | ** *** |
+ | ** ** |
+ | *** **** |
+ | **** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001c, 0x0000,
+0x0036, 0x0000,
+0x0036, 0x0000,
+0x0036, 0x0000,
+0x003c, 0x0000,
+0x0018, 0x0000,
+0x0038, 0x0000,
+0x006c, 0x0000,
+0x0066, 0x00c0,
+0x0063, 0x0080,
+0x0063, 0x0000,
+0x0077, 0x0080,
+0x003c, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x27):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | * |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0008, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x28):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0006, 0x0000,
+0x0003, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x29):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0030, 0x0000,
+0x0018, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x2a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ******** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x007f, 0x0080,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x2b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x2c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x001c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x2d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x2e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x2f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x30):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x31):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | *** |
+ | **** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x001c, 0x0000,
+0x003c, 0x0000,
+0x006c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x32):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | *** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x000e, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x33):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | *** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x000e, 0x0000,
+0x0003, 0x0000,
+0x0001, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x34):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | * |
+ | ** |
+ | *** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0001, 0x0000,
+0x0003, 0x0000,
+0x0007, 0x0000,
+0x000f, 0x0000,
+0x001b, 0x0000,
+0x0033, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x007f, 0x0080,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x35):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** *** |
+ | *** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x006e, 0x0000,
+0x0073, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x36):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** * |
+ | ** |
+ | ** |
+ | ** *** |
+ | *** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x006e, 0x0000,
+0x0073, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x37):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x38):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x39):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** *** |
+ | *** ** |
+ | ** |
+ | ** |
+ | * ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0080,
+0x001d, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0021, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x3a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x3b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ | |
+ | *** |
+ | *** |
+ | *** |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000e, 0x0000,
+0x000e, 0x0000,
+0x001c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x3c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | * |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | * |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0001, 0x0000,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0060, 0x0000,
+0x0030, 0x0000,
+0x0018, 0x0000,
+0x000c, 0x0000,
+0x0006, 0x0000,
+0x0003, 0x0000,
+0x0001, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x3d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x3e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | * |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | * |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0020, 0x0000,
+0x0030, 0x0000,
+0x0018, 0x0000,
+0x000c, 0x0000,
+0x0006, 0x0000,
+0x0003, 0x0000,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0020, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x3f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x40):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** **** |
+ | ** ***** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** **** |
+ | ** ** |
+ | ** |
+ | ** ** |
+ | ***** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0067, 0x0080,
+0x006f, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006f, 0x0000,
+0x0066, 0x0000,
+0x0060, 0x0000,
+0x0031, 0x0080,
+0x001f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x41):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ******** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x007f, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x42):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ***** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007c, 0x0000,
+0x0066, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0066, 0x0000,
+0x007e, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0063, 0x0000,
+0x007e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x43):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x44):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007e, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0063, 0x0000,
+0x007e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x45):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x007e, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x46):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x007e, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x47):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** *** |
+ | **** * |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0067, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0080,
+0x001e, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x48):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ******** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x007f, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x49):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x4a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000f, 0x00c0,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0036, 0x0000,
+0x001c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x4b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ***** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x007c, 0x0000,
+0x0066, 0x0000,
+0x0066, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x4c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x4d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | *** *** |
+ | *** *** |
+ | ******** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0073, 0x0080,
+0x0073, 0x0080,
+0x007f, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x4e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | *** ** |
+ | *** ** |
+ | **** ** |
+ | **** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** **** |
+ | ** **** |
+ | ** *** |
+ | ** *** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0071, 0x0080,
+0x0071, 0x0080,
+0x0079, 0x0080,
+0x0079, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x0067, 0x0080,
+0x0067, 0x0080,
+0x0063, 0x0080,
+0x0063, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x4f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x50):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007e, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0063, 0x0000,
+0x007e, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x51):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** ** |
+ | ** **** |
+ | ** ** |
+ | ***** |
+ | ** |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x006d, 0x0080,
+0x0067, 0x0080,
+0x0033, 0x0000,
+0x001f, 0x0000,
+0x0001, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x52):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007e, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0063, 0x0000,
+0x007e, 0x0000,
+0x0066, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x53):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0030, 0x0000,
+0x001e, 0x0000,
+0x0003, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x54):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x55):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x56):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | **** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x001e, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x57):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | *** *** |
+ | *** *** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x0073, 0x0080,
+0x0073, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x58):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | **** |
+ | ** |
+ | **** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x59):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x5a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ******** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x5b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ****** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003f, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x003f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x5c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0006, 0x0000,
+0x0006, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x5d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ****** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003f, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x0003, 0x0000,
+0x003f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x5e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x5f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ********* |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x007f, 0x00c0,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x60):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0018, 0x0000,
+0x000c, 0x0000,
+0x0006, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x61):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ***** |
+ | ** ** |
+ | ** |
+ | ******* |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ***** * |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001f, 0x0000,
+0x0031, 0x0080,
+0x0001, 0x0080,
+0x003f, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x003e, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x62):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** *** |
+ | *** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | *** ** |
+ | ** *** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x006e, 0x0000,
+0x0073, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0073, 0x0000,
+0x006e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x63):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ***** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ***** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001f, 0x0000,
+0x0031, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0031, 0x0080,
+0x001f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x64):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | *** ** |
+ | ** *** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** *** |
+ | *** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x001d, 0x0080,
+0x0033, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0080,
+0x001d, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x65):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ******** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ***** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x007f, 0x0080,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0031, 0x0080,
+0x001f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x66):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** |
+ | ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000f, 0x0000,
+0x0019, 0x0080,
+0x0019, 0x0080,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x007e, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x67):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ***** * |
+ | ** *** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ***** |
+ | ** |
+ | ****** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ****** |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003e, 0x0080,
+0x0063, 0x0080,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x0063, 0x0000,
+0x003e, 0x0000,
+0x0060, 0x0000,
+0x003f, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x003f, 0x0000,
+
+/* Character (0x68):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** *** |
+ | *** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x006e, 0x0000,
+0x0073, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x69):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x003c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x6a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ***** |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0000, 0x0000,
+0x0007, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0031, 0x0080,
+0x0031, 0x0080,
+0x0031, 0x0080,
+0x001f, 0x0000,
+
+/* Character (0x6b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ***** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0063, 0x0000,
+0x0066, 0x0000,
+0x006c, 0x0000,
+0x0078, 0x0000,
+0x007c, 0x0000,
+0x0066, 0x0000,
+0x0063, 0x0000,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x6c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x007f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x6d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | * ** ** |
+ | ******** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x005b, 0x0000,
+0x007f, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x6e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** *** |
+ | *** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x006e, 0x0000,
+0x0073, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x6f):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x70):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** *** |
+ | *** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | *** ** |
+ | ** *** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x006e, 0x0000,
+0x0073, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0073, 0x0000,
+0x006e, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+0x0060, 0x0000,
+
+/* Character (0x71):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | *** ** |
+ | ** *** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** *** |
+ | *** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x001d, 0x0080,
+0x0033, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0080,
+0x001d, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0001, 0x0080,
+
+/* Character (0x72):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** **** |
+ | *** ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x006f, 0x0000,
+0x0039, 0x0080,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0030, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x73):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ****** |
+ | ** ** |
+ | ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** ** |
+ | ****** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003f, 0x0000,
+0x0061, 0x0080,
+0x0060, 0x0000,
+0x003f, 0x0000,
+0x0001, 0x0080,
+0x0001, 0x0080,
+0x0061, 0x0080,
+0x003f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x74):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ****** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x007e, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0018, 0x0000,
+0x0019, 0x0080,
+0x000f, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x75):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** *** |
+ | *** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0080,
+0x001d, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x76):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | **** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x77):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ** ** ** |
+ | ******** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x006d, 0x0080,
+0x007f, 0x0080,
+0x0033, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x78):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | **** |
+ | ** |
+ | ** |
+ | **** |
+ | ** ** |
+ | ** ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x001e, 0x0000,
+0x0033, 0x0000,
+0x0061, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x79):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** ** |
+ | ** *** |
+ | *** ** |
+ | ** |
+ | ** ** |
+ | ** ** |
+ | **** |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0080,
+0x001d, 0x0080,
+0x0001, 0x0080,
+0x0061, 0x0080,
+0x0033, 0x0000,
+0x001e, 0x0000,
+
+/* Character (0x7a):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | ******* |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ******* |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x003f, 0x0080,
+0x0001, 0x0080,
+0x0003, 0x0000,
+0x0006, 0x0000,
+0x000c, 0x0000,
+0x0018, 0x0000,
+0x0030, 0x0000,
+0x003f, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x7b):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0007, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0078, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0007, 0x0080,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x7c):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x7d):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | **** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | ** |
+ | **** |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0078, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0007, 0x0080,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x000c, 0x0000,
+0x0078, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+
+/* Character (0x7e):
+ bbw=10, bbh=20, bbx=0, bby=-4, width=10
+ +----------------+
+ | |
+ | |
+ | |
+ | *** ** |
+ | ** ** ** |
+ | ** *** |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +----------------+ */
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0039, 0x0080,
+0x006d, 0x0080,
+0x0067, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+0x0000, 0x0000,
+};
+
+/* Exported structure definition. */
+Font font_10x20 = {
+ font_10x20_glyphs,
+ 10,
+ 20
+};
--- /dev/null
+/**
+ * \file
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief General pourpose graphics routines
+ */
+
+#ifndef GFX_GFX_H
+#define GFX_GFX_H
+
+#include <cfg/compiler.h>
+#include <cpu/attr.h> /* CPU_HARVARD */
+
+#include <appconfig.h> /* CONFIG_GFX_* */
+
+/**
+ * \name Known pixel formats for bitmap representation.
+ * \{
+ */
+#define BITMAP_FMT_PLANAR_H_MSB 1 /**< Planar pixels, horizontal bytes, MSB left. */
+#define BITMAP_FMT_PLANAR_V_LSB 2 /**< Planar pixels, vertical bytes, LSB top. */
+/* \} */
+
+#if !defined(CONFIG_BITMAP_FMT) || (CONFIG_BITMAP_FMT != BITMAP_FMT_PLANAR_H_MSB && CONFIG_BITMAP_FMT != BITMAP_FMT_PLANAR_V_LSB)
+ #error CONFIG_BITMAP_FMT must be defined to either BITMAP_FMT_PLANAR_H_LSB or BITMAP_FMT_PLANAR_V_LSB
+#endif
+#if !defined(CONFIG_GFX_CLIPPING) || (CONFIG_GFX_CLIPPING != 0 && CONFIG_GFX_CLIPPING != 1)
+ #error CONFIG_GFX_CLIPPING must be defined to either 0 or 1
+#endif
+#if !defined(CONFIG_GFX_TEXT) || (CONFIG_GFX_TEXT != 0 && CONFIG_GFX_TEXT != 1)
+ #error CONFIG_GFX_TEXT must be defined to either 0 or 1
+#endif
+
+EXTERN_C_BEGIN
+
+/** Common type for coordinates expressed in pixel units */
+typedef int coord_t;
+typedef unsigned int ucoord_t;
+
+#if CONFIG_GFX_VCOORDS
+/** Common type for coordinates expressed in logical units */
+typedef float vcoord_t;
+#endif /* CONFIG_GFX_VCOORDS */
+
+
+/**
+ * Describe a rectangular area with coordinates expressed in pixels.
+ *
+ * The rectangle is represented in terms of its top/left and
+ * right/bottom borders.
+ *
+ * In some cases, rectangles are assumed to obey to the
+ * following invariants:
+ *
+ * xmin <= xmax
+ * ymin <= ymax
+ *
+ * Oddly, the xmin and ymin coordinates are inclusive, while the
+ * xmax and ymax coordinates are non-inclusive. This design
+ * decision makes several computations simpler and lets you
+ * specify empty (0x0) rectangles without breaking the
+ * invariants.
+ *
+ * Computing the size of a rectangle can be done by simply
+ * subtracting the maximum X or Y coordinate from the minimum
+ * X or Y coordinate.
+ */
+typedef struct Rect { coord_t xmin, ymin, xmax, ymax; } Rect;
+
+/**
+ * Return the width of a rectangle in pixels.
+ *
+ * \note The argument \a r is evaluated twice.
+ */
+#define RECT_WIDTH(r) ((r)->xmax - (r)->xmin)
+
+/**
+ * Return the height of a rectangle in pixels.
+ *
+ * \note The argument \a r is evaluated twice.
+ */
+#define RECT_HEIGHT(r) ((r)->ymax - (r)->ymin)
+
+/* Fwd decl */
+struct Font;
+
+/**
+ * Control structure to draw in a bitmap
+ *
+ * \todo For better ortogonality, split this structure into
+ * an Image and a plain drawing context called Painter.
+ */
+typedef struct Bitmap
+{
+ uint8_t *raster; /**< Pointer to byte array to hold the data */
+ coord_t width, height; /**< Width/Height in pixels */
+ coord_t stride; /**< Bytes per row. */
+ coord_t penX, penY; /**< Current pen position MoveTo()/LineTo() */
+
+#if CONFIG_GFX_CLIPPING || CONFIG_GFX_VCOORDS
+ Rect cr; /**< Clip drawing inside this rectangle */
+#endif
+
+#if CONFIG_GFX_TEXT
+ const struct Font *font;/**< Current font for text rendering. */
+
+ /**
+ * Algorithmic text style flags.
+ *
+ * The text rendering routine can apply a few simple transformations
+ * to the current font in order to generate common styles such as
+ * bold, italic and underline from plain glyphs.
+ *
+ * \see text_style()
+ */
+ uint8_t styles;
+#endif /* CONFIG_GFX_TEXT */
+
+#if CONFIG_GFX_VCOORDS
+ /**
+ * \name Logical coordinate system
+ * \{
+ */
+ vcoord_t orgX, orgY;
+ vcoord_t scaleX, scaleY;
+ /*\}*/
+#endif /* CONFIG_GFX_VCOORDS */
+
+} Bitmap;
+
+/**
+ * Hold image pixels.
+ *
+ * \todo Use this as Bitmap and change Bitmap to Drawable.
+ */
+typedef struct Image
+{
+ const uint8_t *raster; /**< Pointer to byte array to hold the data. */
+ coord_t width; /**< Raster width in pixels. */
+ coord_t height; /**< Raster height in pixels. */
+ coord_t stride; /**< Bytes per row. */
+} Image;
+
+#if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
+ /**
+ * Compute the size in bytes of a raster suitable for
+ * holding a bitmap of \a width x \a height pixels.
+ */
+ #define RAST_SIZE(width, height) ( ((width) + 7 / 8) * (height) )
+
+#elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
+ /**
+ * Compute the size in bytes of a raster suitable for
+ * holding a bitmap of \a width x \a height pixels.
+ */
+ #define RAST_SIZE(width, height) ( (width) * (((height) + 7) / 8) )
+#else
+ #error Unknown value of CONFIG_BITMAP_FMT
+#endif /* CONFIG_BITMAP_FMT */
+
+/* Function prototypes */
+void gfx_bitmapInit (Bitmap *bm, uint8_t *raster, coord_t w, coord_t h);
+void gfx_bitmapClear(Bitmap *bm);
+void gfx_blit (Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy);
+void gfx_blitRaster (Bitmap *dst, coord_t dx, coord_t dy, const uint8_t *raster, coord_t w, coord_t h, coord_t stride);
+void gfx_blitImage (Bitmap *dst, coord_t dx, coord_t dy, const Image *image);
+void gfx_line (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
+void gfx_rectDraw (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
+void gfx_rectFillC (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t color);
+void gfx_rectFill (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
+void gfx_rectClear (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
+void gfx_moveTo (Bitmap *bm, coord_t x, coord_t y);
+void gfx_lineTo (Bitmap *bm, coord_t x, coord_t y);
+void gfx_setClipRect(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord_t ymax);
+
+#if CPU_HARVARD
+ #include <mware/pgm.h>
+ void gfx_blit_P(Bitmap *bm, const pgm_uint8_t *raster);
+#endif
+
+#if CONFIG_GFX_TEXT
+INLINE void gfx_setFont(Bitmap *bm, const struct Font *font)
+{
+ bm->font = font;
+}
+#endif
+
+#if CONFIG_GFX_VCOORDS
+void gfx_setViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2);
+coord_t gfx_transformX(Bitmap *bm, vcoord_t x);
+coord_t gfx_transformY(Bitmap *bm, vcoord_t y);
+void gfx_vline(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2);
+#endif /* CONFIG_GFX_VCOORDS */
+
+EXTERN_C_END
+
+#endif /* GFX_GFX_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Graphics private header.
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2006/05/27 17:17:34 bernie
+ *#* Optimize away divisions in RAST_ADDR/MASK macros.
+ *#*
+ *#* Revision 1.5 2006/05/25 23:35:40 bernie
+ *#* Cleanup.
+ *#*
+ *#* Revision 1.4 2006/03/22 09:50:37 bernie
+ *#* Use the same format for fonts and rasters.
+ *#*
+ *#* Revision 1.3 2006/02/15 09:10:15 bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
+ *#* Revision 1.2 2006/02/10 12:28:33 bernie
+ *#* Add font support in bitmaps; Make bitmap formats public.
+ *#*
+ *#* Revision 1.1 2006/01/26 00:32:49 bernie
+ *#* Graphics private header.
+ *#*
+ *#*/
+
+#ifndef GFX_GFX_P_H
+#define GFX_GFX_P_H
+
+#include <gfx/gfx.h>
+
+#if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
+
+ /* We use ucoord_t to let the compiler optimize away the division/modulo. */
+ #define RAST_ADDR(raster, x, y, stride) \
+ ((raster) + (ucoord_t)(y) * (ucoord_t)(stride) + (ucoord_t)(x) / 8)
+ #define RAST_MASK(raster, x, y) \
+ (1 << (7 - (ucoord_t)(x) % 8))
+
+#elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
+
+ /* We use ucoord_t to let the compiler optimize away the division/modulo. */
+ #define RAST_ADDR(raster, x, y, stride) \
+ ((raster) + ((ucoord_t)(y) / 8) * (ucoord_t)(stride) + (ucoord_t)(x))
+ #define RAST_MASK(raster, x, y) \
+ (1 << ((ucoord_t)(y) % 8))
+
+#else
+ #error Unknown value of CONFIG_BITMAP_FMT
+#endif /* CONFIG_BITMAP_FMT */
+
+#define BM_ADDR(bm, x, y) RAST_ADDR((bm)->raster, (x), (y), (bm)->stride)
+#define BM_MASK(bm, x, y) RAST_MASK((bm)->raster, (x), (y))
+
+/**
+ * Plot a pixel in bitmap \a bm.
+ *
+ * \note bm is evaluated twice.
+ * \see BM_CLEAR BM_DRAWPIXEL
+ */
+#define BM_PLOT(bm, x, y) \
+ ( *BM_ADDR(bm, x, y) |= BM_MASK(bm, x, y) )
+
+/**
+ * Clear a pixel in bitmap \a bm.
+ *
+ * \note bm is evaluated twice.
+ * \see BM_PLOT BM_DRAWPIXEL
+ */
+#define BM_CLEAR(bm, x, y) \
+ ( *BM_ADDR(bm, x, y) &= ~BM_MASK(bm, x, y) )
+
+/**
+ * Set a pixel in bitmap \a bm to the specified color.
+ *
+ * \note bm is evaluated twice.
+ * \note This macro is somewhat slower than BM_PLOT and BM_CLEAR.
+ * \see BM_PLOT BM_CLEAR
+ */
+#define BM_DRAWPIXEL(bm, x, y, fg_pen) \
+ do { \
+ uint8_t *p = BM_ADDR(bm, x, y); \
+ uint8_t mask = BM_MASK(bm, x, y); \
+ *p = (*p & ~mask) | ((fg_pen) ? mask : 0); \
+ } while (0)
+
+/**
+ * Get the value of the pixel in bitmap \a bm.
+ *
+ * \return The returned value is either 0 or 1.
+ *
+ * \note bm is evaluated twice.
+ * \see BM_DRAWPIXEL
+ */
+#define BM_READPIXEL(bm, x, y) \
+ ( *BM_ADDR(bm, x, y) & BM_MASK(bm, x, y) ? 1 : 0 )
+
+#define RAST_READPIXEL(raster, x, y, stride) \
+ ( *RAST_ADDR(raster, x, y, stride) & RAST_MASK(raster, x, y) ? 1 : 0 )
+
+#endif /* GFX_GFX_P_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Line drawing graphics routines
+ */
+
+#include "gfx.h"
+#include "gfx_p.h"
+
+#include <cfg/debug.h> /* ASSERT() */
+#include <cfg/macros.h> /* SWAP() */
+#include <appconfig.h> /* CONFIG_GFX_CLIPPING */
+
+/* Configuration sanity checks */
+#if !defined(CONFIG_GFX_CLIPPING) || (CONFIG_GFX_CLIPPING != 0 && CONFIG_GFX_CLIPPING != 1)
+ #error CONFIG_GFX_CLIPPING must be defined to either 0 or 1
+#endif
+#if !defined(CONFIG_GFX_VCOORDS) || (CONFIG_GFX_VCOORDS != 0 && CONFIG_GFX_VCOORDS != 1)
+ #error CONFIG_GFX_VCOORDS must be defined to either 0 or 1
+#endif
+
+/**
+ * Draw a sloped line without performing clipping.
+ *
+ * Parameters are the same of gfx_line().
+ * This routine is based on the Bresenham Line-Drawing Algorithm.
+ *
+ * \note Passing coordinates outside the bitmap boundaries will
+ * result in memory trashing.
+ *
+ * \todo Optimize for vertical and horiziontal lines.
+ *
+ * \sa gfx_line()
+ */
+static void gfx_lineUnclipped(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
+{
+ int x, y, e, len, adx, ady, signx, signy;
+
+ if (x2 > x1)
+ {
+ /* left to right */
+ signx = +1;
+ adx = x2 - x1;
+ }
+ else
+ {
+ /* right to left */
+ signx = -1;
+ adx = x1 - x2;
+ }
+
+ if (y2 > y1)
+ {
+ /* top to bottom */
+ signy = +1;
+ ady = y2 - y1;
+ }
+ else
+ {
+ /* bottom to top */
+ signy = -1;
+ ady = y1 - y2;
+ }
+
+ x = x1;
+ y = y1;
+
+ if (adx > ady)
+ {
+ /* X-major line (octants 1/4/5/8) */
+
+ len = adx;
+ e = -adx;
+ while (len--)
+ {
+ /* Sanity check */
+ ASSERT((x >= 0) && (x < bm->width) && (y >= 0) && (y < bm->height));
+ BM_PLOT(bm, x, y);
+ x += signx;
+ e += ady;
+ if (e >= 0)
+ {
+ y += signy;
+ e -= adx;
+ }
+ }
+ }
+ else
+ {
+ /* Y-major line (octants 2/3/6/7) */
+
+ len = ady;
+ e = -ady;
+ while (len--)
+ {
+ /* Sanity check */
+ ASSERT ((x >= 0) && (x < bm->width) && (y >= 0) && (y < bm->height));
+ BM_PLOT(bm, x, y);
+ y += signy;
+ e += adx;
+ if (e >= 0)
+ {
+ x += signx;
+ e -= ady;
+ }
+ }
+ }
+}
+
+#if CONFIG_GFX_CLIPPING
+
+/// Helper routine for gfx_line().
+static int gfx_findRegion(int x, int y, Rect *cr)
+{
+ int code = 0;
+
+ if (y >= cr->ymax)
+ code |= 1; /* below */
+ else if (y < cr->ymin)
+ code |= 2; /* above */
+
+ if (x >= cr->xmax)
+ code |= 4; /* right */
+ else if (x < cr->xmin)
+ code |= 8; /* left */
+
+ return code;
+}
+
+#endif /* CONFIG_CLIPPING */
+
+/**
+ * Draw a sloped line segment.
+ *
+ * Draw a sloped line segment identified by the provided
+ * start and end coordinates on the bitmap \a bm.
+ *
+ * The line endpoints are clipped inside the current bitmap
+ * clipping rectangle using the Cohen-Sutherland algorithm,
+ * which is very fast.
+ *
+ * \note The point at coordinates \a x2 \a y2 is not drawn.
+ *
+ * \note This function does \b not update the current pen position.
+ *
+ * \todo Compute updated Bresenham error term.
+ */
+void gfx_line(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
+{
+#if CONFIG_GFX_CLIPPING
+ int clip1 = gfx_findRegion(x1, y1, &bm->cr);
+ int clip2 = gfx_findRegion(x2, y2, &bm->cr);
+
+ /* Loop while there is at least one point outside */
+ while (clip1 | clip2)
+ {
+ /* Check for line totally outside */
+ if (clip1 & clip2)
+ return;
+
+ int c = clip1 ? clip1 : clip2;
+ int x, y;
+
+ if (c & 1) /* Below */
+ {
+ x = x1 + (x2 - x1) * (bm->cr.ymax - y1) / (y2 - y1);
+ y = bm->cr.ymax - 1;
+ }
+ else if (c & 2) /* Above */
+ {
+ x = x1 + (x2 - x1) * (bm->cr.ymin - y1) / (y2 - y1);
+ y = bm->cr.ymin;
+ }
+ else if (c & 4) /* Right */
+ {
+ y = y1 + (y2 - y1) * (bm->cr.xmax - x1) / (x2 - x1);
+ x = bm->cr.xmax - 1;
+ }
+ else /* Left */
+ {
+ y = y1 + (y2 - y1) * (bm->cr.xmin - x1) / (x2 - x1);
+ x = bm->cr.xmin;
+ }
+
+ if (c == clip1) /* First endpoint was clipped */
+ {
+ // TODO: adjust Bresenham error term
+ //coord_t clipdx = ABS(x - x1);
+ //coord_t clipdy = ABS(y - y1);
+ //e += (clipdy * e2) + ((clipdx - clipdy) * e1);
+
+ x1 = x;
+ y1 = y;
+ clip1 = gfx_findRegion(x1, y1, &bm->cr);
+ }
+ else /* Second endpoint was clipped */
+ {
+ x2 = x;
+ y2 = y;
+ clip2 = gfx_findRegion(x2, y2, &bm->cr);
+ }
+ }
+#endif /* CONFIG_GFX_CLIPPING */
+
+ gfx_lineUnclipped(bm, x1, y1, x2, y2);
+}
+
+/**
+ * Move the current pen position to the specified coordinates.
+ *
+ * The pen position is used for drawing operations such as
+ * gfx_lineTo(), which can be used to draw polygons.
+ */
+void gfx_moveTo(Bitmap *bm, coord_t x, coord_t y)
+{
+ bm->penX = x;
+ bm->penY = y;
+}
+
+/**
+ * Draw a line from the current pen position to the new coordinates.
+ *
+ * \note This function moves the current pen position to the
+ * new coordinates.
+ *
+ * \sa gfx_line()
+ */
+void gfx_lineTo(Bitmap *bm, coord_t x, coord_t y)
+{
+ gfx_line(bm, bm->penX, bm->penY, x, y);
+ gfx_moveTo(bm, x, y);
+}
+
+
+/**
+ * Draw the perimeter of an hollow rectangle.
+ *
+ * \note The bottom-right corner of the rectangle is drawn at (x2-1;y2-1).
+ * \note This function does \b not update the current pen position.
+ */
+void gfx_rectDraw(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
+{
+ /* Sort coords (needed for correct bottom-right semantics) */
+ if (x1 > x2) SWAP(x1, x2);
+ if (y1 > y2) SWAP(y1, y2);
+
+ /* Draw rectangle */
+ gfx_line(bm, x1, y1, x2-1, y1);
+ gfx_line(bm, x2-1, y1, x2-1, y2-1);
+ gfx_line(bm, x2-1, y2-1, x1, y2-1);
+ gfx_line(bm, x1, y2-1, x1, y1);
+}
+
+
+/**
+ * Fill a rectangular area with \a color.
+ *
+ * \note The bottom-right border of the rectangle is not drawn.
+ *
+ * \note This function does \b not update the current pen position.
+ */
+void gfx_rectFillC(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t color)
+{
+ coord_t x, y;
+
+ /* Sort coords */
+ if (x1 > x2) SWAP(x1, x2);
+ if (y1 > y2) SWAP(y1, y2);
+
+#if CONFIG_GFX_CLIPPING
+ /* Clip rect to bitmap clip region */
+ if (x1 < bm->cr.xmin) x1 = bm->cr.xmin;
+ if (x2 < bm->cr.xmin) x2 = bm->cr.xmin;
+ if (x1 > bm->cr.xmax) x1 = bm->cr.xmax;
+ if (x2 > bm->cr.xmax) x2 = bm->cr.xmax;
+ if (y1 < bm->cr.ymin) y1 = bm->cr.ymin;
+ if (y2 < bm->cr.ymin) y2 = bm->cr.ymin;
+ if (y1 > bm->cr.ymax) y1 = bm->cr.ymax;
+ if (y2 > bm->cr.ymax) y2 = bm->cr.ymax;
+#endif /* CONFIG_GFX_CLIPPING */
+
+ /* NOTE: Code paths are duplicated for efficiency */
+ if (color) /* fill */
+ {
+ for (x = x1; x < x2; x++)
+ for (y = y1; y < y2; y++)
+ BM_PLOT(bm, x, y);
+ }
+ else /* clear */
+ {
+ for (x = x1; x < x2; x++)
+ for (y = y1; y < y2; y++)
+ BM_CLEAR(bm, x, y);
+ }
+}
+
+
+/**
+ * Draw a filled rectangle.
+ *
+ * \note The bottom-right border of the rectangle is not drawn.
+ *
+ * \note This function does \b not update the current pen position.
+ */
+void gfx_rectFill(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
+{
+ gfx_rectFillC(bm, x1, y1, x2, y2, 0xFF);
+}
+
+
+/**
+ * Clear a rectangular area.
+ *
+ * \note The bottom-right border of the rectangle is not cleared.
+ *
+ * \note This function does \b not update the current pen position.
+ */
+void gfx_rectClear(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
+{
+ gfx_rectFillC(bm, x1, y1, x2, y2, 0x00);
+}
+
+
+#if CONFIG_GFX_VCOORDS
+/**
+ * Imposta gli estremi del sistema di coordinate cartesiane rispetto
+ * al rettangolo di clipping della bitmap.
+ */
+void gfx_setViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2)
+{
+ ASSERT(x1 != x2);
+ ASSERT(y1 != y2);
+
+ bm->orgX = x1;
+ bm->orgY = y1;
+ bm->scaleX = (vcoord_t)(bm->cr.xmax - bm->cr.xmin - 1) / (vcoord_t)(x2 - x1);
+ bm->scaleY = (vcoord_t)(bm->cr.ymax - bm->cr.ymin - 1) / (vcoord_t)(y2 - y1);
+
+/* DB(kprintf("orgX = %f, orgY = %f, scaleX = %f, scaleY = %f\n",
+ bm->orgX, bm->orgY, bm->scaleX, bm->scaleY);)
+*/
+}
+
+
+/**
+ * Transform a coordinate from the current reference system to a
+ * pixel offset within the bitmap.
+ */
+coord_t gfx_transformX(Bitmap *bm, vcoord_t x)
+{
+ return bm->cr.xmin + (coord_t)((x - bm->orgX) * bm->scaleX);
+}
+
+/**
+ * Transform a coordinate from the current reference system to a
+ * pixel offset within the bitmap.
+ */
+coord_t gfx_transformY(Bitmap *bm, vcoord_t y)
+{
+ return bm->cr.ymin + (coord_t)((y - bm->orgY) * bm->scaleY);
+}
+
+
+/**
+ * Draw a line from (x1;y1) to (x2;y2).
+ */
+void gfx_vline(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2)
+{
+ gfx_line(bm,
+ gfx_transformX(bm, x1), gfx_transformY(bm, y1),
+ gfx_transformY(bm, x2), gfx_transformY(bm, y2));
+}
+#endif /* CONFIG_GFX_VCOORDS */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Text graphic routines
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.13 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.12 2006/05/25 23:35:22 bernie
+ *#* Implement correct and faster clipping for algo text.
+ *#*
+ *#* Revision 1.11 2006/05/15 07:21:06 bernie
+ *#* Doxygen fix.
+ *#*
+ *#* Revision 1.10 2006/04/27 05:39:23 bernie
+ *#* Enhance text rendering to arbitrary x,y coords.
+ *#*
+ *#* Revision 1.9 2006/04/11 00:08:24 bernie
+ *#* text_offset(): New function, but I'm not quite confident with the design.
+ *#*
+ *#* Revision 1.8 2006/03/22 09:50:37 bernie
+ *#* Use the same format for fonts and rasters.
+ *#*
+ *#* Revision 1.7 2006/03/20 17:51:55 bernie
+ *#* Cleanups.
+ *#*
+ *#* Revision 1.6 2006/03/13 02:05:54 bernie
+ *#* Mark slow paths as UNLIKELY.
+ *#*
+ *#* Revision 1.5 2006/03/07 22:18:04 bernie
+ *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute.
+ *#*
+ *#* Revision 1.4 2006/02/15 09:10:15 bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
+ *#* Revision 1.3 2006/02/10 12:31:55 bernie
+ *#* Add multiple font support in bitmaps.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:11:35 bernie
+ *#* Move graphics stuff from mware/ to gfx/.
+ *#*
+ *#* Revision 1.13 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.12 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.11 2005/01/20 18:46:31 aleph
+ *#* Fix progmem includes.
+ *#*
+ *#* Revision 1.10 2005/01/08 09:20:12 bernie
+ *#* Really make it work on both architectures.
+ *#*
+ *#* Revision 1.9 2004/12/31 16:44:29 bernie
+ *#* Sanitize for non-Harvard processors.
+ *#*
+ *#* Revision 1.8 2004/11/16 21:16:28 bernie
+ *#* Update to new naming scheme in mware/gfx.c.
+ *#*
+ *#* Revision 1.7 2004/09/20 03:28:28 bernie
+ *#* Fix header.
+ *#*
+ *#* Revision 1.6 2004/09/14 20:57:15 bernie
+ *#* Use debug.h instead of kdebug.h.
+ *#*
+ *#* Revision 1.5 2004/09/06 21:51:26 bernie
+ *#* Extend interface to allow any algorithmic style.
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 15:43:16 bernie
+ *#* Import mware modules.
+ *#*
+ *#* Revision 1.17 2004/05/15 16:57:01 aleph
+ *#* Fixes for non-DEBUG build
+ *#*
+ *#* Revision 1.16 2004/04/03 20:42:49 aleph
+ *#* Add text_clear()
+ *#*
+ *#* Revision 1.15 2004/03/24 15:03:45 bernie
+ *#* Use explicit include paths; clean Doxygen comments
+ *#*
+ *#* Revision 1.14 2004/03/19 16:52:28 bernie
+ *#* Move printf() like functions from text.c to text_format.c and add PROGMEM versions.
+ *#*
+ *#* Revision 1.13 2004/03/17 18:23:32 bernie
+ *#* Oops.
+ *#*
+ *#* Revision 1.12 2004/03/17 18:03:22 bernie
+ *#* Make diagnostic message shorter
+ *#*
+ *#* Revision 1.11 2004/03/13 22:52:54 aleph
+ *#* documentation fixes
+ *#*/
+
+#include <gfx/gfx.h>
+#include <gfx/font.h>
+#include <gfx/text.h>
+#include <gfx/text.h>
+
+#include <gfx/gfx_p.h> // FIXME: BM_DRAWPIXEL
+
+#include <cfg/debug.h>
+
+
+/**
+ * ANSI escape sequences flag: true for ESC state on.
+ *
+ * \todo Move to Bitmap.flags.
+ */
+static bool ansi_mode = false;
+
+/**
+ * Move (imaginary) cursor to coordinates specified.
+ */
+void text_setCoord(struct Bitmap *bm, int x, int y)
+{
+ bm->penX = x;
+ bm->penY = y;
+}
+
+
+/**
+ * Move (imaginary) cursor to column and row specified.
+ * Next text write will start a that row and col.
+ */
+void text_moveTo(struct Bitmap *bm, int row, int col)
+{
+ ASSERT(col >= 0);
+ ASSERT(col < bm->width / bm->font->width);
+ ASSERT(row >= 0);
+ ASSERT(row < bm->height / bm->font->height);
+
+ text_setCoord(bm, col * bm->font->width, row * bm->font->height);
+}
+
+
+/**
+ * Render char \a c on Bitmap \a bm.
+ */
+static int text_putglyph(char c, struct Bitmap *bm)
+{
+ const uint8_t * PROGMEM glyph; /* font is in progmem */
+ uint8_t glyph_width, glyph_height, glyph_height_bytes;
+ unsigned char index = (unsigned char)c;
+
+ /* Check for out of range char and replace with '?' or first char in font. */
+ if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
+ {
+ kprintf("Illegal char '%c' (0x%02x)\n", index, index);
+ if (FONT_HAS_GLYPH(bm->font, '?'))
+ index = '?';
+ else
+ index = bm->font->first;
+ }
+
+ /* Make character relative to font start */
+ index -= bm->font->first;
+
+ glyph_height = bm->font->height;
+ // FIXME: for vertical fonts only
+ glyph_height_bytes = (glyph_height + 7) / 8;
+
+ if (bm->font->offset)
+ {
+ /* Proportional font */
+ glyph_width = bm->font->widths[index]; /* TODO: optimize away */
+ glyph = bm->font->glyph + bm->font->offset[index];
+ }
+ else
+ {
+ /*
+ * Fixed-width font: compute the first column of pixels
+ * of the selected glyph using the character code to index
+ * the glyph array.
+ */
+ glyph_width = bm->font->width;
+
+ //For horizontal fonts
+ //glyph = bm->font->glyph + index * (((glyph_width + 7) / 8) * glyph_height);
+ glyph = bm->font->glyph + index * glyph_height_bytes * glyph_width;
+ }
+
+ /* Slow path for styled glyphs */
+ if (UNLIKELY(bm->styles))
+ {
+ uint8_t styles = bm->styles;
+ uint8_t prev_dots = 0, italic_prev_dots = 0;
+ uint8_t dots;
+ uint8_t row, col, row_bit;
+
+ /*
+ * To avoid repeating clipping and other expensive computations,
+ * we cluster calls to gfx_blitRaster() using a small buffer.
+ */
+ #define CONFIG_TEXT_RENDER_OPTIMIZE 1
+ #if CONFIG_TEXT_RENDER_OPTIMIZE
+ #define RENDER_BUF_WIDTH 12
+ #define RENDER_BUF_HEIGHT 8
+ uint8_t render_buf[RAST_SIZE(RENDER_BUF_WIDTH, RENDER_BUF_HEIGHT)];
+ uint8_t render_xpos = 0;
+ #endif
+
+ /* This style alone could be handled by the fast path too */
+ if (bm->styles & STYLEF_CONDENSED)
+ --glyph_width;
+
+ if (bm->styles & STYLEF_EXPANDED)
+ glyph_width *= 2;
+
+ for (row = 0, row_bit = 0; row < glyph_height_bytes; ++row, row_bit += 8)
+ {
+ /* For each dot column in the glyph... */
+ for (col = 0; col < glyph_width; ++col)
+ {
+ uint8_t src_col = col;
+
+ /* Expanded style: advances only once every two columns. */
+ if (styles & STYLEF_EXPANDED)
+ src_col /= 2;
+
+ /* Fetch a column of dots from glyph. */
+ dots = PGM_READ_CHAR(RAST_ADDR(glyph, src_col, row_bit, glyph_width));
+
+ /* Italic: get lower 4 dots from previous column */
+ if (styles & STYLEF_ITALIC)
+ {
+ uint8_t new_dots = dots;
+ dots = (dots & 0xF0) | italic_prev_dots;
+ italic_prev_dots = new_dots & 0x0F;
+ }
+
+ /* Bold: "or" pixels with the previous column */
+ if (styles & STYLEF_BOLD)
+ {
+ uint8_t new_dots = dots;
+ dots |= prev_dots;
+ prev_dots = new_dots;
+ }
+
+ /* Underlined: turn on base pixel */
+ if ((styles & STYLEF_UNDERLINE)
+ && (row == glyph_height_bytes - 1))
+ dots |= (1 << (glyph_height - row_bit - 1));
+
+ /* Inverted: invert pixels */
+ if (styles & STYLEF_INVERT)
+ dots = ~dots;
+
+ /* Output dots */
+ #if CONFIG_TEXT_RENDER_OPTIMIZE
+ render_buf[render_xpos++] = dots;
+ if (render_xpos == RENDER_BUF_WIDTH)
+ {
+ gfx_blitRaster(bm, bm->penX + col - render_xpos + 1, bm->penY + row_bit,
+ render_buf, render_xpos,
+ MIN((uint8_t)RENDER_BUF_HEIGHT, (uint8_t)(glyph_height - row_bit)),
+ RENDER_BUF_WIDTH);
+ render_xpos = 0;
+ }
+ #else
+ gfx_blitRaster(bm, bm->penX + col, bm->penY + row_bit,
+ &dots, 1, MIN((uint8_t)8, glyph_height - row_bit), 1);
+ #endif
+ }
+
+ #if CONFIG_TEXT_RENDER_OPTIMIZE
+ /* Flush out rest of render buffer */
+ if (render_xpos != 0)
+ {
+ gfx_blitRaster(bm, bm->penX + col - render_xpos, bm->penY + row_bit,
+ render_buf, render_xpos,
+ MIN((uint8_t)RENDER_BUF_HEIGHT, (uint8_t)(glyph_height - row_bit)),
+ RENDER_BUF_WIDTH);
+ render_xpos = 0;
+ }
+ #endif
+ }
+ }
+ else
+ {
+ /* No style: fast vanilla copy of glyph to bitmap */
+ gfx_blitRaster(bm, bm->penX, bm->penY, glyph, glyph_width, glyph_height, glyph_width);
+ }
+
+ /* Update current pen position */
+ bm->penX += glyph_width;
+
+ return c;
+}
+
+
+/**
+ * Render char \c c, with (currently) limited ANSI escapes
+ * emulation support and '\n' for newline.
+ */
+int text_putchar(char c, struct Bitmap *bm)
+{
+ /* Handle ANSI escape sequences */
+ if (UNLIKELY(ansi_mode))
+ {
+ switch (c)
+ {
+ case ANSI_ESC_CLEARSCREEN:
+ gfx_bitmapClear(bm);
+ bm->penX = 0;
+ bm->penY = 0;
+ text_style(bm, 0, STYLEF_MASK);
+ break;
+ DB(default:
+ kprintf("Unknown ANSI esc code: %x\n", c);)
+ }
+ ansi_mode = false;
+ }
+ else if (c == '\033') /* Enter ANSI ESC mode */
+ {
+ ansi_mode = true;
+ }
+ else if (c == '\n') /* Go one line down on a line-feed */
+ {
+ if (bm->penY + bm->font->height < bm->height)
+ {
+ bm->penY += bm->font->height;
+ bm->penX = 0;
+ }
+ }
+ else
+ {
+ text_putglyph(c, bm);
+ }
+ return c;
+}
+
+
+/**
+ * Clear the screen and reset cursor position
+ */
+void text_clear(struct Bitmap *bmp)
+{
+ text_putchar('\x1b', bmp);
+ text_putchar('c', bmp);
+}
+
+
+void text_clearLine(struct Bitmap *bm, int line)
+{
+ gfx_rectClear(bm, 0, line * bm->font->height, bm->width, (line + 1) * bm->font->height);
+}
+
+
+/**
+ * Set/clear algorithmic font style bits.
+ *
+ * \param bm Pointer to Bitmap to affect.
+ * \param flags Style flags to set
+ * \param mask Mask of flags to modify
+ * \return Old style flags
+ *
+ * Examples:
+ * Turn on bold, leave other styles alone
+ * \code text_style(bm, STYLEF_BOLD, STYLEF_BOLD); \endcode
+ *
+ * Turn off bold and turn on italic, leave others as they are
+ * \code text_style(bm, STYLEF_ITALIC, STYLEF_BOLD | STYLEF_ITALIC); \endcode
+ *
+ * Query current style without chaning it
+ * \code style = text_style(bm, 0, 0); \endcode
+ *
+ * Reset all styles (plain text)
+ * \code text_style(bm, 0, STYLE_MASK); \endcode
+ */
+uint8_t text_style(struct Bitmap *bm, uint8_t flags, uint8_t mask)
+{
+ uint8_t old = bm->styles;
+ bm->styles = (bm->styles & ~mask) | flags;
+ return old;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Text graphic routines (interface)
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \version $Id$
+ */
+
+#ifndef GFX_TEXT_H
+#define GFX_TEXT_H
+
+#include <cfg/compiler.h>
+#include <cfg/macros.h> /* BV() */
+#include <cpu/attr.h> /* CPU_HARVARD */
+#include <gfx/gfx.h> /* coord_t */
+
+#include <stdarg.h>
+
+/**
+ * \name Style flags
+ * \see text_style()
+ * \{
+ */
+#define STYLEF_BOLD BV(0)
+#define STYLEF_ITALIC BV(1)
+#define STYLEF_UNDERLINE BV(2)
+#define STYLEF_INVERT BV(3)
+#define STYLEF_EXPANDED BV(4)
+#define STYLEF_CONDENSED BV(5)
+#define STYLEF_STRIKEOUT BV(6) /*<! Not implemented */
+#define STYLEF_TALL BV(7) /*<! Not implemented */
+
+#define STYLEF_MASK \
+ (STYLEF_BOLD | STYLEF_ITALIC | STYLEF_UNDERLINE \
+ | STYLEF_INVERT | STYLEF_EXPANDED | STYLEF_CONDENSED \
+ | STYLEF_STRIKEOUT | STYLEF_TALL)
+/*\}*/
+
+/**
+ * \name Formatting flags for text rendering
+ * \see text_xprintf()
+ * \{
+ */
+#define TEXT_NORMAL 0 /**< Normal mode */
+#define TEXT_FILL BV(13) /**< Fill rest of line with spaces */
+#define TEXT_CENTER BV(14) /**< Center string in line */
+#define TEXT_RIGHT BV(15) /**< Right aligned */
+/*\}*/
+
+/** Escape sequences codes */
+#define ANSI_ESC_CLEARSCREEN 'c'
+
+
+/* Fwd decl */
+struct Bitmap;
+
+/* Low-level text functions (mware/text.c) */
+void text_moveTo(struct Bitmap *bm, int row, int col);
+void text_setCoord(struct Bitmap *bm, int x, int y);
+int text_putchar(char c, struct Bitmap *bm);
+uint8_t text_style(struct Bitmap *bm, uint8_t flags, uint8_t mask);
+void text_clear(struct Bitmap *bm);
+void text_clearLine(struct Bitmap *bm, int line);
+
+/* Text formatting functions (mware/text_format.c) */
+int text_puts(const char *str, struct Bitmap *bm);
+int text_vprintf(struct Bitmap *bm, const char *fmt, va_list ap);
+int text_printf(struct Bitmap *bm, const char *fmt, ...) FORMAT(__printf__, 2, 3);
+int text_xyvprintf(struct Bitmap *bm, coord_t x, coord_t y, uint16_t mode, const char *fmt, va_list ap);
+int text_xyprintf(struct Bitmap *bm, coord_t x, coord_t col, uint16_t mode, const char *fmt, ...) FORMAT(__printf__, 5, 6);
+int text_xprintf(struct Bitmap *bm, uint8_t row, uint8_t col, uint16_t mode, const char *fmt, ...) FORMAT(__printf__, 5, 6);
+int text_vwidthf(struct Bitmap *bm, const char * fmt, va_list ap);
+int text_widthf(struct Bitmap *bm, const char * fmt, ...) FORMAT(__printf__, 2, 3);
+
+/* Text formatting functions for program-memory strings (mware/text_format.c) */
+#if CPU_HARVARD
+#include <mware/pgm.h>
+int text_puts_P(const char * PROGMEM str, struct Bitmap *bm);
+int text_vprintf_P(struct Bitmap *bm, const char * PROGMEM fmt, va_list ap);
+int text_printf_P(struct Bitmap *bm, const char * PROGMEM fmt, ...) FORMAT(__printf__, 2, 3);
+int text_xprintf_P(struct Bitmap *bm, uint8_t row, uint8_t col, uint16_t mode, const char * PROGMEM fmt, ...) FORMAT(__printf__, 5, 6);
+int text_vwidthf_P(struct Bitmap *bm, const char * PROGMEM fmt, va_list ap);
+int text_widthf_P(struct Bitmap *bm, const char * PROGMEM fmt, ...);
+#endif /* CPU_HARVARD */
+
+#endif /* GFX_TEXT_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief printf-family routines for text output
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.10 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.9 2006/04/27 05:39:24 bernie
+ *#* Enhance text rendering to arbitrary x,y coords.
+ *#*
+ *#* Revision 1.8 2006/03/22 09:50:11 bernie
+ *#* Don't use C99 stuff.
+ *#*
+ *#* Revision 1.7 2006/03/20 17:51:55 bernie
+ *#* Cleanups.
+ *#*
+ *#* Revision 1.6 2006/03/13 02:05:54 bernie
+ *#* Mark slow paths as UNLIKELY.
+ *#*
+ *#* Revision 1.5 2006/03/07 22:18:04 bernie
+ *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute.
+ *#*
+ *#* Revision 1.4 2006/02/10 12:31:33 bernie
+ *#* Add multiple font support in bitmaps.
+ *#*
+ *#* Revision 1.3 2005/11/27 23:31:58 bernie
+ *#* Reorder includes.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
+ *#* Revision 1.1 2005/11/04 18:11:35 bernie
+ *#* Move graphics stuff from mware/ to gfx/.
+ *#*
+ *#* Revision 1.10 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.9 2004/12/31 17:47:45 bernie
+ *#* Rename UNUSED() to UNUSED_ARG().
+ *#*
+ *#* Revision 1.8 2004/11/16 21:16:56 bernie
+ *#* Update to new naming scheme in mware/gfx.c.
+ *#*
+ *#* Revision 1.7 2004/10/03 19:05:04 bernie
+ *#* text_widthf(), text_vwidthf(): New functions.
+ *#*
+ *#* Revision 1.6 2004/09/14 20:59:04 bernie
+ *#* text_xprintf(): Support all styles; Pixel-wise text centering.
+ *#*
+ *#* Revision 1.5 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.4 2004/08/05 18:46:44 bernie
+ *#* Documentation improvements.
+ *#*
+ *#* Revision 1.3 2004/08/03 15:57:18 aleph
+ *#* Add include to fix warning for vsprintf()
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 15:43:16 bernie
+ *#* Import mware modules.
+ *#*
+ *#* Revision 1.2 2004/03/26 18:50:50 bernie
+ *#* Move _PROGMEM stuff to compiler.h
+ *#*
+ *#* Revision 1.1 2004/03/19 16:52:28 bernie
+ *#* Move printf() like functions from text.c to text_format.c and add PROGMEM versions.
+ *#*
+ *#*/
+
+#include "text.h"
+
+#include <mware/formatwr.h> /* _formatted_write() */
+#include <gfx/font.h>
+#include <gfx/gfx.h>
+
+#include <stdio.h> /* vsprintf() */
+#include <stdarg.h>
+#include <string.h> /* strlen() */
+
+/**
+ * Render string \a str in Bitmap \a bm at current cursor position
+ *
+ * \note Text formatting functions are also available with an _P suffix
+ * accepting the source string from program memory. This feature
+ * is only available (and useful) on Harvard microprocessors such
+ * as the AVR.
+ *
+ * \see text_putchar()
+ */
+int PGM_FUNC(text_puts)(const char * PGM_ATTR str, struct Bitmap *bm)
+{
+ char c;
+
+ while ((c = PGM_READ_CHAR(str++)))
+ text_putchar(c, bm);
+
+ return 0;
+}
+
+
+/**
+ * vprintf()-like formatter to render text in a Bitmap.
+ *
+ * Perform vprintf()-like formatting on the \a fmt format string using the
+ * variable-argument list \a ap.
+ * Render the resulting string in Bitmap \a bm starting at the current
+ * cursor position.
+ *
+ * \see text_puts() text_putchar() text_printf()
+ */
+int PGM_FUNC(text_vprintf)(struct Bitmap *bm, const char * PGM_ATTR fmt, va_list ap)
+{
+ return PGM_FUNC(_formatted_write)(fmt, (void (*)(char, void *))text_putchar, bm, ap);
+}
+
+/**
+ * printf()-like formatter to render text in a Bitmap.
+ *
+ * Perform printf()-like formatting on the \a fmt format string.
+ * Render the resulting string in Bitmap \a bm starting at the
+ * current cursor position.
+ *
+ * \see text_puts() text_putchar() text_vprintf()
+ */
+int PGM_FUNC(text_printf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
+{
+ int len;
+
+ va_list ap;
+ va_start(ap, fmt);
+ len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
+ va_end(ap);
+
+ return len;
+}
+
+/**
+ * Render text with vprintf()-like formatting at a specified pixel position.
+ *
+ * \see text_xyprintf()
+ */
+int PGM_FUNC(text_xyvprintf)(struct Bitmap *bm,
+ coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, va_list ap)
+{
+ int len;
+ uint8_t oldstyle = 0;
+
+ text_setCoord(bm, x, y);
+
+ if (style & STYLEF_MASK)
+ oldstyle = text_style(bm, style, STYLEF_MASK);
+
+ if (style & (TEXT_CENTER | TEXT_RIGHT))
+ {
+ uint8_t pad = bm->width - PGM_FUNC(text_vwidthf)(bm, fmt, ap);
+
+ if (style & TEXT_CENTER)
+ pad /= 2;
+
+ if (style & TEXT_FILL)
+ gfx_rectFillC(bm, 0, y, pad, y + bm->font->height,
+ (style & STYLEF_INVERT) ? 0xFF : 0x00);
+
+ text_setCoord(bm, pad, y);
+ }
+
+ len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
+
+ if (style & TEXT_FILL)
+ gfx_rectFillC(bm, bm->penX, y, bm->width, y + bm->font->height,
+ (style & STYLEF_INVERT) ? 0xFF : 0x00);
+
+ /* Restore old style */
+ if (style & STYLEF_MASK)
+ text_style(bm, oldstyle, STYLEF_MASK);
+
+ return len;
+}
+
+
+/**
+ * Render text with printf()-like formatting at a specified pixel position.
+ *
+ * \param bm Bitmap where to render the text
+ * \param x [pixels] Initial X coordinate of text.
+ * \param y [pixels] Coordinate of top border of text.
+ * \param style Formatting style to use. In addition to any STYLEF_
+ * flag, it can be TEXT_NORMAL, TEXT_FILL, TEXT_INVERT or
+ * TEXT_RIGHT, or a combination of these flags ORed together.
+ * \param fmt String possibly containing printf() formatting commands.
+ *
+ * \see text_puts() text_putchar() text_printf() text_vprintf()
+ * \see text_moveTo() text_style()
+ */
+int PGM_FUNC(text_xyprintf)(struct Bitmap *bm,
+ coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, ...)
+{
+ int len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ len = PGM_FUNC(text_xyvprintf)(bm, x, y, style, fmt, ap);
+ va_end(ap);
+
+ return len;
+}
+
+
+/**
+ * Render text with printf()-like formatting at a specified row/column position.
+ *
+ * \see text_xyprintf()
+ */
+int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
+ uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
+{
+ int len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ len = PGM_FUNC(text_xyvprintf)(
+ bm, col * bm->font->width, row * bm->font->height,
+ style, fmt, ap);
+ va_end(ap);
+
+ return len;
+}
+
+
+struct TextWidthData
+{
+ Bitmap *bitmap;
+ coord_t width;
+};
+
+/**
+ * Compute width in pixels of a character.
+ *
+ * Compute the on screen width of a character, taking the
+ * current style and font into account.
+ *
+ * The width is accumulated in the WidthData structure
+ * passed as second argument.
+ *
+ * This is a formatted_write() callback used by text_vwidthf()
+ * to compute the length of a formatted string.
+ */
+static int text_charWidth(int c, struct TextWidthData *twd)
+{
+ unsigned char index = (unsigned char)c;
+ Bitmap *bm = twd->bitmap;
+ coord_t glyph_width;
+
+
+ if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
+ {
+ if (!FONT_HAS_GLYPH(bm->font, '?'))
+ index = '?';
+ else
+ index = bm->font->first;
+ }
+
+ /* Make character relative to font start */
+ index -= bm->font->first;
+
+ if (bm->font->offset)
+ /* Proportional font */
+ glyph_width = bm->font->widths[index]; /* TODO: optimize away */
+ else
+ /* Fixed width font */
+ glyph_width = bm->font->width;
+
+ if (bm->styles & STYLEF_CONDENSED)
+ --glyph_width;
+
+ if (bm->styles & STYLEF_EXPANDED)
+ glyph_width *= 2;
+
+ twd->width += glyph_width;
+
+ return c;
+}
+
+/**
+ * Return the width in pixels of a vprintf()-formatted string.
+ */
+int PGM_FUNC(text_vwidthf)(
+ UNUSED_ARG(struct Bitmap *, bm),
+ const char * PGM_ATTR fmt,
+ va_list ap)
+{
+ /* Fixed font with no styles affecting the width? */
+ if (!bm->font->offset && !(bm->styles & (STYLEF_CONDENSED | STYLEF_EXPANDED)))
+ return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width;
+ else
+ {
+ struct TextWidthData twd;
+ twd.bitmap = bm;
+ twd.width = 0;
+ _formatted_write(fmt, (void (*)(char, void *))text_charWidth, &twd, ap);
+ return twd.width;
+ }
+}
+
+
+/**
+ * Return the width in pixels of a printf()-formatted string.
+ */
+int PGM_FUNC(text_widthf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
+{
+ int width;
+
+ va_list ap;
+ va_start(ap, fmt);
+ width = PGM_FUNC(text_vwidthf)(bm, fmt, ap);
+ va_end(ap);
+
+ return width;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Very simple hierarchical windowing system.
+ *
+ * All functions in this module are to be intended as methods
+ * of the Window class. Please see its documentation
+ * for a module-wise introduction.
+ *
+ * \see struct Window
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/08/01 17:26:04 batt
+ *#* Update docs.
+ *#*
+ *#* Revision 1.1 2006/08/01 15:43:01 batt
+ *#* Add in board_kd current edited channel visualization.
+ *#*
+ *#* Revision 1.4 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.3 2006/02/10 12:25:41 bernie
+ *#* Add missing header.
+ *#*
+ *#* Revision 1.2 2006/01/26 00:36:48 bernie
+ *#* Const correctness for some new functions.
+ *#*
+ *#* Revision 1.1 2006/01/23 23:14:29 bernie
+ *#* Implement simple, but impressive windowing system.
+ *#*
+ *#*/
+
+#include "win.h"
+#include <mware/list.h>
+
+/**
+ * Map the contents of all child-windows into the bitmap of \a w.
+ *
+ * \note Recursively drawing children into their parent
+ * effectively damages the parent buffer.
+ */
+void win_compose(Window *w)
+{
+ Window *child;
+
+ /*
+ * Walk over all children, in back to front order and tell them
+ * to compose into us.
+ */
+ REVERSE_FOREACH_NODE(child, &w->children)
+ {
+ /* Recursively compose child first. */
+ win_compose(child);
+
+ /* Draw child into our bitmap. */
+ if (w->bitmap)
+ gfx_blit(w->bitmap, &child->geom, child->bitmap, 0, 0);
+ }
+}
+
+/**
+ * Map window \a w into \a parent.
+ *
+ * The new window becomes the topmost window.
+ *
+ * \note Opening a window twice is illegal.
+ *
+ * \see win_close()
+ */
+void win_open(Window *w, Window *parent)
+{
+ ASSERT(!w->parent);
+ w->parent = parent;
+ ADDHEAD(&parent->children, &w->link);
+}
+
+/**
+ * Detach window from its parent.
+ *
+ * Closing a window causes it to become orphan of its
+ * parent. Its content will no longer appear in its
+ * parent after the next refresh cycle.
+ *
+ * \note Closing a window that has not been previously
+ * opened is illegal.
+ *
+ * \see win_open()
+ */
+void win_close(Window *w)
+{
+ ASSERT(w->parent);
+ REMOVE(&w->link);
+ w->parent = NULL;
+}
+
+/**
+ * Move window to the topmost position relative to its sibling.
+ *
+ * \see win_move(), win_resize(), win_setGeometry()
+ */
+void win_raise(Window *w)
+{
+ ASSERT(w->parent);
+ REMOVE(&w->link);
+ ADDHEAD(&w->parent->children, &w->link);
+}
+
+/**
+ * Set window position and size at the same time.
+ *
+ * This function is equivalent to subsequent calls to win_move()
+ * and win_resize() using the coordinates provided by the
+ * \a new_geom rectangle.
+ *
+ * \note The xmax and ymax members of \a new_geom are non-inclusive,
+ * as usual for the Rect interface.
+ *
+ * \see win_move()
+ * \see win_resize()
+ */
+void win_setGeometry(Window *w, const Rect *new_geom)
+{
+ // requires C99?
+ // memcpy(&w->geom, new_geom, sizeof(w->geom));
+ w->geom = *new_geom;
+}
+
+/**
+ * Move window to specified position.
+ *
+ * Move the window top-left corner to the pixel coordinates
+ * \a left and \a top, which are relative to the parent window.
+ *
+ * \note A window can also be moved outside the borders
+ * of its parent, or at negative coordinates.
+ *
+ * \note It is allowed to move an orphan window.
+ */
+void win_move(Window *w, coord_t left, coord_t top)
+{
+ Rect r;
+
+ r.xmin = left;
+ r.ymin = top;
+ r.xmax = r.xmin + RECT_WIDTH(&w->geom);
+ r.ymax = r.ymin + RECT_WIDTH(&w->geom);
+
+ win_setGeometry(w, &r);
+}
+
+/**
+ * Resize the rectangle of a window.
+ *
+ * The window shrinks or grows to the specified size.
+ *
+ * \note Growing a window beyond the size of its
+ * backing bitmap results in unspecified behavior.
+ *
+ * \note It is allowed to resize an orphan window.
+ */
+void win_resize(Window *w, coord_t width, coord_t height)
+{
+ Rect r;
+
+ r.xmin = w->geom.xmin;
+ r.ymin = w->geom.ymin;
+ r.xmax = r.xmin + width;
+ r.ymax = r.ymin + height;
+
+ win_setGeometry(w, &r);
+}
+
+/**
+ * Initialize a new window structure.
+ *
+ * The new window initial position is set to (0,0).
+ * The size is set to the size of the installed bitmap,
+ * or (0,0) if there's no backing store.
+ *
+ * \arg bm The bitmap to install as backing store
+ * for drawing into the window, or NULL if
+ * the window is not drawable.
+ */
+void win_create(Window *w, Bitmap *bm)
+{
+ w->parent = NULL;
+ w->bitmap = bm;
+ w->geom.xmin = 0;
+ w->geom.ymin = 0;
+ if (bm)
+ {
+ w->geom.xmax = bm->width;
+ w->geom.ymax = bm->height;
+ }
+ LIST_INIT(&w->children);
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Very simple hierarchical windowing system.
+ *
+ * All functions in this module are to be intended as methods
+ * of the Window class. Please see its documentation
+ * for a module-wise introduction.
+ *
+ * \see struct Window
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.3 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.2 2006/01/26 00:36:48 bernie
+ *#* Const correctness for some new functions.
+ *#*
+ *#* Revision 1.1 2006/01/23 23:14:29 bernie
+ *#* Implement simple, but impressive windowing system.
+ *#*
+ *#*/
+
+#ifndef GFX_WIN_H
+#define GFX_WIN_H
+
+#include <mware/list.h> /* Node, List */
+#include <gfx/gfx.h> /* coord_t */
+
+
+EXTERN_C_BEGIN
+
+/**
+ * Window handle and context structure.
+ *
+ * A window is a small rectangular area on the
+ * screen backed by its own bitmap where you
+ * can draw.
+ *
+ * A window can contain any number of children
+ * sub-windows that can be depth arranged with
+ * respect to their siblings.
+ *
+ * At any time, a window and all its children
+ * can be drawn into another bitmap to display
+ * a complete screen, taking depth and
+ * overlapping into account.
+ *
+ * This rendering model is commonly referred to as
+ * screen composition, and is quite popular among
+ * modern windowing systems.
+ */
+typedef struct Window
+{
+ Node link; /**< Link us with other siblings into our parent. */
+ struct Window *parent; /**< Our parent window. NULL for the root window. */
+
+ Bitmap *bitmap; /**< Pixel storage for window contents. */
+ Rect geom; /**< [px] Window size and position relative to parent. */
+
+ /**
+ * List of child windows, arranged by depth (front to back).
+ *
+ * Child top/left coordinates are relative to us.
+ */
+ List children;
+
+} Window;
+
+/*
+ * Public function prototypes
+ */
+void win_compose(Window *w);
+void win_open(Window *w, Window *parent);
+void win_close(Window *w);
+void win_raise(Window *w);
+void win_setGeometry(Window *w, const Rect *new_geom);
+void win_move(Window *w, coord_t left, coord_t top);
+void win_resize(Window *w, coord_t width, coord_t height);
+void win_create(Window *w, Bitmap *bm);
+
+EXTERN_C_END
+
+#endif /* GFX_WIN_H */
+
--- /dev/null
+/**
+ * \file
+ * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ *
+ * \brief Graphics user interface element to display a level bar.
+ *
+ * \version $Id$
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#include "levelbar.h"
+
+
+/**
+ * Initialize the LevelBar widget with the bitmap associated,
+ * the value range and the coordinates in the bitmap.
+ * \note The levelbar should be at least 5 pixels wide and high
+ * for correct borders drawing. No check is done on this.
+ */
+void lbar_init(struct LevelBar *lb, struct Bitmap *bmp, int type, int min, int max, int pos,
+ coord_t x1, coord_t y1, coord_t x2, coord_t y2)
+{
+ lb->bitmap = bmp;
+ lb->type = type;
+ lb->min = min;
+ lb->max = max;
+ lb->pos = pos;
+ lb->x1 = x1;
+ lb->y1 = y1;
+ lb->x2 = x2;
+ lb->y2 = y2;
+}
+
+
+/**
+ * Set the level.
+ */
+void lbar_setLevel(struct LevelBar *lb, int level)
+{
+ if (level < lb->min)
+ level = lb->min;
+ if (level > lb->max)
+ level = lb->max;
+
+ lb->pos = level;
+}
+
+
+/**
+ * Get current level.
+ */
+int lbar_getLevel(struct LevelBar *lb)
+{
+ return lb->pos;
+}
+
+
+/**
+ * Change level with respect to previous value
+ * (delta can be negative).
+ */
+void lbar_changeLevel(struct LevelBar *lb, int delta)
+{
+ lbar_setLevel(lb, lb->pos + delta);
+}
+
+
+/**
+ * Change the top limit.
+ */
+void lbar_setMax(struct LevelBar *lb, int max)
+{
+ lb->max = max;
+}
+
+
+/**
+ * Render the LevelBar on the bitmap.
+ */
+void lbar_draw(struct LevelBar *lb)
+{
+#define BORDERW 1
+#define BORDERH 1
+
+ /* Compute filled bar length in pixels */
+ int totlen = (lb->type & LBAR_HORIZONTAL) ? lb->x2 - lb->x1 - BORDERW*4 : lb->y2 - lb->y1 - BORDERH*4;
+ int range = lb->max - lb->min;
+ int barlen = ((long)(lb->pos - lb->min) * (long)totlen + range - 1) / range;
+
+ // Draw border
+ gfx_rectDraw(lb->bitmap, lb->x1, lb->y1, lb->x2, lb->y2);
+
+ // Clear inside
+ gfx_rectClear(lb->bitmap, lb->x1 + BORDERW, lb->y1 + BORDERH, lb->x2 - BORDERW, lb->y2 - BORDERH);
+
+ // Draw bar
+ if (lb->type & LBAR_HORIZONTAL)
+ gfx_rectFill(lb->bitmap,
+ lb->x1 + BORDERW*2, lb->y1 + BORDERH*2,
+ lb->x1 + BORDERW*2 + barlen, lb->y2 - BORDERH*2);
+ else
+ gfx_rectFill(lb->bitmap,
+ lb->x1 + BORDERW*2, lb->y2 - BORDERH*2 - barlen,
+ lb->x2 - BORDERW*2, lb->y2 - BORDERH*2);
+}
--- /dev/null
+/**
+ * \file
+ * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ *
+ * \version $Id$
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Graphics level bar widget
+ */
+
+#ifndef GUI_LEVELBAR_H
+#define GUI_LEVELBAR_H
+
+#include <gfx/gfx.h>
+
+
+/** Type of levelbar */
+#define LBAR_HORIZONTAL 1
+#define LBAR_VERTICAL 2
+
+typedef struct LevelBar
+{
+ struct Bitmap *bitmap;
+ int type;
+ int pos; ///< Current level
+ int min; ///< Minimum level
+ int max; ///< Maximum level
+ coord_t x1, y1, x2, y2; ///< Position of widget in the bitmap
+} LevelBar;
+
+void lbar_init(struct LevelBar *lb, struct Bitmap *bmp, int type, int min, int max, int pos,
+ coord_t x1, coord_t y1, coord_t x2, coord_t y2);
+void lbar_setLevel(struct LevelBar *lb, int level);
+int lbar_getLevel(struct LevelBar *lb);
+void lbar_changeLevel(struct LevelBar *lb, int delta);
+void lbar_setMax(struct LevelBar *lb, int max);
+void lbar_draw(struct LevelBar *lb);
+
+#endif /* GUI_LEVELBAR_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Generic editor for (volume/gain/contrast/...) setting.
+ *
+ * \version $Id$
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#include "leveledit.h"
+
+#include <cfg/macros.h> /* MAX() */
+#include <drv/kbd.h>
+#include <drv/timer.h>
+#include <gui/levelbar.h>
+#include <mware/pgm.h>
+#include <gfx/text.h>
+#include <gfx/font.h>
+#include <appconfig.h>
+
+#if CONFIG_MENU_MENUBAR
+#include <gui/menubar.h>
+#endif
+
+// BEGIN project_grl LOCAL
+#include <drv/lcd_gfx.h>
+#include <gui/guiman.h>
+// END project_grl LOCAL
+
+#define LBAR_HEIGHT 16
+
+/**
+ * Allow user to change level.
+ */
+void level_edit(struct LevelEdit *lev)
+{
+#if CONFIG_MENU_MENUBAR
+ /* Labels for menubars */
+ enum LabelId ch_labels[] = { LABEL_C1PLUS2, LABEL_CH_1, LABEL_CH_2 };
+ const_iptr_t labels[] =
+ {
+ (const_iptr_t)LABEL_BACK,
+ (const_iptr_t)LABEL_MINUS,
+ (const_iptr_t)LABEL_PLUS,
+ (const_iptr_t)LABEL_EMPTY
+ };
+ struct MenuBar mb;
+#endif /* CONFIG_MENU_MENUBAR */
+
+ struct LevelBar bar1, bar2;
+ keymask_t keys, old_rpt_mask;
+ int step, rep_step;
+
+ rep_step = MAX(lev->step, ((lev->max - lev->min) / 200));
+ step = lev->step;
+
+ // Allow keys repetition.
+ old_rpt_mask = kbd_setRepeatMask(K_UP | K_DOWN);
+
+ text_clear(lev->bitmap);
+ //text_style(STYLEF_UNDERLINE, STYLEF_UNDERLINE);
+ text_puts(lev->title, lev->bitmap);
+ //text_style(0, STYLEF_UNDERLINE);
+
+ if (lev->type & LEVELEDIT_DOUBLE)
+ {
+ int chn = 0; /* edit both channels */
+
+ /* Levelbars init */
+ lbar_init(&bar1, lev->bitmap, LBAR_HORIZONTAL,
+ lev->min, lev->max, *lev->ch1_val, 0, 16, lev->bitmap->width / 2 - 1, 23);
+ lbar_init(&bar2, lev->bitmap, LBAR_HORIZONTAL,
+ lev->min, lev->max, *lev->ch2_val, lev->bitmap->width / 2 + 1, 16, lev->bitmap->width, 23);
+
+ #if CONFIG_MENU_MENUBAR
+ labels[3] = (const_iptr_t)ch_labels[chn];
+ mbar_init(&mb, lev->bitmap, labels, countof(labels));
+ mbar_draw(&mb);
+ #endif /* CONFIG_MENU_MENUBAR */
+
+ /* Input loop for double level setting */
+ for (;;)
+ {
+ #if CONFIG_LEVELEDIT_TIMEOUT != 0
+ ticks_t idle_timeout = timer_clock();
+ #endif
+ do
+ {
+ if (lev->display_hook)
+ lev->display_hook(lev);
+ else
+ {
+ text_xprintf(lev->bitmap, 1, 0, TEXT_CENTER | TEXT_FILL, lev->unit);
+ PGM_FUNC(text_xprintf)(lev->bitmap, 1, 3, 0, PGM_STR("%d"), *lev->ch1_val);
+ PGM_FUNC(text_xprintf)(lev->bitmap, 1, 14, 0, PGM_STR("%d"), *lev->ch2_val);
+
+ lbar_setLevel(&bar1, *lev->ch1_val);
+ lbar_setLevel(&bar2, *lev->ch2_val);
+ lbar_draw(&bar1);
+ lbar_draw(&bar2);
+ }
+
+ #if CONFIG_LEVELEDIT_TIMEOUT != 0
+ if (timer_clock() - idle_timeout > ms_to_ticks(CONFIG_LEVELEDIT_TIMEOUT))
+ {
+ /* Accept input implicitly */
+ keys = K_OK;
+ break;
+ }
+ #endif
+ }
+ while (!(keys = kbd_peek()));
+
+ if (keys & K_CANCEL)
+ break;
+
+ if (keys & K_OK)
+ {
+ chn = (chn + 1) % 3;
+
+ #if CONFIG_MENU_MENUBAR
+ labels[3] = (const_iptr_t)ch_labels[chn];
+ mbar_draw(&mb);
+ #endif /* CONFIG_MENU_MENUBAR */
+ }
+
+ /* Increment step to achieve greater accelerations on larger values */
+ if (keys & K_REPEAT)
+ step = MIN(rep_step, step + 1);
+ else
+ step = lev->step;
+
+ if (keys & (K_UP | K_DOWN))
+ {
+ if (keys & K_UP)
+ {
+ /* If changing both channels (chn == 0), don't change
+ * level if one of two is at min or max */
+ if (chn != 0 ||
+ (*lev->ch1_val + step <= lev->max
+ && *lev->ch2_val + step <= lev->max))
+ {
+ /* If chn == 0 change both channels */
+ if (chn != 2)
+ {
+ *lev->ch1_val += step;
+ if (*lev->ch1_val > lev->max)
+ *lev->ch1_val = lev->max;
+ }
+ if (chn != 1)
+ {
+ *lev->ch2_val += step;
+ if (*lev->ch2_val > lev->max)
+ *lev->ch2_val = lev->max;
+ }
+ }
+ }
+ else
+ {
+ if (chn != 0 ||
+ (*lev->ch1_val - step >= lev->min
+ && *lev->ch2_val - step >= lev->min))
+ {
+ if (chn != 2)
+ {
+ *lev->ch1_val -= step;
+ if (*lev->ch1_val < lev->min)
+ *lev->ch1_val = lev->min;
+ }
+ if (chn != 1)
+ {
+ *lev->ch2_val -= step;
+ if (*lev->ch2_val < lev->min)
+ *lev->ch2_val = lev->min;
+ }
+ }
+ }
+
+ if (lev->set_hook)
+ lev->set_hook();
+ }
+ } // end for(;;)
+ }
+ else
+ {
+ const PGM_ATTR char *fmt = lev->unit ? PGM_STR("%d %s") : PGM_STR("%d");
+
+/*
+ const int textw = MAX(PGM_FUNC(text_widthf)(lev->bitmap, fmt, lev->max, lev->unit),
+ PGM_FUNC(text_widthf)(lev->bitmap, fmt, lev->min, lev->unit));
+
+ const coord_t barlen = lev->bitmap->width - 6 - textw;
+*/
+ const coord_t barlen = lev->bitmap->width;
+ const coord_t barvtop = lev->bitmap->height / 2 - LBAR_HEIGHT/2 + lev->bitmap->font->height;
+ lbar_init(&bar1, lev->bitmap, LBAR_HORIZONTAL,
+ lev->min, lev->max, *lev->ch1_val,
+ 0, barvtop, barlen, barvtop + LBAR_HEIGHT);
+
+ #if CONFIG_MENU_MENUBAR
+ mbar_init(&mb, lev->bitmap, labels, countof(labels));
+ mbar_draw(&mb);
+ #endif /* CONFIG_MENU_MENUBAR */
+
+ /* Input loop for single level setting */
+ for (;;)
+ {
+ #if CONFIG_LEVELEDIT_TIMEOUT != 0
+ ticks_t idle_timeout = timer_clock();
+ #endif
+ do
+ {
+ if (lev->display_hook)
+ lev->display_hook(lev);
+ else
+ {
+ if (lev->type != LEVELEDIT_NOBAR)
+ {
+ lbar_setLevel(&bar1, *lev->ch1_val);
+ lbar_draw(&bar1);
+ }
+ PGM_FUNC(text_xyprintf)(lev->bitmap, 0, bar1.y1 - lev->bitmap->font->height,
+ TEXT_CENTER | TEXT_FILL, fmt, *lev->ch1_val, lev->unit);
+ }
+
+ #if CONFIG_LEVELEDIT_TIMEOUT != 0
+ if (timer_clock() - idle_timeout > CONFIG_LEVELEDIT_TIMEOUT)
+ {
+ /* Accept input implicitly */
+ keys = K_CANCEL;
+ break;
+ }
+ #endif
+
+// BEGIN project_grl LOCAL
+#if 1
+ //FIXME: must to this only when needed
+ lcd_blitBitmap(&lcd_bitmap);
+ }
+ while (!(keys = GuiMan_KbdPeek()));
+#else
+ }
+ while (!(keys = kbd_peek()));
+#endif
+// END project_grl LOCAL
+
+ if (keys & K_CANCEL)
+ break;
+
+ /* Increment step to achieve greater accelerations on larger values */
+ if (keys & K_REPEAT)
+ step = MIN(rep_step, step + 1);
+ else
+ step = lev->step;
+
+ if (keys & K_UP)
+ {
+ *lev->ch1_val += step;
+ if (*lev->ch1_val > lev->max)
+ *lev->ch1_val = lev->max;
+ }
+
+ if (keys & K_DOWN)
+ {
+ *lev->ch1_val -= step;
+ if (*lev->ch1_val < lev->min)
+ *lev->ch1_val = lev->min;
+ }
+
+ if (lev->set_hook)
+ lev->set_hook();
+ }
+ }
+
+ kbd_setRepeatMask(old_rpt_mask);
+}
+
+/**
+ * LevelEdit structure initialization.
+ * Init data structure and init LevelEdit widgets.
+ */
+void level_init(struct LevelEdit *lev,
+ int type,
+ struct Bitmap *bmp, const char *title, const char *unit,
+ int min, int max, int step,
+ int *ch1_val, int *ch2_val,
+ level_set_callback *set_hook, display_callback *display_hook)
+{
+ lev->type = type;
+ lev->bitmap = bmp;
+ lev->title = title;
+ lev->unit = unit;
+ lev->min = min;
+ lev->max = max;
+ lev->step = step;
+
+ lev->ch1_val = ch1_val;
+ lev->ch2_val = ch2_val;
+ lev->set_hook = set_hook;
+ lev->display_hook = display_hook;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Generic editor for (volume/gain/contrast/...) setting.
+ *
+ * \version $Id$
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+#ifndef GUI_LEVELEDIT_H
+#define GUI_LEVELEDIT_H
+
+//#include <gui/levelbar.h>
+
+/* Type for level_init */
+#define LEVELEDIT_NOBAR 0 /**< Edit number only, without bar nor units */
+#define LEVELEDIT_SINGLE 1 /**< Single channel editing */
+#define LEVELEDIT_DOUBLE 2 /**< Double channel editing */
+
+
+
+/* Fwd decl */
+struct Bitmap;
+struct LevelEdit;
+
+/** Type for callback used to set meter levels */
+typedef void level_set_callback(void);
+
+/** Type for callback used to customize display of units */
+typedef void display_callback(struct LevelEdit *);
+
+/**
+ * State of a level meter
+ */
+typedef struct LevelEdit {
+ int type; /*<! Type of level edititing mode (see prev defines) */
+ const char *title; /*<! Title on top of screen */
+ const char *unit; /*<! Unit of quantity changed by this LevelEdit */
+ int min; /*<! Minimum level */
+ int max; /*<! Maximum level */
+ int step; /*<! Value of a single increment/decrement */
+
+ level_set_callback *set_hook; /*<! Callback called when a value is changed */
+ display_callback *display_hook; /*<! Callback for complex unit display */
+ int *ch1_val; /*<! (left) Value edited by this leveledit */
+ int *ch2_val; /*<! Right channel edited */
+
+ struct Bitmap *bitmap; /*<! Bitmap where the whole thing is rendered */
+} LevelEdit;
+
+
+void level_init(struct LevelEdit *lev,
+ int type,
+ struct Bitmap *bmp, const char *title, const char *unit,
+ int min, int max, int step,
+ int *ch1_val, int *ch2_val,
+ level_set_callback *change_hook, display_callback *display_hook);
+void level_edit(struct LevelEdit *lev);
+
+#endif /* GUI_LEVELEDIT_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief General pourpose menu handling functions
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.8 2006/09/13 13:58:32 bernie
+ *#* Add RenderHook support.
+ *#*
+ *#* Revision 1.7 2006/08/01 12:22:46 bernie
+ *#* Mention DevLib license.
+ *#*
+ *#* Revision 1.6 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.5 2006/06/03 13:58:01 bernie
+ *#* Fix recursive timeout and add exit status information.
+ *#*
+ *#* Revision 1.4 2006/06/02 12:26:18 bernie
+ *#* Draw graphical checkmarks.
+ *#*
+ *#* Revision 1.3 2006/05/28 15:03:31 bernie
+ *#* Avoid unnecessary rendering.
+ *#*
+ *#* Revision 1.2 2006/05/25 23:34:38 bernie
+ *#* Implement menu timeouts.
+ *#*
+ *#* Revision 1.1 2006/05/15 07:20:54 bernie
+ *#* Move menu to gui/.
+ *#*
+ *#* Revision 1.7 2006/04/27 05:39:24 bernie
+ *#* Enhance text rendering to arbitrary x,y coords.
+ *#*
+ *#* Revision 1.6 2006/04/11 00:07:32 bernie
+ *#* Implemenent MF_SAVESEL flag.
+ *#*
+ *#* Revision 1.5 2006/03/22 09:49:51 bernie
+ *#* Simplifications from project_grl.
+ *#*
+ *#* Revision 1.4 2006/03/20 17:48:35 bernie
+ *#* Implement support for ROM menus.
+ *#*
+ *#* Revision 1.3 2006/02/20 14:34:32 bernie
+ *#* Include appconfig.h before using its definitions.
+ *#*
+ *#* Revision 1.2 2006/02/15 09:10:51 bernie
+ *#* Make title bold; Fix height when we have no menubar.
+ *#*/
+
+#include "menu.h"
+
+#include <gfx/gfx.h>
+#include <gfx/font.h>
+#include <gfx/text.h>
+#include <drv/kbd.h>
+#include <cfg/compiler.h>
+#include <cfg/debug.h>
+#include <appconfig.h>
+#include <string.h> /* strcpy() */
+
+#if CPU_HARVARD
+#include <avr/pgmspace.h> /* strncpy_P() */
+#endif
+
+#if CONFIG_MENU_SMOOTH
+#include <drv/lcd_gfx.h>
+#endif
+
+#if (CONFIG_MENU_TIMEOUT != 0)
+#include <drv/timer.h>
+#endif
+
+#if CONFIG_MENU_MENUBAR
+#include "menubar.h"
+#endif
+
+#if defined(CONFIG_LOCALE) && (CONFIG_LOCALE == 1)
+#include "msg.h"
+#else
+#define PTRMSG(x) ((const char *)x)
+#endif
+
+
+/* Temporary fake defines for ABORT stuff... */
+#define abort_top 0
+#define PUSH_ABORT false
+#define POP_ABORT do {} while(0)
+#define DO_ABORT do {} while(0)
+
+
+/**
+ * Return the total number of items in in a menu.
+ */
+static int menu_count(const struct Menu *menu)
+{
+ int cnt = 0;
+
+ for (cnt = 0; /*NOP*/; ++cnt)
+ {
+ const MenuItem *item = &menu->items[cnt];
+#if CPU_HARVARD
+ MenuItem ram_item;
+ if (menu->flags & MF_ROMITEMS)
+ {
+ memcpy_P(&ram_item, item, sizeof(ram_item));
+ item = &ram_item;
+ }
+#endif
+ if (!(item->label || item->hook))
+ break;
+ }
+
+ return cnt;
+}
+
+#if CONFIG_MENU_MENUBAR
+
+/**
+ * Update the menu bar according to the selected item and redraw it.
+ */
+static void menu_update_menubar(
+ const struct Menu *menu,
+ struct MenuBar *mb,
+ int selected)
+{
+ int item_flags;
+#if CPU_HARVARD
+ if (menu->flags & MF_ROMITEMS)
+ {
+ ASSERT(sizeof(menu->items[selected].flags) == sizeof(int));
+ item_flags = pgm_read_int(&menu->items[selected].flags);
+ }
+ else
+#endif
+ item_flags = menu->items[selected].flags;
+
+ const_iptr_t newlabel = (const_iptr_t)LABEL_OK;
+
+ if (item_flags & MIF_DISABLED)
+ newlabel = (const_iptr_t)LABEL_EMPTY;
+ else if (item_flags & MIF_TOGGLE)
+ newlabel = (const_iptr_t)LABEL_SEL;
+ else if (item_flags & MIF_CHECKIT)
+ {
+ newlabel = (item_flags & MIF_CHECKED) ?
+ (const_iptr_t)LABEL_EMPTY : (const_iptr_t)LABEL_SEL;
+ }
+
+ mb->labels[3] = newlabel;
+ mbar_draw(mb);
+}
+#endif /* CONFIG_MENU_MENUBAR */
+
+
+static void menu_defaultRenderHook(struct Bitmap *bm, int ypos, bool selected, const struct MenuItem *item)
+{
+ if (item->flags & MIF_CHECKIT)
+ {
+ gfx_rectClear(bm, 0, ypos,
+ bm->font->height, ypos + bm->font->height);
+
+ if (item->flags & MIF_TOGGLE)
+ gfx_rectDraw(bm, 2, ypos + 2,
+ bm->font->height - 2, ypos + bm->font->height - 2);
+ if (item->flags & MIF_CHECKED)
+ {
+ gfx_line(bm,
+ 3, ypos + 3,
+ bm->font->height - 3, ypos + bm->font->height - 3);
+ gfx_line(bm,
+ bm->font->height - 3, ypos + 3,
+ 3, ypos + bm->font->height - 3);
+ }
+ }
+
+#if CPU_HARVARD
+ ((item->flags & MIF_RAMLABEL) ? text_xyprintf : text_xyprintf_P)
+#else
+ text_xyprintf
+#endif
+ (
+ bm, (item->flags & MIF_CHECKIT) ? bm->font->height : 0, ypos,
+ selected ? (STYLEF_INVERT | TEXT_FILL) : TEXT_FILL,
+ PTRMSG(item->label)
+ );
+}
+
+/**
+ * Show a menu on the display.
+ */
+static void menu_layout(
+ const struct Menu *menu,
+ int first_item,
+ int selected,
+ bool redraw)
+{
+ coord_t ypos;
+ int i;
+ const char * PROGMEM title = PTRMSG(menu->title);
+ Bitmap *bm = menu->bitmap;
+
+ ypos = bm->cr.ymin;
+
+#if 0
+ if (redraw)
+ {
+ /* Clear screen */
+ text_clear(menu->bitmap);
+ }
+#endif
+
+ if (title)
+ {
+ if (redraw)
+ text_xyprintf(bm, 0, ypos, STYLEF_UNDERLINE | STYLEF_BOLD | TEXT_CENTER | TEXT_FILL, title);
+ ypos += bm->font->height;
+ }
+
+#if CONFIG_MENU_SMOOTH
+ static coord_t yoffset = 0;
+ static int old_first_item = 0;
+ static int speed;
+ coord_t old_ymin = bm->cr.ymin;
+
+ /* Clip drawing inside menu items area */
+ gfx_setClipRect(bm,
+ bm->cr.xmin, bm->cr.ymin + ypos,
+ bm->cr.xmax, bm->cr.ymax);
+
+ if (old_first_item != first_item)
+ {
+ /* Speed proportional to distance */
+ speed = ABS(old_first_item - first_item) * 3;
+
+ if (old_first_item > first_item)
+ {
+ yoffset += speed;
+ if (yoffset > bm->font->height)
+ {
+ yoffset = 0;
+ --old_first_item;
+ }
+ }
+ else
+ {
+ yoffset -= speed;
+ if (yoffset < -bm->font->height)
+ {
+ yoffset = 0;
+ ++old_first_item;
+ }
+ }
+ first_item = MIN(old_first_item, menu_count(menu));
+
+ ypos += yoffset;
+ redraw = true;
+ }
+#endif /* CONFIG_MENU_SMOOTH */
+
+ if (redraw) for (i = first_item; /**/; ++i)
+ {
+ const MenuItem *item = &menu->items[i];
+#if CPU_HARVARD
+ MenuItem ram_item;
+ if (menu->flags & MF_ROMITEMS)
+ {
+ memcpy_P(&ram_item, item, sizeof(ram_item));
+ item = &ram_item;
+ }
+#endif /* CPU_HARVARD */
+
+ /* Check for end of room */
+ if (ypos > bm->cr.ymax)
+ break;
+
+ /* Check for end of menu */
+ if (!(item->label || item->hook))
+ break;
+
+ /* Only print visible items */
+ if (!(item->flags & MIF_HIDDEN))
+ {
+ /* Check if a special render function is supplied, otherwise use defaults */
+ RenderHook renderhook = (item->flags & MIF_RENDERHOOK) ? (RenderHook)item->label : menu_defaultRenderHook;
+
+ /* Render menuitem */
+ renderhook(menu->bitmap, ypos++, (i == selected), item);
+
+ ypos += bm->font->height;
+ }
+ }
+
+#if CONFIG_MENU_SMOOTH
+ if (redraw)
+ {
+ /* Clear rest of area */
+ gfx_rectClear(bm, bm->cr.xmin, ypos, bm->cr.xmax, bm->cr.ymax);
+
+ lcd_blitBitmap(&lcd_bitmap);
+ }
+
+ /* Restore old cliprect */
+ gfx_setClipRect(bm,
+ bm->cr.xmin, old_ymin,
+ bm->cr.xmax, bm->cr.ymax);
+
+#endif /* CONFIG_MENU_SMOOTH */
+}
+
+
+/**
+ * Handle menu item selection
+ */
+static iptr_t menu_doselect(const struct Menu *menu, struct MenuItem *item)
+{
+ iptr_t result = 0;
+
+ /* Exclude other items */
+ int mask, i;
+ for (mask = item->flags & MIF_EXCLUDE_MASK, i = 0; mask; mask >>= 1, ++i)
+ {
+ if (mask & 1)
+ menu->items[i].flags &= ~MIF_CHECKED;
+ }
+
+ if (item->flags & MIF_DISABLED)
+ return MENU_DISABLED;
+
+ /* Handle checkable items */
+ if (item->flags & MIF_TOGGLE)
+ item->flags ^= MIF_CHECKED;
+ else if (item->flags & MIF_CHECKIT)
+ item->flags |= MIF_CHECKED;
+
+ /* Handle items with callback hooks */
+ if (item->hook)
+ {
+ /* Push a jmp buffer to abort the operation with the STOP/CANCEL key */
+ if (!PUSH_ABORT)
+ {
+ result = item->hook(item->userdata);
+ POP_ABORT;
+ }
+ }
+ else
+ result = item->userdata;
+
+ return result;
+}
+
+
+/**
+ * Return the next visible item (rolls back to the first item)
+ */
+static int menu_next_visible_item(const struct Menu *menu, int index)
+{
+ int total = menu_count(menu);
+ int item_flags;
+
+ do
+ {
+ if (++index >= total)
+ index = 0;
+
+#if CPU_HARVARD
+ if (menu->flags & MF_ROMITEMS)
+ {
+ ASSERT(sizeof(menu->items[index].flags) == sizeof(int));
+ item_flags = pgm_read_int(&menu->items[index].flags);
+ }
+ else
+#endif
+ item_flags = menu->items[index].flags;
+ }
+ while (item_flags & MIF_HIDDEN);
+
+ return index;
+}
+
+
+/**
+ * Return the previous visible item (rolls back to the last item)
+ */
+static int menu_prev_visible_item(const struct Menu *menu, int index)
+{
+ int total = menu_count(menu);
+ int item_flags;
+
+ do
+ {
+ if (--index < 0)
+ index = total - 1;
+
+#if CPU_HARVARD
+ if (menu->flags & MF_ROMITEMS)
+ {
+ ASSERT(sizeof(menu->items[index].flags) == sizeof(int));
+ item_flags = pgm_read_int(&menu->items[index].flags);
+ }
+ else
+#endif
+ item_flags = menu->items[index].flags;
+ }
+ while (item_flags & MIF_HIDDEN);
+
+ return index;
+}
+
+
+/**
+ * Handle a menu and invoke hook functions for the selected menu items.
+ */
+iptr_t menu_handle(const struct Menu *menu)
+{
+ uint8_t items_per_page;
+ uint8_t first_item = 0;
+ uint8_t selected;
+ iptr_t result = 0;
+ bool redraw = true;
+
+#if (CONFIG_MENU_TIMEOUT != 0)
+ ticks_t now, menu_idle_time = timer_clock();
+#endif
+
+#if CONFIG_MENU_MENUBAR
+ struct MenuBar mb;
+ const_iptr_t labels[] =
+ {
+ (const_iptr_t)LABEL_BACK,
+ (const_iptr_t)LABEL_UPARROW,
+ (const_iptr_t)LABEL_DOWNARROW,
+ (const_iptr_t)0
+ };
+
+ /*
+ * Initialize menu bar
+ */
+ if (menu->flags & MF_TOPLEVEL)
+ labels[0] = (const_iptr_t)LABEL_EMPTY;
+
+ mbar_init(&mb, menu->bitmap, labels, countof(labels));
+#endif /* CONFIG_MENU_MENUBAR */
+
+
+ items_per_page =
+ (menu->bitmap->height / menu->bitmap->font->height)
+#if CONFIG_MENU_MENUBAR
+ - 1 /* menu bar labels */
+#endif
+ - (menu->title ? 1 : 0);
+
+ /* Selected item should be a visible entry */
+ //first_item = selected = menu_next_visible_item(menu, menu->selected - 1);
+ selected = menu->selected;
+ first_item = 0;
+
+ for(;;)
+ {
+ keymask_t key;
+
+ /*
+ * Keep selected item visible
+ */
+ while (selected < first_item)
+ first_item = menu_prev_visible_item(menu, first_item);
+ while (selected >= first_item + items_per_page)
+ first_item = menu_next_visible_item(menu, first_item);
+
+ menu_layout(menu, first_item, selected, redraw);
+ redraw = false;
+
+ #if CONFIG_MENU_MENUBAR
+ menu_update_menubar(menu, &mb, selected);
+ #endif
+
+ #if CONFIG_MENU_SMOOTH || (CONFIG_MENU_TIMEOUT != 0)
+ key = kbd_peek();
+ #else
+ key = kbd_get();
+ #endif
+
+ #if (CONFIG_MENU_TIMEOUT != 0)
+ /* Reset idle timer on key press. */
+ now = timer_clock();
+ if (key)
+ menu_idle_time = now;
+ #endif
+
+ if (key & K_OK)
+ {
+ struct MenuItem *item = &(menu->items[selected]);
+#if CPU_HARVARD
+ MenuItem ram_item;
+ if (menu->flags & MF_ROMITEMS)
+ {
+ memcpy_P(&ram_item, item, sizeof(ram_item));
+ item = &ram_item;
+ }
+#endif
+ result = menu_doselect(menu, item);
+ redraw = true;
+
+ /* Return immediately */
+ if (!(menu->flags & MF_STICKY))
+ break;
+
+ #if (CONFIG_MENU_TIMEOUT != 0)
+ /* Chain timeout */
+ if ((result == MENU_TIMEOUT) && !(menu->flags & MF_TOPLEVEL))
+ break;
+
+ /* Reset timeout */
+ menu_idle_time = timer_clock();
+ #endif
+ }
+ else if (key & K_UP)
+ {
+ selected = menu_prev_visible_item(menu, selected);
+ redraw = true;
+ }
+ else if (key & K_DOWN)
+ {
+ selected = menu_next_visible_item(menu, selected);
+ redraw = true;
+ }
+ else if (!(menu->flags & MF_TOPLEVEL))
+ {
+ if (key & K_CANCEL)
+ {
+ result = MENU_CANCEL;
+ break;
+ }
+
+ #if CONFIG_MENU_TIMEOUT != 0
+ if (now - menu_idle_time > ms_to_ticks(CONFIG_MENU_TIMEOUT))
+ {
+ result = MENU_TIMEOUT;
+ break;
+ }
+ #endif
+ }
+ }
+
+ /* Store currently selected item before leaving. */
+ if (menu->flags & MF_SAVESEL)
+ CONST_CAST(struct Menu *, menu)->selected = selected;
+
+ return result;
+}
+
+
+/**
+ * Set flags on a menuitem.
+ *
+ * \param menu Menu owner of the item to change.
+ * \param idx Index of the menu item.
+ * \param flags Bit mask of the flags to set.
+ *
+ * \return Old flags.
+ */
+int menu_setFlags(struct Menu *menu, int idx, int flags)
+{
+ ASSERT(idx < menu_count(menu));
+ ASSERT(!(menu->flags & MF_ROMITEMS));
+
+ int old = menu->items[idx].flags;
+ menu->items[idx].flags |= flags;
+ return old;
+}
+
+
+/**
+ * Clear flags on a menuitem.
+ *
+ * \param menu Menu owner of the item to change.
+ * \param idx Index of the menu item.
+ * \param flags Bit mask of the flags to clear.
+ *
+ * \return Old flags.
+ */
+int menu_clearFlags(struct Menu *menu, int idx, int flags)
+{
+ ASSERT(idx < menu_count(menu));
+ ASSERT(!(menu->flags & MF_ROMITEMS));
+
+ int old = menu->items[idx].flags;
+ menu->items[idx].flags &= ~flags;
+ return old;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
+ * All Rights Reserved.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Common menu handling API
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.5 2007/09/19 16:23:27 batt
+ *#* Fix doxygen warnings.
+ *#*
+ *#* Revision 1.4 2006/09/13 13:58:33 bernie
+ *#* Add RenderHook support.
+ *#*
+ *#* Revision 1.3 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.2 2006/06/03 13:58:02 bernie
+ *#* Fix recursive timeout and add exit status information.
+ *#*
+ *#* Revision 1.1 2006/05/15 07:20:54 bernie
+ *#* Move menu to gui/.
+ *#*
+ *#* Revision 1.4 2006/04/11 00:07:32 bernie
+ *#* Implemenent MF_SAVESEL flag.
+ *#*
+ *#* Revision 1.3 2006/03/22 09:49:51 bernie
+ *#* Simplifications from project_grl.
+ *#*
+ *#* Revision 1.2 2006/03/20 17:48:35 bernie
+ *#* Implement support for ROM menus.
+ *#*
+ *#* Revision 1.1 2006/02/10 12:29:36 bernie
+ *#* Add menu system.
+ *#*
+ *#* Revision 1.20 2005/11/16 18:10:19 bernie
+ *#* Move top-level headers to cfg/ as in DevLib.
+ *#*
+ *#* Revision 1.19 2005/02/11 19:11:38 aleph
+ *#* Move menu_displaymsg() in new displaymsg module
+ *#*
+ *#* Revision 1.18 2005/01/13 16:56:36 aleph
+ *#* Fix progmem includes.
+ *#*
+ *#* Revision 1.17 2004/12/14 12:52:45 aleph
+ *#* Add exclude menu flags
+ *#*
+ *#* Revision 1.16 2004/10/01 14:04:59 customer_pw
+ *#* Add accessor functions for menu flags
+ *#*
+ *#* Revision 1.15 2004/09/09 08:31:36 customer_pw
+ *#* Add disabled item type
+ *#*
+ *#* Revision 1.14 2004/08/29 21:46:12 bernie
+ *#* CVSSILENT: Mark CVS log blocks.
+ *#*
+ *#* Revision 1.13 2004/08/25 15:35:23 customer_pw
+ *#* IPTR -> iptr_t conversion.
+ *#*
+ *#* Revision 1.12 2004/08/25 13:23:45 bernie
+ *#* IPTR -> iptr_t conversion.
+ *#*/
+#ifndef MWARE_MENU_H
+#define MWARE_MENU_H
+
+#include <cfg/compiler.h>
+
+/* Fwd decl */
+struct Bitmap;
+
+/** Menu callback function */
+typedef iptr_t (*MenuHook)(iptr_t userdata);
+
+/**
+ * Menu item description.
+ */
+typedef struct MenuItem
+{
+ const_iptr_t label; /**< Item label (ID or ptr to string, 0 to disable) */
+ int flags; /**< See MIF_#? definitions below */
+ MenuHook hook; /**< Callback function (NULL to terminate item list) */
+ iptr_t userdata; /**< User data to be passed back to the hook */
+} MenuItem;
+
+/** Render hook callback function prototype */
+typedef void (*RenderHook)(struct Bitmap *bitmap, int ypos, bool selected, const struct MenuItem *item);
+
+/**
+ * \name Flags for MenuItem.flags.
+ * \{
+ */
+#define MIF_EXCLUDE_MASK 0x00FF /**< Mask for mutual exclusion map (shared with priority). */
+#define MIF_PRI_MASK 0x00FF /**< Mask for priority value (shared with mutual exclusion). */
+#define MIF_PRI(x) ((x) & MIF_PRI_MASK) /**< Set menu item priority. */
+#define MIF_EXCLUDE_0 BV(0) /**< Exclude item 0 when this item is checked */
+#define MIF_EXCLUDE_1 BV(1) /**< Exclude item 1 when this item is checked */
+#define MIF_EXCLUDE_2 BV(2) /**< Exclude item 2 when this item is checked */
+#define MIF_EXCLUDE_3 BV(3) /**< Exclude item 3 when this item is checked */
+#define MIF_EXCLUDE_4 BV(4) /**< Exclude item 4 when this item is checked */
+#define MIF_EXCLUDE_5 BV(5) /**< Exclude item 5 when this item is checked */
+#define MIF_EXCLUDE_6 BV(6) /**< Exclude item 6 when this item is checked */
+#define MIF_EXCLUDE_7 BV(7) /**< Exclude item 7 when this item is checked */
+#define MIF_CHECKED BV(8) /**< Item is currently checked */
+#define MIF_CHECKIT BV(9) /**< Automatically check this item when selected */
+#define MIF_TOGGLE BV(10) /**< Toggle MIF_CHECKED when item is selected */
+#define MIF_HIDDEN BV(11) /**< This menu item is not visible */
+#define MIF_DISABLED BV(12) /**< This menu item is not visible */
+#define MIF_RAMLABEL BV(13) /**< Item label is stored in RAM, not in program memory */
+#define MIF_RENDERHOOK BV(14) /**< Menu render function is passed in label field */
+/* \} */
+
+/**
+ * Menu description.
+ */
+typedef struct Menu
+{
+ MenuItem *items; /**< Array of items (end with a NULL hook) */
+ const_iptr_t title; /**< Menu title (ID or ptr to string, 0 to disable) */
+ int flags; /**< See MF_#? definitions below */
+ struct Bitmap *bitmap; /**< Bitmap where the menu is rendered */
+ int selected; /**< Initial selection (written to if MF_SAVESEL is set). */
+} Menu;
+
+/**
+ * \name Flags for Menu.flags.
+ * \{
+ */
+#define MF_STICKY BV(0) /**< Stay in the menu when the items called return */
+#define MF_TOPLEVEL BV(1) /**< Top-level menu (do not display "back" label) */
+#define MF_ROMITEMS BV(2) /**< Menu items are stored in ROM (default is RAM) */
+#define MF_SAVESEL BV(3) /**< Remember the selected item across invocations. */
+/* \} */
+
+/**
+ * \name Special result codes for menu_handle().
+ * \{
+ */
+#define MENU_OK ((iptr_t)0)
+#define MENU_CANCEL ((iptr_t)-1)
+#define MENU_TIMEOUT ((iptr_t)-2)
+#define MENU_ABORT ((iptr_t)-3)
+#define MENU_DISABLED ((iptr_t)-4)
+/* \} */
+
+/* Function prototypes */
+iptr_t menu_handle(const struct Menu *menu);
+int menu_setFlags(struct Menu *menu, int idx, int flags);
+int menu_clearFlags(struct Menu *menu, int idx, int flags);
+
+#endif /* MWARE_MENU_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Buzzer hardware-specific definitions
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2006/02/10 12:31:03 bernie
+ *#* Add templates for hw definitions.
+ *#*
+ *#*/
+
+#ifndef HW_BUZZER_H
+#define HW_BUZZER_H
+
+#define BUZZER_BIT BV(1)
+#define IS_BUZZER_ON 0
+#define BUZZER_HW_INIT do { } while (0)
+#define BUZZER_ON do { } while (0)
+#define BUZZER_OFF do { } while (0)
+
+#endif /* HW_BUZZER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Keyboard hardware-specific definitions
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Stefano Fedrigo <a@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.3 2006/03/22 09:51:27 bernie
+ *#* Wrap C++ stuff.
+ *#*
+ *#* Revision 1.2 2006/02/15 09:13:42 bernie
+ *#* Add keyboard emulator.
+ *#*
+ *#* Revision 1.1 2006/02/10 12:31:03 bernie
+ *#* Add templates for hw definitions.
+ *#*
+ *#*/
+
+#ifndef HW_KBD_H
+#define HW_KBD_H
+
+#include "kbd_map.h"
+#include <cfg/macros.h>
+
+#define K_RPT_MASK (K_UP | K_DOWN | K_OK | K_CANCEL)
+
+#define KBD_HW_INIT \
+ do { \
+ } while (0)
+
+EXTERN_C int emul_kbdReadCols(void);
+
+/**
+ * Read the keyboard ports and return the mask of
+ * depressed keys.
+ */
+INLINE keymask_t kbd_readkeys(void)
+{
+ return (keymask_t)emul_kbdReadCols();
+}
+
+#endif /* HW_KBD_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief LCD low-level hardware macros
+ */
+
+#ifndef HW_LCD_H
+#define HW_LCD_H
+
+#include <appconfig.h>
+//#include <hw.h>
+
+#include <cpu/attr.h>
+#include <cpu/irq.h>
+#include <cpu/types.h>
+
+#include <cfg/macros.h> /* BV() */
+#include <cfg/debug.h>
+
+#include <avr/io.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+/**
+ * \name LCD I/O pins/ports
+ * @{
+ */
+#define LCD_RS BV(PG3)
+#define LCD_RW BV(PG0)
+#define LCD_E BV(PG2)
+#define LCD_DB0 BV(PA0)
+#define LCD_DB1 BV(PA1)
+#define LCD_DB2 BV(PA2)
+#define LCD_DB3 BV(PA3)
+#define LCD_DB4 BV(PA4)
+#define LCD_DB5 BV(PA5)
+#define LCD_DB6 BV(PA6)
+#define LCD_DB7 BV(PA7)
+/*@}*/
+
+/**
+ * \name DB high nibble (DB[4-7])
+ * @{
+ */
+#define LCD_PORT PORTG
+#define LCD_DB_PORT PORTA
+#define LCD_PIN PING
+#define LCD_DB_PIN PINA
+#define LCD_DDR DDRG
+#define LCD_DB_DDR DDRA
+
+#if CONFIG_LCD_4BIT
+ #define LCD_MASK (LCD_DB7 | LCD_DB6 | LCD_DB5 | LCD_DB4)
+ #define LCD_SHIFT 4
+#else
+ #define LCD_MASK (uint8_t)0xff
+ #define LCD_SHIFT 0
+#endif
+/*@}*/
+
+/**
+ * \name LCD bus control macros
+ * @{
+ */
+#define LCD_CLR_RS (LCD_PORT &= ~LCD_RS)
+#define LCD_SET_RS (LCD_PORT |= LCD_RS)
+#define LCD_CLR_RD (LCD_PORT &= ~LCD_RW)
+#define LCD_SET_RD (LCD_PORT |= LCD_RW)
+#define LCD_CLR_E (LCD_PORT &= ~LCD_E)
+#define LCD_SET_E (LCD_PORT |= LCD_E)
+
+#if CONFIG_LCD_4BIT
+ #define LCD_WRITE_H(x) (LCD_DB_PORT = (LCD_DB_PORT & ~LCD_MASK) | (((x) >> (4 - LCD_SHIFT)) & LCD_MASK))
+ #define LCD_WRITE_L(x) (LCD_DB_PORT = (LCD_DB_PORT & ~LCD_MASK) | (((x) << LCD_SHIFT) & LCD_MASK))
+ #define LCD_READ_H ((LCD_DB_PIN & LCD_MASK) >> (4 - LCD_SHIFT))
+ #define LCD_READ_L ((LCD_DB_PIN & LCD_MASK) >> LCD_SHIFT)
+#else
+ #define LCD_WRITE(x) (LCD_DB_PORT = (x))
+ #define LCD_READ (LCD_DB_PIN)
+#endif
+/*@}*/
+
+/** Set data bus direction to output (write to display) */
+#define LCD_DB_OUT (LCD_DB_DDR |= LCD_MASK)
+
+/** Set data bus direction to input (read from display) */
+#define LCD_DB_IN (LCD_DB_DDR &= ~LCD_MASK)
+
+/** Delay for write (Enable pulse width, 220ns) */
+#define LCD_DELAY_WRITE \
+ do { \
+ NOP; \
+ NOP; \
+ NOP; \
+ NOP; \
+ NOP; \
+ } while (0)
+
+/** Delay for read (Data ouput delay time, 120ns) */
+#define LCD_DELAY_READ \
+ do { \
+ NOP; \
+ NOP; \
+ NOP; \
+ NOP; \
+ } while (0)
+
+
+INLINE void lcd_bus_init(void)
+{
+ cpuflags_t flags;
+ IRQ_SAVE_DISABLE(flags);
+
+ LCD_PORT = (LCD_PORT & ~(LCD_E | LCD_RW)) | LCD_RS;
+ LCD_DDR |= LCD_RS | LCD_RW | LCD_E;
+
+ /*
+ * Data bus is in output state most of the time:
+ * LCD r/w functions assume it is left in output state
+ */
+ LCD_DB_OUT;
+
+
+ IRQ_RESTORE(flags);
+}
+
+#endif /* HW_LCD_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief MCP41 hardware-specific definitions
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#include <hw_mcp41.h>
+
+#include <cfg/macros.h>
+#include <cfg/compiler.h>
+
+#include <avr/io.h>
+
+
+const uint16_t mcp41_ports[MCP41_CNT] = {
+ _SFR_IO_ADDR(PORTB), /** Led pot */
+ _SFR_IO_ADDR(PORTB), /** Photometer pot */
+ };
+const uint8_t mcp41_pins [MCP41_CNT] = {
+ BV(PB7),
+ BV(PB6),
+ };
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief MCP41 hardware-specific definitions
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef HW_MCP41_H
+#define HW_MCP41_H
+
+#include <mcp41_map.h>
+#include <cfg/compiler.h>
+#include <cpu/irq.h>
+#include <avr/io.h>
+
+extern const uint16_t mcp41_ports[MCP41_CNT];
+extern const uint8_t mcp41_pins[MCP41_CNT];
+
+/**
+ * Set MCP41 port associated with \a dev to output.
+ */
+INLINE void SET_MCP41_DDR(Mcp41Dev dev)
+{
+ /* DDR port is 1 address before PORT */
+ ATOMIC(_SFR_IO8(mcp41_ports[dev] - 1) |= mcp41_pins[dev]);
+}
+
+INLINE void MCP41_ON(Mcp41Dev i)
+{
+ ATOMIC(_SFR_IO8(mcp41_ports[i]) &= ~mcp41_pins[i]);
+}
+
+INLINE void MCP41_OFF(Mcp41Dev i)
+{
+ ATOMIC(_SFR_IO8(mcp41_ports[i]) |= mcp41_pins[i]);
+}
+
+
+#endif /* HW_MCP41_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief TC520 hardware-specific definitions
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef HW_TC520_H
+#define HW_TC520_H
+
+#include <cfg/compiler.h>
+#include <avr/io.h>
+
+#define CE_PIN PE6
+#define DV_PIN PE5
+#define LOAD_PIN PE3
+#define READ_PIN PE4
+
+#define TC520_DDR DDRE
+#define TC520_PORT PORTE
+#define TC520_PIN PINE
+
+#define DV_HIGH() (TC520_PIN & BV(DV_PIN))
+#define DV_LOW() (!DV_HIGH())
+
+#define CE_HIGH() (TC520_PORT |= BV(CE_PIN))
+#define CE_LOW() (TC520_PORT &= ~BV(CE_PIN))
+
+#define LOAD_HIGH() (TC520_PORT |= BV(LOAD_PIN))
+#define LOAD_LOW() (TC520_PORT &= ~BV(LOAD_PIN))
+
+#define READ_HIGH() (TC520_PORT |= BV(READ_PIN))
+#define READ_LOW() (TC520_PORT &= ~BV(READ_PIN))
+
+#define TC520_HW_INIT \
+do\
+{\
+ TC520_PORT |= (BV(CE_PIN) | BV(LOAD_PIN) | BV(READ_PIN));\
+ TC520_DDR |= (BV(CE_PIN) | BV(LOAD_PIN) | BV(READ_PIN));\
+ TC520_DDR &= ~BV(DV_PIN);\
+}\
+while(0)
+
+#endif /* HW_TC520_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Keyboard map definitions.
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Stefano Fedrigo <a@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2006/02/10 12:31:03 bernie
+ *#* Add templates for hw definitions.
+ *#*
+ *#*/
+
+#ifndef HW_KBD_MAP_H
+#define HW_KBD_MAP_H
+
+#include <cfg/macros.h>
+
+
+/**
+ * Type for keyboard mask.
+ */
+typedef uint16_t keymask_t;
+
+/**
+ * \name Keycodes.
+ */
+/*@{*/
+#define K_UP BV(0)
+#define K_DOWN BV(1)
+#define K_OK BV(2)
+#define K_CANCEL BV(3)
+
+#define K_REPEAT BV(14) /**< This is a repeated keyevent. */
+#define K_TIMEOUT BV(15) /**< Fake key event for timeouts. */
+/*@}*/
+
+
+#endif /* HW_KBD_MAP_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief MCP41 digital potentiometer map definitions.
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef MCP41_MAP_H
+#define MCP41_MAP_H
+
+/** \name Enum for mcp41 pot evices.
+ * \{
+ */
+typedef enum Mcp41Dev
+{
+ MCP41_LED,
+ MCP41_PHOTO_GAIN,
+
+ MCP41_CNT,
+} Mcp41Dev;
+/* \} */
+
+#endif /* MCP41_MAP_H */
--- /dev/null
+#
+# $Id: Makefile 18234 2007-10-08 13:39:48Z rasky $
+# Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+# All rights reserved.
+#
+# Author: Stefano Fedrigo <aleph@develer.com>
+#
+# $Log$
+# Revision 1.2 2006/09/20 14:18:01 marco
+# Use only icons neede by demo.
+#
+# Revision 1.1 2006/09/19 17:48:00 bernie
+# Add temporary logo.
+#
+#
+
+# Set to 1 for debug builds
+DEBUG = 1
+
+RASTERS = logo.raster
+
+FLIPIMAGE = flipimage
+flipimage_SRC = flipimage.cpp
+flipimage_OBJ = $(flipimage_SRC:%.cpp=%.o)
+
+.PHONY: all
+all: $(RASTERS)
+
+# Link rule
+$(FLIPIMAGE): $(flipimage_OBJ)
+ $(CXX) $^ $(flipimage_LIBS) $(LDFLAGS) -o $@
+
+.PHONY: clean
+clean:
+ rm -f $(TRG) $(flipimage_OBJ)
+ rm -f $(RASTERS)
+
+.PHONY: rasters
+rasters: $(FLIPIMAGE) $(RASTERS)
+
+%.raster: %.png $(FLIPIMAGE)
+ convert $< txt:- | ./flipimage >$@
+
+# Include dependencies
+-include *.d
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright (C) 2004 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \version $Id$
+ * \author Stefano Fedrigo <aleph@develer.com>
+ *
+ * \brief Conversion tool from image TXT format to LCD bitmap
+ */
+
+/*
+ * $Log$
+ * Revision 1.1 2006/09/19 17:48:00 bernie
+ * Add temporary logo.
+ *
+ * Revision 1.3 2004/09/24 17:25:32 powersoft
+ * Fix for new version of ImageMagick.
+ *
+ * Revision 1.2 2004/03/13 22:52:54 aleph
+ * documentation fixes
+ *
+ * Revision 1.1 2004/01/26 15:31:17 aleph
+ * Add boot images and tools for importing them
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#define RASTER_WIDTH 82
+#define RASTER_HEIGHT 64
+
+// Minimum color level to consider a pixel on
+#define COLOR_THRESHOLD 128
+
+
+using namespace std;
+
+
+int main(void)
+{
+ char buf[64];
+ int n;
+ unsigned char mask;
+ unsigned char line[RASTER_WIDTH];
+
+ for (int l = 0; l < RASTER_HEIGHT/8; l++)
+ {
+ mask = 1;
+ memset(line, 0, sizeof(line));
+
+ do
+ {
+ for (int x = 0; x < RASTER_WIDTH; x++)
+ {
+ if (!cin.getline(buf, sizeof(buf)))
+ goto print_line;
+
+ istringstream ss(buf);
+ string s;
+ char c;
+
+ ss
+ >> s // skip glob coord spec
+ >> c // skip open paren
+ >> n; // this is the red level
+
+ //DEBUG
+ //cout << "s='" << s << "' n='" << n << "'" << endl;
+
+ if (n < COLOR_THRESHOLD)
+ line[x] |= mask;
+ }
+ }
+ while (mask <<= 1);
+
+print_line:
+ cout << "\n\t";
+ for (int x = 0; x < RASTER_WIDTH; x++)
+ {
+ printf("0x%02X", line[x]);
+ if (x % 8 == 7)
+ cout << ",\n\t";
+ else
+ cout << ", ";
+ }
+ cout << endl;
+ }
+
+ return 0;
+}
--- /dev/null
+
+#include "logo.h"
+#include <cfg/compiler.h>
+#include <mware/pgm.h>
+
+/**
+ * BeRTOS logo
+ */
+const PROGMEM uint8_t bertos_logo_raster[] = {
+
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ 0x00, 0xF8, 0xF8, 0xF8, 0x78, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x78, 0x70, 0xF0, 0xF0, 0xE0, 0x80, 0x00,
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x70, 0x70, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x70, 0xF0, 0xE0, 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, 0x00,
+
+ 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xF1, 0x7F, 0x3F, 0x1F, 0x00,
+ 0x00, 0xFE, 0xFF, 0xFF, 0x3F, 0x18, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x3F,
+ 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x07, 0x1F, 0xFF, 0xFE, 0xFC,
+ 0x00, 0x00, 0x07, 0x1F, 0x9F, 0xBC, 0xB8, 0xB8,
+ 0x30, 0x30, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
+ 0x70, 0xB0, 0xB0, 0xB8, 0xB8, 0xBC, 0x9E, 0x1F,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
+ 0x80, 0x00,
+
+ 0x32, 0x3F, 0x3F, 0x3F, 0x3C, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x3C, 0x1C, 0x1F, 0x1F, 0x0F, 0x03,
+ 0x00, 0x00, 0x00, 0x3F, 0x0D, 0x04, 0x04, 0x0C,
+ 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x31,
+ 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24,
+ 0x24, 0x25,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+
+};
+
+EXTERN_CONST struct Image bertos_logo =
+{
+ /* .raster = */ bertos_logo_raster,
+ /* .width = */ 82,
+ /* .height = */ 64,
+ /* .stride = */ 82
+};
+
--- /dev/null
+#include <gfx/gfx.h>
+
+extern const struct Image bertos_logo;
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Virtual KFile I/O interface.
+ * This module implements some generic I/O interfaces for kfile.
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ *
+ */
+
+
+#include "kfile.h"
+#include <appconfig.h>
+
+#include <cfg/debug.h>
+#include <mware/formatwr.h>
+#include <string.h>
+
+/*
+ * Sanity check for config parameters required by this module.
+ */
+#if !defined(CONFIG_KFILE_GETS) || ((CONFIG_KFILE_GETS != 0) && CONFIG_KFILE_GETS != 1)
+ #error CONFIG_KFILE_GETS must be set to either 0 or 1 in appconfig.h
+#endif
+#if !defined(CONFIG_PRINTF)
+ #error CONFIG_PRINTF missing in appconfig.h
+#endif
+
+
+/**
+ * Generic putc() implementation using \a fd->write.
+ */
+int kfile_putc(int _c, struct KFile *fd)
+{
+ unsigned char c = (unsigned char)_c;
+
+ if (kfile_write(fd, &c, sizeof(c)) == sizeof(c))
+ return (int)((unsigned char)_c);
+ else
+ return EOF;
+}
+
+/**
+ * Generic getc() implementation using \a fd->read.
+ */
+int kfile_getc(struct KFile *fd)
+{
+ unsigned char c;
+
+ if (kfile_read(fd, &c, sizeof(c)) == sizeof(c))
+ return (int)((unsigned char)c);
+ else
+ return EOF;
+}
+
+#if CONFIG_PRINTF
+/**
+ * Formatted write.
+ */
+int kfile_printf(struct KFile *fd, const char *format, ...)
+{
+ va_list ap;
+ int len;
+
+ va_start(ap, format);
+ len = _formatted_write(format, (void (*)(char, void *))kfile_putc, fd, ap);
+ va_end(ap);
+
+ return len;
+}
+#endif /* CONFIG_PRINTF */
+
+/**
+ * Write a string to kfile \a fd.
+ * \return 0 if OK, EOF in case of error.
+ */
+int kfile_print(struct KFile *fd, const char *s)
+{
+ while (*s)
+ {
+ if (kfile_putc(*s++, fd) == EOF)
+ return EOF;
+ }
+ return 0;
+}
+
+#if CONFIG_KFILE_GETS
+/**
+ * Read a line long at most as size and put it
+ * in buf.
+ * \return number of chars read or EOF in case
+ * of error.
+ */
+int kfile_gets(struct KFile *fd, char *buf, int size)
+{
+ return kfile_gets_echo(fd, buf, size, false);
+}
+
+
+/**
+ * Read a line long at most as size and put it
+ * in buf, with optional echo.
+ *
+ * \return number of chars read, or EOF in case
+ * of error.
+ */
+int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo)
+{
+ int i = 0;
+ int c;
+
+ for (;;)
+ {
+ if ((c = kfile_getc(fd)) == EOF)
+ {
+ buf[i] = '\0';
+ return -1;
+ }
+
+ /* FIXME */
+ if (c == '\r' || c == '\n' || i >= size-1)
+ {
+ buf[i] = '\0';
+ if (echo)
+ kfile_print(fd, "\r\n");
+ break;
+ }
+ buf[i++] = c;
+ if (echo)
+ kfile_putc(c, fd);
+ }
+
+ return i;
+}
+#endif /* !CONFIG_KFILE_GETS */
+
+
+/**
+ * Move \a fd file seek position of \a offset bytes from \a whence.
+ *
+ * This is a generic implementation of seek function, you can redefine
+ * it in your local module if needed.
+ */
+kfile_off_t kfile_genericSeek(struct KFile *fd, kfile_off_t offset, KSeekMode whence)
+{
+ uint32_t seek_pos;
+
+ switch (whence)
+ {
+
+ case KSM_SEEK_SET:
+ seek_pos = 0;
+ break;
+ case KSM_SEEK_END:
+ seek_pos = fd->size;
+ break;
+ case KSM_SEEK_CUR:
+ seek_pos = fd->seek_pos;
+ break;
+ default:
+ ASSERT(0);
+ return EOF;
+ break;
+ }
+
+ /* Bound check */
+ if (seek_pos + offset > fd->size)
+ {
+ ASSERT(0);
+ return EOF;
+ }
+
+ fd->seek_pos = seek_pos + offset;
+
+ return fd->seek_pos;
+}
+
+/**
+ * Reopen file \a fd.
+ * This is a generic implementation that only flush file
+ * and reset seek_pos to 0.
+ */
+struct KFile * kfile_genericReopen(struct KFile *fd)
+{
+ kfile_flush(fd);
+ kfile_seek(fd, 0, KSM_SEEK_SET);
+ return fd;
+}
+
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Virtual KFile I/O interface.
+ * KFile is a generic interface for file I/O.
+ * It uses an object-oriented model to supply
+ * a generic interface for drivers to communicate.
+ * This module contains only definitions, the instance structure
+ * and an API.
+ * Each KFile user should implement at least some methods.
+ * E.G.
+ * If you have a serial driver and want to comply to KFile interface,
+ * you have to declare your context structure:
+ *
+ * \code
+ * typedef struct KFileSerial
+ * {
+ * KFile fd;
+ * Serial *ser;
+ * } KFileSerial;
+ * \endcode
+ *
+ * You should also supply a macro for casting KFile to KFileSerial:
+ *
+ * \code
+ * INLINE KFileSerial * KFILESERIAL(KFile *fd)
+ * {
+ * ASSERT(fd->_type == KFT_SERIAL);
+ * return (KFileSerial *)fd;
+ * }
+ * \endcode
+ *
+ * Then you can implement as much interface functions as you like
+ * and leave the others to NULL.
+ * ser_close implementation example:
+ *
+ * \code
+ * static int ser_kfile_close(struct KFile *fd)
+ * {
+ * KFileSerial *fds = KFILESERIAL(fd);
+ * ser_close(fds->ser);
+ * return 0;
+ * }
+ * \endcode
+ * KFILESERIAL macro helps to ensure that obj passed is really a Serial.
+ *
+ * KFile interface do not supply the open function: this is deliberate,
+ * because in embedded systems each device has its own init parameters.
+ * For the same reason specific file settings (like baudrate for Serial, for example)
+ * are demanded to specific driver implementation.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ */
+
+#ifndef KERN_KFILE_H
+#define KERN_KFILE_H
+
+#include <cfg/compiler.h>
+#include <cfg/debug.h>
+#include <cfg/macros.h>
+
+/* fwd decl */
+struct KFile;
+
+typedef int32_t kfile_off_t; ///< KFile offset type, used by kfile_seek function.
+
+/**
+ * Costants for repositioning read/write file offset.
+ * These are needed because on some embedded platforms
+ * ANSI I/O library may not be present.
+ */
+typedef enum KSeekMode
+{
+ KSM_SEEK_SET, ///< Seek from file beginning.
+ KSM_SEEK_CUR, ///< Seek from file current position.
+ KSM_SEEK_END, ///< Seek from file end.
+} KSeekMode;
+
+/**
+ * Prototypes for KFile access functions.
+ * I/O file functions must be ANSI compliant.
+ * \note A KFile user can choose which function subset to implement,
+ * but has to set to NULL unimplemented features.
+ * \{
+ */
+
+/**
+ * Read from file.
+ * \return the number of bytes read.
+ */
+typedef size_t (*ReadFunc_t) (struct KFile *fd, void *buf, size_t size);
+
+/**
+ * Write to file.
+ * \return the number of bytes written.
+ */
+typedef size_t (*WriteFunc_t) (struct KFile *fd, const void *buf, size_t size);
+
+/**
+ * Seek into file (if seekable).
+ * \return the new file offset or EOF on errors.
+ */
+typedef kfile_off_t (*SeekFunc_t) (struct KFile *fd, kfile_off_t offset, KSeekMode whence);
+
+/**
+ * Close and reopen file \a fd.
+ * The reopening is done with the former file parameters and access modes.
+ */
+typedef struct KFile * (*ReOpenFunc_t) (struct KFile *fd);
+
+/**
+ * Close file.
+ * \return 0 on success, EOF on errors.
+ */
+typedef int (*CloseFunc_t) (struct KFile *fd);
+
+/**
+ * Flush file I/O.
+ * \return 0 on success, EOF on errors.
+ */
+typedef int (*FlushFunc_t) (struct KFile *fd);
+
+/**
+ * Get file error mask.
+ * \return 0 on success or file error code, device specific.
+ */
+typedef int (*ErrorFunc_t) (struct KFile *fd);
+
+/**
+ * Clear errors.
+ */
+typedef void (*ClearErrFunc_t) (struct KFile *fd);
+/* \} */
+
+/**
+ * Context data for callback functions which operate on
+ * pseudo files.
+ * \note If you change interface, remember to add corresponding access function.
+ */
+typedef struct KFile
+{
+ ReadFunc_t read;
+ WriteFunc_t write;
+ ReOpenFunc_t reopen;
+ CloseFunc_t close;
+ SeekFunc_t seek;
+ FlushFunc_t flush;
+ ErrorFunc_t error;
+ ClearErrFunc_t clearerr;
+ DB(id_t _type); ///< Used to keep trace, at runtime, of obj type.
+
+ /* NOTE: these must _NOT_ be size_t on 16bit CPUs! */
+ uint32_t seek_pos;
+ uint32_t size;
+} KFile;
+
+/**
+ * Generic implementation of kfile_seek.
+ */
+kfile_off_t kfile_genericSeek(struct KFile *fd, kfile_off_t offset, KSeekMode whence);
+
+/**
+ * Generic implementation of kfile_reopen.
+ */
+struct KFile * kfile_genericReopen(struct KFile *fd);
+
+int kfile_putc(int c, struct KFile *fd); ///< Generic putc implementation using kfile_write.
+int kfile_getc(struct KFile *fd); ///< Generic getc implementation using kfile_read.
+int kfile_printf(struct KFile *fd, const char *format, ...);
+int kfile_print(struct KFile *fd, const char *s);
+int kfile_gets(struct KFile *fd, char *buf, int size);
+int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo);
+
+/**
+ * Interface functions for KFile access.
+ * \note Remember to change following functions if KFile interface changes.
+ * \{
+ */
+INLINE size_t kfile_read(struct KFile *fd, void *buf, size_t size)
+{
+ ASSERT(fd->read);
+ return fd->read(fd, buf, size);
+}
+
+INLINE size_t kfile_write(struct KFile *fd, const void *buf, size_t size)
+{
+ ASSERT(fd->write);
+ return fd->write(fd, buf, size);
+}
+
+INLINE KFile * kfile_reopen(struct KFile *fd)
+{
+ ASSERT(fd->reopen);
+ return fd->reopen(fd);
+}
+
+INLINE int kfile_close(struct KFile *fd)
+{
+ ASSERT(fd->close);
+ return fd->close(fd);
+}
+
+INLINE kfile_off_t kfile_seek(struct KFile *fd, kfile_off_t offset, KSeekMode whence)
+{
+ ASSERT(fd->seek);
+ return fd->seek(fd, offset, whence);
+}
+
+INLINE int kfile_flush(struct KFile *fd)
+{
+ ASSERT(fd->flush);
+ return fd->flush(fd);
+}
+
+INLINE int kfile_error(struct KFile *fd)
+{
+ ASSERT(fd->error);
+ return fd->error(fd);
+}
+
+INLINE void kfile_clearerr(struct KFile *fd)
+{
+ ASSERT(fd->clearerr);
+ fd->clearerr(fd);
+}
+/* \} */
+
+/**
+ * Kfile test function.
+ */
+bool kfile_test(KFile *fd, uint8_t *test_buf, uint8_t *save_buf, size_t size);
+
+#endif /* KERN_KFILE_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Test suite for virtual KFile I/O interface.
+ * This module implements a test for some generic I/O interfaces for kfile.
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
+ *
+ */
+
+
+#include "kfile.h"
+#include <appconfig.h>
+
+#include <cfg/debug.h>
+#include <mware/formatwr.h>
+#include <string.h>
+
+/**
+ * KFile read/write subtest.
+ * Try to write/read in the same \a f file location \a size bytes.
+ * \return true if all is ok, false otherwise
+ * \note Restore file position at exit (if no error)
+ * \note Test buffer \a buf must be filled with
+ * the following statement:
+ * <pre>
+ * buf[i] = i & 0xff
+ * </pre>
+ */
+static bool kfile_rwTest(KFile *f, uint8_t *buf, size_t size)
+{
+ /*
+ * Write test buffer
+ */
+ if (kfile_write(f, buf, size) != size)
+ return false;
+
+ kfile_seek(f, -(kfile_off_t)size, KSM_SEEK_CUR);
+
+ /*
+ * Reset test buffer
+ */
+ memset(buf, 0, size);
+
+ /*
+ * Read file in test buffer
+ */
+ if (kfile_read(f, buf, size) != size)
+ return false;
+ kfile_seek(f, -(kfile_off_t)size, KSM_SEEK_CUR);
+
+ /*
+ * Check test result
+ */
+ for (size_t i = 0; i < size; i++)
+ if (buf[i] != (i & 0xff))
+ return false;
+
+ return true;
+}
+
+/**
+ * KFile read/write test.
+ * This function write and read \a test_buf long \a size
+ * on \a fd handler.
+ * \a save_buf can be NULL or a buffer where to save previous file content.
+ */
+bool kfile_test(KFile *fd, uint8_t *test_buf, uint8_t *save_buf, size_t size)
+{
+ /*
+ * Part of test buf size that you would write.
+ * This var is used in test 3 to check kfile_write
+ * when writing beyond filesize limit.
+ */
+ kfile_off_t len = size / 2;
+
+
+ /* Fill test buffer */
+ for (size_t i = 0; i < size; i++)
+ test_buf[i] = (i & 0xff);
+
+ /*
+ * If necessary, user can save content,
+ * for later restore.
+ */
+ if (save_buf)
+ {
+ kfile_read(fd, save_buf, size);
+ kprintf("Saved content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
+ }
+
+ /* TEST 1 BEGIN. */
+ kprintf("Test 1: write from pos 0 to [%lu]\n", size);
+
+ /*
+ * Seek to addr 0.
+ */
+ if (kfile_seek(fd, 0, KSM_SEEK_SET) != 0)
+ goto kfile_test_end;
+
+ /*
+ * Test read/write to address 0..size
+ */
+ if (!kfile_rwTest(fd, test_buf, size))
+ goto kfile_test_end;
+
+ kprintf("Test 1: ok!\n");
+
+ /*
+ * Restore previous read content.
+ */
+ if (save_buf)
+ {
+ kfile_seek(fd, 0, KSM_SEEK_SET);
+
+ if (kfile_write(fd, save_buf, size) != size)
+ goto kfile_test_end;
+
+ kprintf("Restore content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
+ }
+ /* TEST 1 END. */
+
+ /* TEST 2 BEGIN. */
+ kprintf("Test 2: write from pos [%lu] to [%lu]\n", fd->size/2 , fd->size/2 + size);
+
+ /*
+ * Go to half test size.
+ */
+ kfile_seek(fd, (fd->size / 2), KSM_SEEK_SET);
+
+ /*
+ * If necessary, user can save content
+ * for later restore.
+ */
+ if (save_buf)
+ {
+ kfile_read(fd, save_buf, size);
+ kfile_seek(fd, -(kfile_off_t)size, KSM_SEEK_CUR);
+ kprintf("Saved content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
+ }
+
+ /*
+ * Test read/write to address filesize/2 ... filesize/2 + size
+ */
+ if (!kfile_rwTest(fd, test_buf, size))
+ goto kfile_test_end;
+
+ kprintf("Test 2: ok!\n");
+
+ /*
+ * Restore previous content.
+ */
+ if (save_buf)
+ {
+ kfile_seek(fd, -(kfile_off_t)size, KSM_SEEK_CUR);
+
+ if (kfile_write(fd, save_buf, size) != size)
+ goto kfile_test_end;
+
+ kprintf("Restore content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
+ }
+
+ /* TEST 2 END. */
+
+ /* TEST 3 BEGIN. */
+ kprintf("Test 3: write outside of fd->size limit [%lu]\n", fd->size);
+ kprintf("This test should FAIL!, you must see an assertion fail message.\n");
+
+ /*
+ * Go to the Flash end
+ */
+ kfile_seek(fd, -len, KSM_SEEK_END);
+
+ /*
+ * If necessary, user can save content,
+ * for later restore.
+ */
+ if (save_buf)
+ {
+ kfile_read(fd, save_buf, len);
+ kfile_seek(fd, -len, KSM_SEEK_CUR);
+ kprintf("Saved content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + len);
+ }
+
+ /*
+ * Test read/write to address (filesize - size) ... filesize
+ */
+ if (kfile_rwTest(fd, test_buf, size))
+ goto kfile_test_end;
+
+ kprintf("Test 3: ok!\n");
+
+ /*
+ * Restore previous read content
+ */
+ if (save_buf)
+ {
+ kfile_seek(fd, -len, KSM_SEEK_END);
+
+ if (kfile_write(fd, save_buf, len) != len)
+ goto kfile_test_end;
+
+ kprintf("Restore content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + len);
+ }
+
+ /* TEST 3 END. */
+
+ kfile_close(fd);
+ return true;
+
+kfile_test_end:
+ kfile_close(fd);
+ return false;
+}
+
+
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Monitor to check for stack overflows
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+
+#include "monitor.h"
+
+#if CONFIG_KERN_MONITOR
+
+#include "proc_p.h"
+#include <mware/list.h>
+#include <drv/timer.h>
+#include <kern/proc.h>
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+
+static List MonitorProcs;
+
+
+void monitor_init(void)
+{
+ LIST_INIT(&MonitorProcs);
+}
+
+
+void monitor_add(Process* proc, const char* name, cpustack_t* stack_base, size_t stack_size)
+{
+ proc->monitor.name = name;
+ proc->monitor.stack_base = stack_base;
+ proc->monitor.stack_size = stack_size;
+
+ ADDTAIL(&MonitorProcs, &proc->monitor.link);
+}
+
+
+void monitor_remove(Process* proc)
+{
+ REMOVE(&proc->monitor.link);
+}
+
+void monitor_rename(Process *proc, const char* name)
+{
+ proc->monitor.name = name;
+}
+
+/* TODO: use containerof() */
+#define MONITOR_NODE_TO_PROCESS(node) \
+ (struct Process *)((intptr_t)(node) - offsetof(struct Process, monitor.link))
+
+size_t monitor_checkStack(cpustack_t* stack_base, size_t stack_size)
+{
+ cpustack_t* beg;
+ cpustack_t* cur;
+ cpustack_t* end;
+ size_t sp_free;
+
+ beg = stack_base;
+ end = stack_base + stack_size / sizeof(cpustack_t) - 1;
+
+ if (CPU_STACK_GROWS_UPWARD)
+ {
+ cur = beg;
+ beg = end;
+ end = cur;
+ }
+
+ cur = beg;
+ while (cur != end)
+ {
+ if (*cur != CONFIG_KERN_STACKFILLCODE)
+ break;
+
+ if (CPU_STACK_GROWS_UPWARD)
+ cur--;
+ else
+ cur++;
+ }
+
+ sp_free = ABS(cur - beg) * sizeof(cpustack_t);
+ return sp_free;
+}
+
+
+void monitor_report(void)
+{
+ struct Process* p;
+ int i;
+
+ if (LIST_EMPTY(&MonitorProcs))
+ {
+ kputs("No stacks registered in the monitor\n");
+ return;
+ }
+
+ kprintf("%-24s%-8s%-8s%-8s%-8s\n", "Process name", "TCB", "SPbase", "SPsize", "SPfree");
+ for (i=0;i<56;i++)
+ kputchar('-');
+ kputchar('\n');
+
+ for (p = MONITOR_NODE_TO_PROCESS(LIST_HEAD(&MonitorProcs));
+ p->monitor.link.succ;
+ p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
+ {
+ size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
+ kprintf("%-24s%-8p%-8p%-8lu%-8lu\n",
+ p->monitor.name, p, p->monitor.stack_base, p->monitor.stack_size, free);
+ }
+}
+
+
+static void NORETURN monitor(void)
+{
+ struct Process *p;
+
+ while (1)
+ {
+ for (p = MONITOR_NODE_TO_PROCESS(LIST_HEAD(&MonitorProcs));
+ p->monitor.link.succ;
+ p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
+ {
+ size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
+
+ if (free < 0x20)
+ kprintf("MONITOR: WARNING: Free stack for process '%s' is only %u chars\n",
+ p->monitor.name, (unsigned int)free);
+
+ timer_delay(500);
+ }
+ }
+}
+
+
+void monitor_start(size_t stacksize, cpustack_t *stack)
+{
+ proc_new(monitor, NULL, stacksize, stack);
+}
+
+#endif /* CONFIG_KERN_MONITOR */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Monitor to check for stack overflows
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+#ifndef KERN_MONITOR_H
+#define KERN_MONITOR_H
+
+#include <cpu/types.h>
+#include <config_kern.h>
+
+#if CONFIG_KERN_MONITOR
+
+/**
+ * Start the kernel monitor. It is a special process which checks every second the stacks of the
+ * running processes trying to detect stack overflows.
+ *
+ * \param stacksize Size of stack in chars
+ * \param stack Pointer to the stack that will be used by the monitor
+ *
+ * \note The stack is provided by the caller so that there is no wasted space if the monitor
+ * is not used.
+ */
+void monitor_start(size_t stacksize, cpustack_t *stack);
+
+
+/**
+ * Manually check if a given stack has overflown. This is used to check for stacks
+ * of processes handled externally form the kernel, or for other stacks (for instance
+ * the interrupt supervisor stack).
+ *
+ * \note For this function to work, the stack must have been filled at startup with
+ * CONFIG_KERN_STACKFILLCODE.
+ */
+size_t monitor_checkStack(cpustack_t *stack_base, size_t stack_size);
+
+
+/** Print a report of the stack status through kdebug */
+void monitor_report(void);
+
+
+#endif /* CONFIG_KERN_MONITOR */
+#endif /* KERN_MONITOR_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ *
+ * This module implements a common system for executing
+ * a user defined action calling a hook function.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Simple inter-process messaging system
+ *
+ * Handle queues of messages associated an action.
+ *
+ * A message port is an abstraction used to exchange information
+ * asynchronously between processes or other entities such as
+ * interrupts and call-back functions.
+ *
+ * This form of IPC is higher-level than bare signals and
+ * semaphores, because it sets a policy for exchanging
+ * structured data with well-defined synchronization and
+ * ownership semantics.
+ *
+ * Before using it, a message port must be initialized by
+ * calling msg_initPort(), which associates the port with
+ * an Event object, which can be setup to signal a process
+ * or invoke a call-back hook.
+ *
+ * A process or interrupt routine can deliver messages to any
+ * message port by calling msg_put(). By sending a message,
+ * the sender temporarly or permanently transfers ownership
+ * of its associated data to the receiver.
+ *
+ * Queuing a message to a port automatically triggers the
+ * associated Event to notify the receiver. When the
+ * receiver wakes up, it usually invokes msg_get() to pick
+ * the next message from the port.
+ *
+ * Message ports can hold any number of pending messages,
+ * and receivers usually process them in FIFO order.
+ * Other scheduling policies are possible, but not implemented
+ * in this API.
+ *
+ * After the receiver has done processing a message, it replies
+ * it back to the sender with msg_reply(), which transfer
+ * ownership back to the original sender. Replies are delivered
+ * to a reply port, which is nothing more than another MsgPort
+ * structure designated by the sender.
+ *
+ * Returning messages to senders is not mandatory, but it provides
+ * a convenient way to provide some kind of result and simplify
+ * the resource allocation scheme at the same time.
+ *
+ * When using signals to receive messages in a process, you
+ * call sig_wait() in an event-loop to wake up when messages
+ * are delivered to any of your ports. When your process
+ * wakes up with the port signal active, multiple messages
+ * may already have queued up at the message port, and the
+ * process must process them all before returning to sleep.
+ * Signals don't keep a nesting count.
+ *
+ * A simple message loop works like this:
+ *
+ * \code
+ * // Our message port.
+ * static MsgPort test_port;
+ *
+ * // A test message with two parameters and a result.
+ * typedef struct
+ * {
+ * Msg msg;
+ *
+ * int x, y;
+ * int result;
+ * } TestMsg;
+ *
+ *
+ * // A process that sends two messages and waits for replies.
+ * static void sender_proc(void)
+ * {
+ * MsgPort test_reply_port;
+ * TestMsg msg1;
+ * TestMsg msg2;
+ * Msg *reply;
+ *
+ * msg_initPort(&reply_port,
+ * event_createSignal(proc_current(), SIGF_SINGLE);
+ *
+ * // Fill-in first message and send it out.
+ * msg1.x = 3;
+ * msg1.y = 2;
+ * msg1.msg.replyPort = &test_reply_port;
+ * msg_put(&test_port, &msg1);
+ *
+ * // Fill-in second message and send it out too.
+ * msg2.x = 5;
+ * msg2.y = 4;
+ * msg2.msg.replyPort = &test_reply_port;
+ * msg_put(&test_port, &msg1);
+ *
+ * // Wait for a reply...
+ * sig_wait(SIG_SINGLE);
+ *
+ * reply = (TestMsg *)msg_get(&test_reply_port);
+ * ASSERT(reply != NULL);
+ * ASSERT(reply->result == 5);
+ *
+ * // Get reply to second message.
+ * while (!(reply = (TestMsg *)msg_get(&test_reply_port))
+ * {
+ * // Not yet, be patient and wait some more.
+ * sig_wait(SIG_SINGLE);
+ * }
+ *
+ * ASSERT(reply->result == 9);
+ * }
+ *
+ *
+ * // Receive messages and do something boring with them.
+ * static void receiver_proc(void)
+ * {
+ * msg_initPort(&test_port,
+ * event_createSignal(proc_current(), SIGF_EXAMPLE);
+ *
+ * proc_new(sender_proc, (iptr_t)&test_port,
+ * sender_stack, sizeof(sender_stack);
+ *
+ * for (;;)
+ * {
+ * sigmask_t sigs = sig_wait(SIGF_EXAMPLE | more_signals);
+ *
+ * if (sigs & SIGF_EXAMPLE)
+ * {
+ * TestMsg *emsg;
+ * while (emsg = (TestMsg *)msg_get(&test_port)
+ * {
+ * // Do something with the message
+ * emsg->result = emsg->x + emsg->y;
+ * msg_reply((Msg *)msg);
+ * }
+ * }
+ * }
+ * }
+ * \endcode
+ */
+
+ */
+
+#ifndef KERN_MSG_H
+#define KERN_MSG_H
+
+#include "event.h"
+#include <mware/list.h>
+
+
+typedef struct MsgPort
+{
+ List queue; /**< Messages queued at this port. */
+ Event event; /**< Event to trigger when a message arrives. */
+} MsgPort;
+
+
+typedef struct Msg
+{
+ Node link; /**< Link into message port queue. */
+ MsgPort *replyPort; /**< Port to which the msg is to be replied. */
+ /* User data may follow */
+} Msg;
+
+
+/**
+ * Lock a message port.
+ *
+ * This is required before reading or manipulating
+ * any field of the MsgPort structure.
+ *
+ * \note Ports may be locked multiple times and each
+ * call to msg_lockPort() must be paired with
+ * a corresponding call to msg_unlockPort().
+ *
+ * \todo Add a configurable policy for locking against
+ * interrupts and locking with semaphorse.
+ *
+ * \see msg_unlockPort()
+ */
+INLINE void msg_lockPort(MsgPort *port)
+{
+ proc_forbid();
+}
+
+/**
+ * Unlock a message port.
+ *
+ * \see msg_lockPort()
+ */
+INLINE void msg_unlockPort(MsgPort *port)
+{
+ proc_permit();
+}
+
+
+/** Initialize a message port */
+INLINE void msg_initPort(MsgPort *port, Event event)
+{
+ LIST_INIT(&port->queue);
+ port->event = event;
+}
+
+/** Queue \a msg into \a port, triggering the associated event */
+INLINE void msg_put(MsgPort *port, Msg *msg)
+{
+ msg_portLock(port);
+ ADDTAIL(&port->queue, &msg->link);
+ msg_portUnlock(port);
+
+ event_do(&port->event);
+}
+
+/**
+ * Get the first message from the queue of \a port.
+ *
+ * \return Pointer to the message or NULL if the port was empty.
+ */
+INLINE Msg *msg_get(MsgPort *port)
+{
+ Msg *msg;
+
+ msg_portLock(port);
+ msg = (Msg *)REMHEAD(&port->queue);
+ msg_portUnlock(port);
+
+ return msg;
+}
+
+/** Peek the first message in the queue of \a port, or NULL if the port is empty. */
+INLINE Msg *msg_peek(MsgPort *port)
+{
+ Msg *msg;
+
+ msg_portLock(port);
+ msg = (Msg *)port->queue.head;
+ if (ISLISTEMPTY(&port->queue))
+ msg = NULL;
+ msg_portUnlock(port);
+
+ return msg;
+}
+
+/** Send back (reply) \a msg to its sender. */
+INLINE void msg_reply(Msg *msg)
+{
+ msg_put(msg->replyPort, msg);
+}
+
+#endif /* KERN_MSG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Simple realtime multitasking scheduler.
+ * Context switching is only done cooperatively.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+
+#include "proc_p.h"
+#include "proc.h"
+//#include "hw.h"
+#include <mware/event.h>
+#include <cpu/irq.h>
+#include <cpu/types.h>
+#include <cpu/attr.h>
+#include <cfg/debug.h>
+#include <cfg/module.h>
+#include <cfg/arch_config.h> /* ARCH_EMUL */
+#include <cfg/macros.h> /* ABS() */
+
+#include <string.h> /* memset() */
+
+/**
+ * CPU dependent context switching routines.
+ *
+ * \note This function *MUST* preserve also the status of the interrupts.
+ */
+EXTERN_C void asm_switch_context(cpustack_t **new_sp, cpustack_t **save_sp);
+EXTERN_C int asm_switch_version(void);
+
+/*
+ * The scheduer tracks ready and waiting processes
+ * by enqueuing them in these lists. A pointer to the currently
+ * running process is stored in the CurrentProcess pointer.
+ *
+ * NOTE: these variables are protected by DI/EI locking
+ */
+REGISTER Process *CurrentProcess;
+REGISTER List ProcReadyList;
+
+
+#if CONFIG_KERN_PREEMPTIVE
+/*
+ * The time sharing scheduler forces a task switch when
+ * the current process has consumed its quantum.
+ */
+uint16_t Quantum;
+#endif
+
+
+/* In Win32 we must emulate stack on the real process stack */
+#if (ARCH & ARCH_EMUL)
+extern List StackFreeList;
+#endif
+
+/** The main process (the one that executes main()). */
+struct Process MainProcess;
+
+
+static void proc_init_struct(Process *proc)
+{
+ /* Avoid warning for unused argument. */
+ (void)proc;
+
+#if CONFIG_KERN_SIGNALS
+ proc->sig_recv = 0;
+#endif
+
+#if CONFIG_KERN_PREEMPTIVE
+ proc->forbid_cnt = 0;
+#endif
+
+#if CONFIG_KERN_HEAP
+ proc->flags = 0;
+#endif
+}
+
+MOD_DEFINE(proc);
+
+void proc_init(void)
+{
+ LIST_INIT(&ProcReadyList);
+
+#if CONFIG_KERN_MONITOR
+ monitor_init();
+#endif
+
+ /* We "promote" the current context into a real process. The only thing we have
+ * to do is create a PCB and make it current. We don't need to setup the stack
+ * pointer because it will be written the first time we switch to another process.
+ */
+ proc_init_struct(&MainProcess);
+ CurrentProcess = &MainProcess;
+
+ /* Make sure the assembly routine is up-to-date with us */
+ ASSERT(asm_switch_version() == 1);
+ MOD_INIT(proc);
+}
+
+
+/**
+ * Create a new process, starting at the provided entry point.
+ *
+ * \return Process structure of new created process
+ * if successful, NULL otherwise.
+ */
+struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(void), iptr_t data, size_t stacksize, cpustack_t *stack_base)
+{
+ Process *proc;
+ size_t i;
+ size_t proc_size_words = ROUND2(sizeof(Process), sizeof(cpustack_t)) / sizeof(cpustack_t);
+#if CONFIG_KERN_HEAP
+ bool free_stack = false;
+#endif
+
+#if (ARCH & ARCH_EMUL)
+ /* Ignore stack provided by caller and use the large enough default instead. */
+ stack_base = (cpustack_t *)LIST_HEAD(&StackFreeList);
+ REMOVE(LIST_HEAD(&StackFreeList));
+ stacksize = CONFIG_PROC_DEFSTACKSIZE;
+#elif CONFIG_KERN_HEAP
+ /* Did the caller provide a stack for us? */
+ if (!stack_base)
+ {
+ /* Did the caller specify the desired stack size? */
+ if (!stacksize)
+ stacksize = CONFIG_PROC_DEFSTACKSIZE + sizeof(Process);
+
+ /* Allocate stack dinamically */
+ if (!(stack_base = heap_alloc(stacksize)))
+ return NULL;
+
+ free_stack = true;
+ }
+#else
+ /* Stack must have been provided by the user */
+ ASSERT(stack_base);
+ ASSERT(stacksize);
+#endif
+
+#if CONFIG_KERN_MONITOR
+ /* Fill-in the stack with a special marker to help debugging */
+ memset(stack_base, CONFIG_KERN_STACKFILLCODE, stacksize / sizeof(cpustack_t));
+#endif
+
+ /* Initialize the process control block */
+ if (CPU_STACK_GROWS_UPWARD)
+ {
+ proc = (Process*)stack_base;
+ proc->stack = stack_base + proc_size_words;
+ if (CPU_SP_ON_EMPTY_SLOT)
+ proc->stack++;
+ }
+ else
+ {
+ proc = (Process*)(stack_base + stacksize / sizeof(cpustack_t) - proc_size_words);
+ proc->stack = (cpustack_t*)proc;
+ if (CPU_SP_ON_EMPTY_SLOT)
+ proc->stack--;
+ }
+
+ proc_init_struct(proc);
+ proc->user_data = data;
+
+#if CONFIG_KERN_HEAP
+ proc->stack_base = stack_base;
+ proc->stack_size = stack_size;
+ if (free_stack)
+ proc->flags |= PF_FREESTACK;
+#endif
+
+ /* Initialize process stack frame */
+ CPU_PUSH_CALL_CONTEXT(proc->stack, proc_exit);
+ CPU_PUSH_CALL_CONTEXT(proc->stack, entry);
+
+ /* Push a clean set of CPU registers for asm_switch_context() */
+ for (i = 0; i < CPU_SAVED_REGS_CNT; i++)
+ CPU_PUSH_WORD(proc->stack, CPU_REG_INIT_VALUE(i));
+
+ /* Add to ready list */
+ ATOMIC(SCHED_ENQUEUE(proc));
+
+#if CONFIG_KERN_MONITOR
+ monitor_add(proc, name, stack_base, stacksize);
+#endif
+
+ return proc;
+}
+
+/** Rename a process */
+void proc_rename(struct Process *proc, const char *name)
+{
+#if CONFIG_KERN_MONITOR
+ monitor_rename(proc, name);
+#else
+ (void)proc; (void)name;
+#endif
+}
+
+
+/**
+ * System scheduler: pass CPU control to the next process in
+ * the ready queue.
+ *
+ * Saving and restoring the context on the stack is done
+ * by a CPU-dependent support routine which must usually be
+ * written in assembly.
+ */
+void proc_schedule(void)
+{
+ struct Process *old_process;
+ cpuflags_t flags;
+
+ /* Remember old process to save its context later */
+ old_process = CurrentProcess;
+
+#ifdef IRQ_RUNNING
+ /* Scheduling in interrupts is a nono. */
+ ASSERT(!IRQ_RUNNING());
+#endif
+
+ /* Poll on the ready queue for the first ready process */
+ IRQ_SAVE_DISABLE(flags);
+ while (!(CurrentProcess = (struct Process *)list_remHead(&ProcReadyList)))
+ {
+ /*
+ * Make sure we physically reenable interrupts here, no matter what
+ * the current task status is. This is important because if we
+ * are idle-spinning, we must allow interrupts, otherwise no
+ * process will ever wake up.
+ *
+ * During idle-spinning, can occur an interrupt, it may be able to
+ * modify \p ProcReadyList. To ensure that compiler reload this
+ * variable every while cycle we call CPU_MEMORY_BARRIER.
+ * The memory barrier ensure that all variables used in this context
+ * are reloaded.
+ * \todo If there was a way to write sig_wait() so that it does not
+ * disable interrupts while waiting, there would not be any
+ * reason to do this.
+ */
+ IRQ_ENABLE;
+ CPU_IDLE;
+ MEMORY_BARRIER;
+ IRQ_DISABLE;
+ }
+ IRQ_RESTORE(flags);
+
+ /*
+ * Optimization: don't switch contexts when the active
+ * process has not changed.
+ */
+ if (CurrentProcess != old_process)
+ {
+ cpustack_t *dummy;
+
+#if CONFIG_KERN_PREEMPTIVE
+ /* Reset quantum for this process */
+ Quantum = CONFIG_KERN_QUANTUM;
+#endif
+
+ /* Save context of old process and switch to new process. If there is no
+ * old process, we save the old stack pointer into a dummy variable that
+ * we ignore. In fact, this happens only when the old process has just
+ * exited.
+ * TODO: Instead of physically clearing the process at exit time, a zombie
+ * list should be created.
+ */
+ asm_switch_context(&CurrentProcess->stack, old_process ? &old_process->stack : &dummy);
+ }
+
+ /* This RET resumes the execution on the new process */
+}
+
+
+/**
+ * Terminate the current process
+ */
+void proc_exit(void)
+{
+#if CONFIG_KERN_MONITOR
+ monitor_remove(CurrentProcess);
+#endif
+
+#if CONFIG_KERN_HEAP
+ /*
+ * The following code is BROKEN.
+ * We are freeing our own stack before entering proc_schedule()
+ * BAJO: A correct fix would be to rearrange the scheduler with
+ * an additional parameter which frees the old stack/process
+ * after a context switch.
+ */
+ if (CurrentProcess->flags & PF_FREESTACK)
+ heap_free(CurrentProcess->stack_base, CurrentProcess->stack_size);
+ heap_free(CurrentProcess);
+#endif
+
+#if (ARCH & ARCH_EMUL)
+#warning This is wrong
+ /* Reinsert process stack in free list */
+ ADDHEAD(&StackFreeList, (Node *)(CurrentProcess->stack
+ - (CONFIG_PROC_DEFSTACKSIZE / sizeof(cpustack_t))));
+
+ /*
+ * NOTE: At this point the first two words of what used
+ * to be our stack contain a list node. From now on, we
+ * rely on the compiler not reading/writing the stack.
+ */
+#endif /* ARCH_EMUL */
+
+ CurrentProcess = NULL;
+ proc_schedule();
+ /* not reached */
+}
+
+
+/**
+ * Co-operative context switch
+ */
+void proc_switch(void)
+{
+ cpuflags_t flags;
+
+ IRQ_SAVE_DISABLE(flags);
+ SCHED_ENQUEUE(CurrentProcess);
+ IRQ_RESTORE(flags);
+
+ proc_schedule();
+}
+
+
+/**
+ * Get the pointer to the current process
+ */
+struct Process *proc_current(void)
+{
+ return CurrentProcess;
+}
+
+/**
+ * Get the pointer to the user data of the current process
+ */
+iptr_t proc_current_user_data(void)
+{
+ return CurrentProcess->user_data;
+}
+
+
+#if CONFIG_KERN_PREEMPTIVE
+
+/**
+ * Disable preemptive task switching.
+ *
+ * The scheduler maintains a per-process nesting counter. Task switching is
+ * effectively re-enabled only when the number of calls to proc_permit()
+ * matches the number of calls to proc_forbid().
+ *
+ * Calling functions that could sleep while task switching is disabled
+ * is dangerous, although supported. Preemptive task switching is
+ * resumed while the process is sleeping and disabled again as soon as
+ * it wakes up again.
+ *
+ * \sa proc_permit()
+ */
+void proc_forbid(void)
+{
+ /* No need to protect against interrupts here. */
+ ++CurrentProcess->forbid_cnt;
+}
+
+/**
+ * Re-enable preemptive task switching.
+ *
+ * \sa proc_forbid()
+ */
+void proc_permit(void)
+{
+ /* No need to protect against interrupts here. */
+ --CurrentProcess->forbid_cnt;
+}
+
+#endif /* CONFIG_KERN_PREEMPTIVE */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Process scheduler (public interface).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+#ifndef KERN_PROC_H
+#define KERN_PROC_H
+
+#include <cfg/compiler.h>
+#include <cpu/irq.h>
+#include <config_kern.h>
+
+/* Fwd decl */
+struct Process;
+
+/* Task scheduling services */
+void proc_init(void);
+struct Process *proc_new_with_name(const char* name, void (*entry)(void), iptr_t data, size_t stacksize, cpustack_t *stack);
+
+#if !CONFIG_KERN_MONITOR
+ #define proc_new(entry,data,size,stack) proc_new_with_name(NULL,(entry),(data),(size),(stack))
+#else
+ #define proc_new(entry,data,size,stack) proc_new_with_name(#entry,(entry),(data),(size),(stack))
+#endif
+
+void proc_exit(void);
+void proc_switch(void);
+void proc_test(void);
+struct Process *proc_current(void);
+iptr_t proc_current_user_data(void);
+void proc_rename(struct Process *proc, const char* name);
+
+#if CONFIG_KERN_PREEMPTIVE
+ void proc_forbid(void);
+ void proc_permit(void);
+#else
+ INLINE void proc_forbid(void) { /* nop */ }
+ INLINE void proc_permit(void) { /* nop */ }
+#endif
+
+/**
+ * Execute a block of \a CODE atomically with respect to task scheduling.
+ */
+#define PROC_ATOMIC(CODE) \
+ do { \
+ proc_forbid(); \
+ CODE; \
+ proc_permit(); \
+ } while(0)
+
+#endif /* KERN_PROC_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2001, 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Internal scheduler structures and definitions for processes.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef KERN_PROC_P_H
+#define KERN_PROC_P_H
+
+#include <cfg/compiler.h>
+#include <cpu/types.h> /* for cpu_stack_t */
+#include <mware/list.h>
+#include <config_kern.h>
+#include <appconfig.h>
+
+typedef struct Process
+{
+ Node link; /**< Link Process into scheduler lists */
+ cpustack_t *stack; /**< Per-process SP */
+ iptr_t user_data; /**< Custom data passed to the process */
+
+#if CONFIG_KERN_SIGNALS
+ sigmask_t sig_wait; /**< Signals the process is waiting for */
+ sigmask_t sig_recv; /**< Received signals */
+#endif
+
+#if CONFIG_KERN_PREEMPTIVE
+ int forbid_cnt; /**< Nesting count for proc_forbid()/proc_permit(). */
+#endif
+
+#if CONFIG_KERN_HEAP
+ uint16_t flags; /**< Flags */
+ cpustack_t *stack_base; /**< Base of process stack */
+ size_t stack_size; /**< Size of process stack */
+#endif
+
+#if CONFIG_KERN_MONITOR
+ struct ProcMonitor
+ {
+ Node link;
+ const char *name;
+ cpustack_t *stack_base;
+ size_t stack_size;
+ } monitor;
+#endif
+
+} Process;
+
+
+/**
+ * \name Flags for Process.flags.
+ * \{
+ */
+#define PF_FREESTACK BV(0) /**< Free the stack when process dies */
+/*\}*/
+
+
+/** Track running processes. */
+extern REGISTER Process *CurrentProcess;
+
+/** Track ready processes. */
+extern REGISTER List ProcReadyList;
+
+
+/** Enqueue a task in the ready list. */
+#define SCHED_ENQUEUE(proc) ADDTAIL(&ProcReadyList, &(proc)->link)
+
+/** Schedule to another process *without* adding the current to the ready list. */
+void proc_schedule(void);
+
+#if CONFIG_KERN_MONITOR
+ /** Initialize the monitor */
+ void monitor_init(void);
+
+ /** Register a process into the monitor */
+ void monitor_add(Process *proc, const char *name, cpustack_t *stack, size_t stacksize);
+
+ /** Unregister a process from the monitor */
+ void monitor_remove(Process *proc);
+
+ /** Rename a process */
+ void monitor_rename(Process *proc, const char* name);
+#endif /* CONFIG_KERN_MONITOR */
+
+#endif /* KERN_PROC_P_H */
+
--- /dev/null
+
+#include <kern/proc.h>
+#include <drv/timer.h>
+
+/**
+ * Proc scheduling test subthread 1
+ */
+static void NORETURN proc_test_thread1(void)
+{
+ for (;;)
+ {
+ kputs(">task 1\n");
+ timer_delay(50);
+ proc_switch();
+ }
+}
+
+/**
+ * Proc scheduling test subthread 2
+ */
+static void NORETURN proc_test_thread2(void)
+{
+ for (;;)
+ {
+ kputs(">task 2\n");
+ timer_delay(75);
+ proc_switch();
+ }
+}
+
+static cpustack_t proc_test_stack1[CONFIG_PROC_DEFSTACKSIZE / sizeof(cpustack_t)];
+static cpustack_t proc_test_stack2[CONFIG_PROC_DEFSTACKSIZE / sizeof(cpustack_t)];
+
+/**
+ * Proc scheduling test
+ */
+void NORETURN proc_test(void)
+{
+ proc_new(proc_test_thread1, NULL, sizeof(proc_test_stack1), proc_test_stack1);
+ proc_new(proc_test_thread2, NULL, sizeof(proc_test_stack2), proc_test_stack2);
+ kputs("Created tasks\n");
+
+ kputs("stack1:\n");
+// #warning FIXME
+ kdump(proc_test_stack1+sizeof(proc_test_stack1)-64, 64);
+ kputs("stack2:\n");
+// #warning FIXME
+ kdump(proc_test_stack2+sizeof(proc_test_stack1)-64, 64);
+
+ for (;;)
+ {
+ kputs(">main task\n");
+ timer_delay(93);
+ proc_switch();
+ }
+
+ ASSERT(false);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2001, 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Semaphore based synchronization services.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "sem.h"
+#include <kern/proc.h>
+#include <kern/proc_p.h>
+#include <kern/signal.h>
+#include <cfg/debug.h>
+
+INLINE void sem_verify(struct Semaphore *s)
+{
+ (void)s;
+ ASSERT(s);
+ LIST_ASSERT_VALID(&s->wait_queue);
+ ASSERT(s->nest_count >= 0);
+ ASSERT(s->nest_count < 128); // heuristic max
+}
+
+
+/**
+ * \brief Initialize a Semaphore structure.
+ */
+void sem_init(struct Semaphore *s)
+{
+ LIST_INIT(&s->wait_queue);
+ s->owner = NULL;
+ s->nest_count = 0;
+}
+
+
+/**
+ * \brief Attempt to lock a semaphore without waiting.
+ *
+ * \return true in case of success, false if the semaphore
+ * was already locked by someone else.
+ *
+ * \note each call to sem_attempt() must be matched by a
+ * call to sem_release().
+ *
+ * \see sem_obtain() sem_release()
+ */
+bool sem_attempt(struct Semaphore *s)
+{
+ bool result = false;
+
+ proc_forbid();
+ sem_verify(s);
+ if ((!s->owner) || (s->owner == CurrentProcess))
+ {
+ s->owner = CurrentProcess;
+ s->nest_count++;
+ result = true;
+ }
+ proc_permit();
+
+ return result;
+}
+
+
+/**
+ * \brief Lock a semaphore.
+ *
+ * If the semaphore is already owned by another process, the caller
+ * process will be enqueued into the waiting list and sleep until
+ * the semaphore is available.
+ *
+ * \note Each call to sem_obtain() must be matched by a
+ * call to sem_release().
+ *
+ * \note This routine is optimized for highest speed in
+ * the most common case: the semaphore is free or locked
+ * by the calling process itself. Rearranging this code
+ * is probably a bad idea.
+ *
+ * \sa sem_release() sem_attempt()
+ */
+void sem_obtain(struct Semaphore *s)
+{
+ proc_forbid();
+ sem_verify(s);
+
+ /* Is the semaphore already locked by another process? */
+ if (UNLIKELY(s->owner && (s->owner != CurrentProcess)))
+ {
+ /* Append calling process to the wait queue */
+ ADDTAIL(&s->wait_queue, (Node *)CurrentProcess);
+
+ /*
+ * We will wake up only when the current owner calls
+ * sem_release(). Then, the semaphore will already
+ * be locked for us.
+ */
+ proc_permit();
+ proc_schedule();
+ }
+ else
+ {
+ ASSERT(LIST_EMPTY(&s->wait_queue));
+
+ /* The semaphore was free: lock it */
+ s->owner = CurrentProcess;
+ s->nest_count++;
+ proc_permit();
+ }
+}
+
+
+/**
+ * \brief Release a lock on a previously locked semaphore.
+ *
+ * If the nesting count of the semaphore reaches zero,
+ * the next process waiting for it will be awaken.
+ *
+ * \note This routine is optimized for highest speed in
+ * the most common case: the semaphore has been locked just
+ * once and nobody else was waiting for it. Rearranging
+ * this code is probably a bad idea.
+ *
+ * \sa sem_obtain() sem_attempt()
+ */
+void sem_release(struct Semaphore *s)
+{
+ proc_forbid();
+ sem_verify(s);
+
+ ASSERT(s->owner == CurrentProcess);
+
+ /*
+ * Decrement nesting count and check if the semaphore
+ * has been fully unlocked.
+ */
+ if (--s->nest_count == 0)
+ {
+ Process *proc;
+
+ /* Disown semaphore */
+ s->owner = NULL;
+
+ /* Give semaphore to the first applicant, if any */
+ if (UNLIKELY((proc = (Process *)list_remHead(&s->wait_queue))))
+ {
+ s->nest_count = 1;
+ s->owner = proc;
+ SCHED_ENQUEUE(proc);
+ }
+ }
+
+ proc_permit();
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2001,2004,2005,2006,2007 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Mutually exclusive semaphores.
+ * Shared locking not supported in this implementation.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+
+#ifndef KERN_SEM_H
+#define KERN_SEM_H
+
+#include <cfg/compiler.h>
+#include <mware/list.h>
+
+/* Fwd decl */
+struct Process;
+
+
+typedef struct Semaphore
+{
+ struct Process *owner;
+ List wait_queue;
+ int nest_count;
+} Semaphore;
+
+/**
+ * \name Process synchronization services
+ * \{
+ */
+void sem_init(struct Semaphore *s);
+bool sem_attempt(struct Semaphore *s);
+void sem_obtain(struct Semaphore *s);
+void sem_release(struct Semaphore *s);
+/* \} */
+
+#endif /* KERN_SEM_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief IPC signals implementation.
+ *
+ * Signals are a low-level IPC primitive. A process receives a signal
+ * when some external event has happened. Like interrupt requests,
+ * signals do not carry any additional information. If processing a
+ * specific event requires additional data, the process must obtain it
+ * through some other mechanism.
+ *
+ * Despite the name, one shouldn't confuse these signals with POSIX
+ * signals. POSIX signals are usually executed synchronously, like
+ * software interrupts.
+ *
+ * Signals are very low overhead. Using them exclusively to wait
+ * for multiple asynchronous events results in very simple dispatch
+ * logic with low processor and resource usage.
+ *
+ * The "event" module is a higher-level interface that can optionally
+ * deliver signals to processes. Messages provide even higher-level
+ * IPC services built on signals. Semaphore arbitration is also
+ * implemented using signals.
+ *
+ * In this implementation, each process has a limited set of signal
+ * bits (usually 32) and can wait for multiple signals at the same
+ * time using sig_wait(). Signals can also be polled using sig_check(),
+ * but a process spinning on its signals usually defeats their purpose
+ * of providing a multitasking-friendly infrastructure for event-driven
+ * applications.
+ *
+ * Signals are like flags: they are either active or inactive. After an
+ * external event has delivered a particular signal, it remains raised until
+ * the process acknowledges it using either sig_wait() or sig_check().
+ * Counting signals is not a reliable way to count how many times a
+ * particular event has occurred, because the same signal may be
+ * delivered twice before the process can notice.
+ *
+ * Any execution context, including an interrupt handler, can deliver
+ * a signal to a process using sig_signal(). Multiple independent signals
+ * may be delivered at once with a single invocation of sig_signal(),
+ * although this is rarely useful.
+ *
+ * \section signal_allocation Signal Allocation
+ *
+ * There's no hardcoded mapping of specific events to signal bits.
+ * The meaning of a particular signal bit is defined by an agreement
+ * between the delivering entity and the receiving process.
+ * For instance, a terminal driver may be designed to deliver
+ * a signal bit called SIG_INT when it reads the CTRL-C sequence
+ * from the keyboard, and a process may react to it by quitting.
+ *
+ * \section sig_single SIG_SINGLE
+ *
+ * The SIG_SINGLE bit is reserved as a convenient shortcut in those
+ * simple scenarios where a process needs to wait on just one event
+ * synchronously. By using SIG_SINGLE, there's no need to allocate
+ * a specific signal from the free pool. The constraints for safely
+ * accessing SIG_SINGLE are:
+ * - The process MUST sig_wait() exclusively on SIG_SINGLE
+ * - SIG_SIGNAL MUST NOT be left pending after use (sig_wait() will reset
+ * it automatically)
+ * - Do not sleep between starting the asynchronous task that will fire
+ * SIG_SINGLE, and the call to sig_wait().
+ * - Do not call system functions that may implicitly sleep, such as
+ * timer_delayTickes().
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "signal.h"
+
+#include <cfg/debug.h>
+#include <drv/timer.h>
+#include <kern/proc.h>
+#include <kern/proc_p.h>
+
+
+#if CONFIG_KERN_SIGNALS
+
+/**
+ * Check if any of the signals in \a sigs has occurred and clear them.
+ * \return the signals that have occurred.
+ */
+sigmask_t sig_check(sigmask_t sigs)
+{
+ sigmask_t result;
+ cpuflags_t flags;
+
+ IRQ_SAVE_DISABLE(flags);
+ result = CurrentProcess->sig_recv & sigs;
+ CurrentProcess->sig_recv &= ~sigs;
+ IRQ_RESTORE(flags);
+
+ return result;
+}
+
+
+/**
+ * Sleep until any of the signals in \a sigs occurs.
+ * \return the signal(s) that have awoken the process.
+ */
+sigmask_t sig_wait(sigmask_t sigs)
+{
+ sigmask_t result;
+ cpuflags_t flags;
+
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Loop until we get at least one of the signals */
+ while (!(result = CurrentProcess->sig_recv & sigs))
+ {
+ /* go to sleep and proc_schedule() another process */
+ CurrentProcess->sig_wait = sigs;
+ proc_schedule();
+
+ /* When we come back here, a signal must be arrived */
+ ASSERT(!CurrentProcess->sig_wait);
+ ASSERT(CurrentProcess->sig_recv);
+ }
+
+ /* Signals found: clear them and return */
+ CurrentProcess->sig_recv &= ~sigs;
+
+ IRQ_RESTORE(flags);
+ return result;
+}
+
+/**
+ * Sleep until any of the signals in \a sigs or \a timeout ticks elapse.
+ * If the timeout elapse a SIG_TIMEOUT is added to the received signal(s).
+ * \return the signal(s) that have awoken the process.
+ * \note Caller must check return value to check which signal awoke the process.
+ */
+sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout)
+{
+ Timer t;
+ sigmask_t res;
+ cpuflags_t flags;
+
+ ASSERT(!sig_check(SIG_TIMEOUT));
+ ASSERT(!(sigs & SIG_TIMEOUT));
+ /* IRQ are needed to run timer */
+ ASSERT(IRQ_ENABLED());
+
+ timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
+ timer_setDelay(&t, timeout);
+ timer_add(&t);
+ res = sig_wait(SIG_TIMEOUT | sigs);
+
+ IRQ_SAVE_DISABLE(flags);
+ /* Remove timer if sigs occur before timer signal */
+ if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT))
+ timer_abort(&t);
+ IRQ_RESTORE(flags);
+ return res;
+}
+
+
+/**
+ * Send the signals \a sigs to the process \a proc.
+ * The process will be awoken if it was waiting for any of them.
+ *
+ * \note This call is interrupt safe.
+ */
+void sig_signal(Process *proc, sigmask_t sigs)
+{
+ cpuflags_t flags;
+ IRQ_SAVE_DISABLE(flags);
+
+ /* Set the signals */
+ proc->sig_recv |= sigs;
+
+ /* Check if process needs to be awoken */
+ if (proc->sig_recv & proc->sig_wait)
+ {
+ /* Wake up process and enqueue in ready list */
+ proc->sig_wait = 0;
+ SCHED_ENQUEUE(proc);
+ }
+
+ IRQ_RESTORE(flags);
+}
+
+#endif /* CONFIG_KERN_SIGNALS */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Signal module (public interface).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+
+#ifndef KERN_SIGNAL_H
+#define KERN_SIGNAL_H
+
+#include <cfg/compiler.h>
+
+
+/* Fwd decl */
+struct Process;
+
+/* Inter-process Communication services */
+sigmask_t sig_check(sigmask_t sigs);
+void sig_signal(struct Process *proc, sigmask_t sig);
+sigmask_t sig_wait(sigmask_t sigs);
+sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout);
+
+
+/**
+ * \name Signal definitions
+ * \{
+ */
+#define SIG_USER0 BV(0) /**< Free for user usage */
+#define SIG_USER1 BV(1) /**< Free for user usage */
+#define SIG_USER2 BV(2) /**< Free for user usage */
+#define SIG_USER3 BV(3) /**< Free for user usage */
+#define SIG_TIMEOUT BV(4) /**< Reserved for timeout use */
+#define SIG_SYSTEM5 BV(5) /**< Reserved for system use */
+#define SIG_SYSTEM6 BV(6) /**< Reserved for system use */
+#define SIG_SINGLE BV(7) /**< Used to wait for a single event */
+/*\}*/
+
+#endif /* KERN_SIGNAL_H */
--- /dev/null
+#if defined(__i386__)
+ #include "switch_i386.s"
+#elif defined(__x86_64__)
+ #include "switch_x86_64.s"
+#else
+ #error Unknown CPU
+#endif
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief ARM context switch
+ *
+ * \version $Id: proc.c 18271 2007-10-11 14:51:31Z batt $
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+
+/*
+ * NOTE: At each change of this function affecting proc.c
+ * (i.e. arguments, data stored in the stack) bump up version
+ * number in asm_switch_version().
+ */
+
+/* void asm_switch_context(void **new_sp, void **save_sp) */
+.globl asm_switch_context
+asm_switch_context:
+ mrs r2, cpsr /* Save status. */
+ stmfd sp!, {r2, r4-r11, lr} /* Save registers. */
+
+ str sp, [r1] /* Save old stack pointer. */
+ ldr sp, [r0] /* Load new stack pointer */
+
+ ldmfd sp!, {r2, r4-r11, lr} /* Load new registers. */
+ msr cpsr, r2 /* restore flags reg. */
+
+ mov pc, lr
+
+
+/* int asm_switch_version(void) */
+.globl asm_switch_version
+asm_switch_version:
+ mov r0, #1
+ mov pc, lr
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ * This file is part of DevLib - See devlib/README for information.
+ * -->
+ *
+ * \brief AVR context switch
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#include <avr/io.h>
+
+/*
+ * NOTE: At each change of this function affecting proc.c
+ * (i.e. arguments, data stored in the stack) bump up version
+ * number in asm_switch_version().
+ */
+
+/* void asm_switch_context(void **new_sp, void **save_sp) */
+.globl asm_switch_context
+asm_switch_context:
+
+; r0 is the TEMP REG and can be used freely.
+; r1 is the ZERO REG and must always contain 0.
+;
+; Stack frame is 19 byte, remember to update
+; CPU_SAVED_REGS_CNT if you change pushed regs.
+
+ in r0,SREG-__SFR_OFFSET
+ push r0
+; push r1 ;zero-reg
+ push r2
+ push r3
+ push r4
+ push r5
+ push r6
+ push r7
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+ push r16
+ push r17
+; push r18 ;caller-save
+; push r19 ;caller-save
+; push r20 ;caller-save
+; push r21 ;caller-save
+; push r22 ;caller-save
+; push r23 ;caller-save
+; push r24 ;caller-save
+; push r25 ;caller-save
+; push r26 ;caller-save
+; push r27 ;caller-save
+ push r28
+ push r29
+; push r30 ;caller-save
+; push r31 ;caller-save
+
+; First parameter (new_sp) is in r24:r25, second (save_sp) in r22:r23
+
+ in r18,SPL-__SFR_OFFSET ; r18:r19 = SP
+ in r19,SPH-__SFR_OFFSET
+ movw r26,r22 ; X = save_sp
+ st X+,r18 ; *save_sp = SP
+ st X,r19
+ movw r26,r24 ; X = new_sp
+ ld r18,X+
+ ld r19,X
+
+; Set new stack pointer.
+; AVR is an 8 bit processor so
+; care must be taken when updating
+; SP that is a 16 bit reg.
+; Two instructions are required to update SP
+; so an IRQ can sneak in between them.
+; So IRQ *MUST* be disabled and then restored.
+ cli ; Disable interrupt
+ out SPL-__SFR_OFFSET,r18 ; SP = *new_sp
+ out SPH-__SFR_OFFSET,r19
+ out SREG-__SFR_OFFSET,r0 ; Restore previous IRQ state
+
+; pop r31 ;caller-save
+; pop r30 ;caller-save
+ pop r29
+ pop r28
+; pop r27 ;caller-save
+; pop r26 ;caller-save
+; pop r25 ;caller-save
+; pop r24 ;caller-save
+; pop r23 ;caller-save
+; pop r22 ;caller-save
+; pop r21 ;caller-save
+; pop r20 ;caller-save
+; pop r19 ;caller-save
+; pop r18 ;caller-save
+ pop r17
+ pop r16
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop r7
+ pop r6
+ pop r5
+ pop r4
+ pop r3
+ pop r2
+; pop r1 ;zero-reg
+ pop r0
+ out SREG-__SFR_OFFSET,r0
+
+ ret
+
+
+/* int asm_switch_version(void) */
+.globl asm_switch_version
+asm_switch_version:
+ ldi r24,lo8(1)
+ ldi r25,hi8(1)
+ ret
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ * \brief DSP5680x task switching support
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2006/02/24 01:17:05 bernie
+ *#* Update for new emulator.
+ *#*
+ *#* Revision 1.5 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.4 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.3 2004/07/30 14:24:16 rasky
+ *#* Task switching con salvataggio perfetto stato di interrupt (SR)
+ *#* Kernel monitor per dump informazioni su stack dei processi
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 17:27:00 bernie
+ *#* Import kern/ subdirectory.
+ *#*
+ *#*/
+
+void asm_switch_context(void ** new_sp/*R2*/, void ** save_sp/*R3*/);
+asm void asm_switch_context(void ** new_sp, void ** save_sp)
+{
+ lea (SP)+
+
+ ; From the manual:
+ ; The compiler uses page 0 address locations X: 0x0030 - 0x003F as register
+ ; variables. Frequently accessed local variables are assigned to the page 0
+ ; registers instead of to stack locations so that load and store instructions
+ ; are shortened. Addresses X: 0x0030 - 0x0037 (page 0 registers MR0-MR7) are
+ ; volatile registers and can be overwritten. The remaining registers (page 0
+ ; registers MR8-MR15) are treated as non-volatile and, if used by a routine,
+ ; must be saved on entry and restored on exit.
+ ;
+ ; So, register 0x30-0x37 are caller-save, while 0x38-0x3F are callee-save.
+ move x:<$38,y1
+ move y1,x:(SP)+
+ move x:<$39,y1
+ move y1,x:(SP)+
+ move x:<$3A,y1
+ move y1,x:(SP)+
+ move x:<$3B,y1
+ move y1,x:(SP)+
+ move x:<$3C,y1
+ move y1,x:(SP)+
+ move x:<$3D,y1
+ move y1,x:(SP)+
+ move x:<$3E,y1
+ move y1,x:(SP)+
+ move x:<$3F,y1
+ move y1,x:(SP)
+
+ ;
+ ; Switch stacks
+ nop
+ move SP, x:(R3)
+ nop
+ move x:(R2), SP
+ nop
+
+ ;
+ ; restore all saved registers
+ ;
+ pop y1
+ move y1,x:<$3F
+ pop y1
+ move y1,x:<$3E
+ pop y1
+ move y1,x:<$3D
+ pop y1
+ move y1,x:<$3C
+ pop y1
+ move y1,x:<$3B
+ pop y1
+ move y1,x:<$3A
+ pop y1
+ move y1,x:<$39
+ pop y1
+ move y1,x:<$38
+
+ ; SR is already pushed on the stack (normal call context). Use RTI to restore
+ ; it, so that interrupt status is preserved across the tasks.
+ rti
+}
+
+int asm_switch_version(void);
+int asm_switch_version(void)
+{
+ return 1;
+}
--- /dev/null
+;* Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+;* Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+;* This file is part of DevLib - See devlib/README for information.
+;*
+;* \version $Id$
+;*
+;* \author Bernardo Innocenti <bernie@develer.com>
+;*
+
+;* $Log$
+;* Revision 1.2 2004/06/06 16:14:12 bernie
+;* Add DevLib license information.
+;*
+;* Revision 1.1 2004/05/23 17:27:00 bernie
+;* Import kern/ subdirectory.
+;*
+;*
+
+!!!!!! THIS FILE HAS NOT BEEN REVISED FOR THE NEW SCHEDULER API !!!!!!
+
+
+
+ NAME AsmSwitch
+ RSEG CODE
+
+ EXTERN ?LR
+ EXTERN ?GR
+ PUBLIC AsmSwitchContext
+ PUBLIC AsmReplaceContext
+
+
+;* Perform low-level process context switching
+;*
+;* void AsmSwitchContext(cpustack_t *new_sp, cpustack_t **save_sp)
+;* GR+0 SP+2
+;*
+;* Replace current context with new process
+;*
+;* void AsmReplaceContext(cpustack_t *new_sp, cpustack_t **dummy)
+;* GR+0 SP+2
+;*
+
+AsmSwitchContext:
+
+; pop 2nd parameter from the stack
+ ld ?GR+2,2[SP]
+
+; save all registers
+ push ?LR+0
+ push ?LR+2
+ push ?LR+4
+ push ?LR+6
+ push ?LR+8
+ push ?LR+10
+ push ?LR+12
+ push ?LR+14
+ push ?LR+16
+ push ?LR+18
+ push ?LR+20
+ push ?LR+22
+ push ?LR+24
+ push ?LR+26
+ push ?LR+28
+ push ?LR+30
+ st SP,[?GR+2] ; save old stack pointer
+ ; fall-thru
+
+AsmReplaceContext:
+ ld SP,?GR+0 ; load new stack pointer
+
+; restore all registers
+ pop ?LR+30
+ pop ?LR+28
+ pop ?LR+26
+ pop ?LR+24
+ pop ?LR+22
+ pop ?LR+20
+ pop ?LR+18
+ pop ?LR+16
+ pop ?LR+14
+ pop ?LR+12
+ pop ?LR+10
+ pop ?LR+8
+ pop ?LR+6
+ pop ?LR+4
+ pop ?LR+2
+ pop ?LR+0
+
+; restore execution in new context
+ ret
+
+ END
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ * This file is part of DevLib - See devlib/README for information.
+ * -->
+ *
+ * \brief i386 context switch
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/* void asm_switch_context(void ** new_sp, void ** save_sp) */
+.globl asm_switch_context
+asm_switch_context:
+ pushl %eax
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %esi
+ pushl %edi
+ pushl %ebp
+ movl 0x24(%esp),%ebp /* ebp = save_sp */
+ movl %esp,(%ebp) /* *save_sp = esp */
+ movl 0x20(%esp),%ebp /* ebp = new_sp */
+ movl (%ebp),%esp /* esp = *new_sp */
+ popl %ebp
+ popl %edi
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+ ret
+
+/* int asm_switch_version(void) */
+.globl asm_switch_version
+asm_switch_version:
+ mov $1,%eax
+ ret
+
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ * This file is part of DevLib - See devlib/README for information.
+ * -->
+ *
+ * \brief i386 context switch for WIN32
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+!!!!!! THIS FILE HAS NOT BEEN REVISED FOR THE NEW SCHEDULER API !!!!!!
+
+__declspec(naked) void AsmSwitchContext(void * new_sp, void ** save_sp)
+{
+ __asm
+ {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+ push edi
+ push ebp
+ mov ebp,dword ptr [esp+24h] ; ebp <- save_sp
+ mov dword ptr [ebp],esp ; *save_sp = esp
+ mov esp,dword ptr [esp+20h] ; new_sp
+ pop ebp
+ pop edi
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret
+ }
+}
+
+__declspec(naked) void AsmReplaceContext(void * new_sp, void ** dummy)
+{
+ __asm
+ {
+ mov esp,dword ptr [esp + 4] ; new_sp
+ pop ebp
+ pop edi
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret
+ }
+}
+
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ * This file is part of DevLib - See devlib/README for information.
+ * -->
+ *
+ * \brief i386 context switch
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*
+ * $Log$
+ * Revision 1.4 2006/09/20 14:02:49 marco
+ * C-style comment.
+ *
+ * Revision 1.3 2006/02/24 01:35:40 bernie
+ * Update for new emulator.
+ *
+ * Revision 1.2 2006/02/24 01:17:05 bernie
+ * Update for new emulator.
+ *
+ * Revision 1.1 2005/11/27 03:06:15 bernie
+ * Add x86_64 task switching (to be updated to new-style scheduler).
+ *
+ * Revision 1.1 2005/11/14 21:06:38 bernie
+ * Add x86_64 support.
+ *
+ * Revision 1.2 2004/06/06 16:14:12 bernie
+ * Add DevLib license information.
+ *
+ * Revision 1.1 2004/05/23 17:27:00 bernie
+ * Import kern/ subdirectory.
+ *
+ */
+
+/* I know it's ugly... */
+/* .intel_syntax */
+
+/* void AsmSwitchContext(void **new_sp, void **save_sp) */
+/* %rdi %rsi */
+.globl asm_switch_context
+asm_switch_context:
+ pushq %rax
+ pushq %rbx
+ pushq %rcx
+ pushq %rdx
+ pushq %rsi
+ pushq %rdi
+ pushq %rbp
+ movq %rsp,(%rsi) /* *save_sp = rsp */
+ movq (%rdi),%rsp /* rsp = *new_sp */
+ popq %rbp
+ popq %rdi
+ popq %rsi
+ popq %rdx
+ popq %rcx
+ popq %rbx
+ popq %rax
+ ret
+
+/* int asm_switch_version(void) */
+.globl asm_switch_version
+asm_switch_version:
+ mov $1,%rax
+ ret
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * -->
+ *
+ * \brief Display Blanker (implementation).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "blanker.h"
+#include <drv/kbd.h>
+#include <drv/timer.h>
+
+/* Time without input events before starting blanker */
+#define BLK_BLANKTIMEOUT (15 * 1000) /* ms */
+
+// TODO: move to blanker_hw.h
+#include <drv/power.h>
+#define BLK_LCDON power_LcdOn()
+#define BLK_LCDOFF power_LcdOff()
+
+
+/** Keyboard event handler to listen for key presses in blanker. */
+static KbdHandler blk_KbdHandler;
+
+/** Time since last key event. */
+static ticks_t blk_lastevent;
+
+/** Display blanking function is enabled. */
+static bool blk_enabled;
+
+/** Display blanker is engaged right now. */
+static bool blk_active;
+
+
+static bool blk_on(void)
+{
+ if (!blk_active)
+ {
+ blk_active = true;
+ BLK_LCDOFF;
+ }
+ return true;
+}
+
+
+static void blk_off(void)
+{
+ if (blk_active)
+ {
+ blk_active = false;
+ BLK_LCDON;
+ }
+}
+
+
+void blk_retrigger(void)
+{
+ blk_lastevent = timer_clock();
+ blk_off();
+}
+
+#if 0
+/**
+ * Matrix-like screen saver effect
+ */
+static void blk_hack(void)
+{
+ static signed char blk_colstart[LCD_COLS];
+ UBYTE row, col;
+
+
+ if (rand()%3 == 0)
+ {
+ /* Modify one column */
+ col = rand() % LCD_COLS;
+ blk_colstart[col] += rand() % 12 - 5;
+ }
+
+ for (col = 0; col < LCD_COLS; ++col)
+ {
+ if (blk_colstart[col] > 0)
+ {
+ --blk_colstart[col];
+
+ /* Scroll down */
+ for(row = LCD_ROWS-1; row; --row)
+ {
+ lcd_SetAddr(blk_layer, LCD_POS(col,row));
+ lcd_PutChar(blk_layer->Buf[LCD_POS(col,row-1)], blk_layer);
+ }
+
+ /* Add new kanji */
+ lcd_SetAddr(blk_layer, LCD_POS(col,0));
+ lcd_PutChar((char)(rand() % 127 + 128), blk_layer);
+ }
+ else if (blk_colstart[col] < 0)
+ {
+ ++blk_colstart[col];
+
+ /* Clear tail */
+ for(row = 0; row < LCD_ROWS; ++row)
+ {
+ if (blk_layer->Buf[LCD_POS(col,row)] != ' ')
+ {
+ lcd_SetAddr(blk_layer, LCD_POS(col,row));
+ lcd_PutChar(' ', blk_layer);
+ break;
+ }
+ }
+ }
+ }
+}
+#endif
+
+
+static keymask_t blk_handlerFunc(keymask_t key)
+{
+ /* key used to turn off blanker */
+ static keymask_t offkey;
+
+ ticks_t now = timer_clock();
+
+ /* If key pressed */
+ if (key != 0)
+ {
+ blk_lastevent = now;
+ if (blk_active)
+ {
+ blk_off();
+
+ /* remember and eat key event */
+ offkey = key;
+ key = 0;
+ }
+ else if (key == offkey)
+ {
+ /* keep eating the key until released */
+ key = 0;
+ }
+
+ /* pass key through */
+ return key;
+ }
+
+ /* reset off key */
+ offkey = 0;
+
+ /* Blank timeout reached? */
+ if (now - blk_lastevent > ms_to_ticks(BLK_BLANKTIMEOUT))
+ {
+ /* Enable blanker unless already done */
+ if (!blk_active && !blk_on())
+ return 0;
+
+#if 0
+ /* Do some nice visual effect */
+ blk_hack();
+#endif /* _DEBUG */
+ }
+
+ return 0;
+}
+
+
+void blk_enable(void)
+{
+ if (!blk_enabled)
+ {
+ blk_active = false;
+ blk_lastevent = timer_clock();
+
+ /* Add display blanker handler */
+ blk_KbdHandler.hook = blk_handlerFunc;
+ blk_KbdHandler.pri = 100; /* high priority */
+ blk_KbdHandler.flags = KHF_RAWKEYS;
+ kbd_addHandler(&blk_KbdHandler);
+
+ blk_enabled = true;
+ }
+}
+
+
+void blk_disable(void)
+{
+ if (blk_enabled)
+ {
+ kbd_remHandler(&blk_KbdHandler);
+ blk_off();
+ blk_enabled = false;
+ }
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * -->
+ *
+ * \brief Display Blanker (implementation).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+#ifndef MWARE_BLANKER_H
+#define MWARE_BLANKER_H
+
+extern void blk_enable(void);
+extern void blk_disable(void);
+extern void blk_retrigger(void);
+
+#endif /* MWARE_BLANKER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Functions to convert integers to/from host byte-order.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#ifndef MWARE_BYTEORDER_H
+#define MWARE_BYTEORDER_H
+
+#include <cfg/compiler.h>
+#include <cpu/attr.h>
+
+/**
+ * Swap upper and lower bytes in a 16-bit value.
+ */
+INLINE uint16_t swab16(uint16_t x)
+{
+ return ((x & (uint16_t)0x00FFU) << 8)
+ | ((x & (uint16_t)0xFF00U) >> 8);
+}
+
+/**
+ * Reverse bytes in a 32-bit value (e.g.: 0x12345678 -> 0x78563412).
+ */
+INLINE uint32_t swab32(uint32_t x)
+{
+ return ((x & (uint32_t)0x000000FFUL) << 24)
+ | ((x & (uint32_t)0x0000FF00UL) << 8)
+ | ((x & (uint32_t)0x00FF0000UL) >> 8)
+ | ((x & (uint32_t)0xFF000000UL) >> 24);
+}
+
+/**
+ * Reverse bytes in a 64-bit value.
+ */
+INLINE uint64_t swab64(uint64_t x)
+{
+ return (uint64_t)swab32(x >> 32)
+ | ((uint64_t)swab32(x & 0xFFFFFFFFUL) << 32);
+}
+
+/**
+ * Reverse bytes in a float value.
+ */
+INLINE float swab_float(float x)
+{
+ /* Avoid breaking strict aliasing rules. */
+ char *cx = (char *)(&x);
+ STATIC_ASSERT(sizeof(float) == 4);
+ #define BYTEORDER_SWAP(a, b) ((a) ^= (b) ^= (a) ^= (b))
+ BYTEORDER_SWAP(cx[0], cx[3]);
+ BYTEORDER_SWAP(cx[1], cx[2]);
+ #undef BYTEORDER_SWAP
+ return x;
+}
+
+INLINE uint16_t cpu_to_be16(uint16_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab16(x) : x;
+}
+
+INLINE uint16_t cpu_to_le16(uint16_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab16(x) : x;
+}
+
+INLINE uint32_t cpu_to_be32(uint32_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab32(x) : x;
+}
+
+INLINE uint32_t cpu_to_le32(uint32_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab32(x) : x;
+}
+
+INLINE uint64_t cpu_to_be64(uint64_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab64(x) : x;
+}
+
+INLINE uint64_t cpu_to_le64(uint64_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab64(x) : x;
+}
+
+INLINE float cpu_to_be_float(float x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab_float(x) : x;
+}
+
+INLINE float cpu_to_le_float(float x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab_float(x) : x;
+}
+
+INLINE uint16_t be16_to_cpu(uint16_t x)
+{
+ return cpu_to_be16(x);
+}
+
+INLINE uint16_t le16_to_cpu(uint16_t x)
+{
+ return cpu_to_le16(x);
+}
+
+INLINE uint32_t be32_to_cpu(uint32_t x)
+{
+ return cpu_to_be32(x);
+}
+
+INLINE uint32_t le32_to_cpu(uint32_t x)
+{
+ return cpu_to_le32(x);
+}
+
+INLINE uint64_t be64_to_cpu(uint64_t x)
+{
+ return cpu_to_be64(x);
+}
+
+INLINE uint64_t le64_to_cpu(uint64_t x)
+{
+ return cpu_to_le64(x);
+}
+
+INLINE float be_float_to_cpu(float x)
+{
+ return cpu_to_be_float(x);
+}
+
+INLINE float le_float_to_cpu(float x)
+{
+ return cpu_to_le_float(x);
+}
+
+INLINE uint16_t host_to_net16(uint16_t x)
+{
+ return cpu_to_be16(x);
+}
+
+INLINE uint16_t net_to_host16(uint16_t x)
+{
+ return be16_to_cpu(x);
+}
+
+INLINE uint32_t host_to_net32(uint32_t x)
+{
+ return cpu_to_be32(x);
+}
+
+INLINE uint32_t net_to_host32(uint32_t x)
+{
+ return be32_to_cpu(x);
+}
+
+INLINE uint64_t host_to_net64(uint64_t x)
+{
+ return cpu_to_be64(x);
+}
+
+INLINE uint64_t net_to_host64(uint64_t x)
+{
+ return be64_to_cpu(x);
+}
+
+INLINE float host_to_net_float(float x)
+{
+ return cpu_to_be_float(x);
+}
+
+INLINE float net_to_host_float(float x)
+{
+ return be_float_to_cpu(x);
+}
+
+#ifdef __cplusplus
+
+/// Type generic byte swapping.
+template<typename T>
+INLINE T swab(T x);
+
+template<> INLINE uint16_t swab(uint16_t x) { return swab16(x); }
+template<> INLINE uint32_t swab(uint32_t x) { return swab32(x); }
+template<> INLINE uint64_t swab(uint64_t x) { return swab64(x); }
+template<> INLINE int16_t swab(int16_t x) { return static_cast<int16_t>(swab16(static_cast<uint16_t>(x))); }
+template<> INLINE int32_t swab(int32_t x) { return static_cast<int32_t>(swab32(static_cast<uint32_t>(x))); }
+template<> INLINE int64_t swab(int64_t x) { return static_cast<int64_t>(swab64(static_cast<uint64_t>(x))); }
+template<> INLINE float swab(float x) { return swab_float(x); }
+
+/// Type generic conversion from CPU byte order to big-endian byte order.
+template<typename T>
+INLINE T cpu_to_be(T x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab(x) : x;
+}
+
+/// Type generic conversion from CPU byte-order to little-endian.
+template<typename T>
+INLINE T cpu_to_le(T x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab(x) : x;
+}
+
+/// Type generic conversion from big endian byte-order to CPU byte order.
+template<typename T>
+INLINE T be_to_cpu(T x)
+{
+ return cpu_to_be(x);
+}
+
+/// Type generic conversion from little-endian byte order to CPU byte order.
+template<typename T>
+INLINE T le_to_cpu(T x)
+{
+ return cpu_to_le(x);
+}
+
+/// Type generic conversion from network byte order to host byte order.
+template<typename T>
+INLINE T net_to_host(T x)
+{
+ return be_to_cpu(x);
+}
+
+/// Type generic conversion from host byte order to network byte order.
+template<typename T>
+INLINE T host_to_net(T x)
+{
+ return net_to_host(x);
+}
+
+#endif /* __cplusplus */
+
+#endif /* MWARE_BYTEORDER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Giovanni Bajo
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ * This module permits to create hunks for the functions that must be executed through
+ * RPC commands. For instance, given this code:
+ *
+ * \code
+ * ResultCode cmd_add(long a, long b, long* result);
+ * DECLARE_COMMAND_HUNK(add, (long)(long)(NIL), (long)(NIL));
+ * // ^ parameters ^ return values
+ * \endcode
+ *
+ * The macro is expanded to:
+ *
+ * \code
+ * ResultCode cmd_add_hunk(params argv[], params results[])
+ * {
+ * return cmd_add(argv[0].l, argv[1].l, &results[0].l);
+ * }
+ *
+ * const struct CmdTemplate cmd_add_template =
+ * {
+ * "add", "dd", "d", cmd_add_hunk
+ * };
+ * \endcode
+ *
+ * which is all the boilerplate needed to make the function ready for the RPC.
+ * The implementation uses the Boost Preprocessor Library (part of the Boost
+ * library, available at http://www.boost.org). The version we developed the
+ * code with is 1.31.
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ * \brief Preprocessor magic to create hunks for the commands executed from the parser
+ *
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2006/06/01 12:27:39 marco
+ *#* Added utilities for protocols
+ *#*
+ *#* Revision 1.8 2005/01/12 20:06:31 rasky
+ *#* enum ResultCode è ora un typedef
+ *#*
+ *#* Revision 1.7 2004/12/14 15:10:53 user1
+ *#* Bernardo e Francesco: Assegnazione di un codice di ritorno ai processi
+ *#*
+ *#* Revision 1.6 2004/12/02 17:43:15 rasky
+ *#* Aggiunta la possibilità di settare le flag dei comandi con la nuova macro DECLARE_CMD_HUNK_FLAGS (altrimenti, il default è zero)
+ *#*
+ *#* Revision 1.5 2004/10/16 13:20:15 rasky
+ *#* Aggiunto supporto per alias di uno stesso comando
+ *#*
+ *#* Revision 1.4 2004/08/25 14:17:10 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.3 2004/07/31 22:00:07 rasky
+ *#* Fixata una dipendenza
+ *#*
+ *#* Revision 1.2 2004/07/31 14:32:58 rasky
+ *#* args e results possono overlapparsi sempre grazie ai thunk generati: eliminati i due array separati per risparmiare memoria
+ *#*
+ *#* Revision 1.1 2004/05/22 16:29:16 rasky
+ *#* Generazione degli hunk dei comandi RPC tramite preprocessore
+ *#*
+ *#*/
+
+#ifndef CMD_HUNK_H
+#define CMD_HUNK_H
+
+#include "parser.h"
+
+// Bring in the Boost Preprocess Library
+#include <boost/preprocessor/library.hpp>
+
+#define HUNK_INDEX_FOR_NIL 0
+#define HUNK_INDEX_FOR_string 1
+#define HUNK_INDEX_FOR_long 2
+#define HUNK_ARRAY_LETTERS (3, (NIL, s, l))
+#define HUNK_ARRAY_STRINGS (3, ("", "s", "d"))
+
+// Transform int->l, float->f, etc.
+#define HUNK_TYPE_LETTER(s, _, type) \
+ BOOST_PP_CAT(HUNK_INDEX_FOR_, type) \
+ /**/
+
+#define HUNK_TRANSFORMER(_, array, elem) \
+ BOOST_PP_ARRAY_ELEM(elem, array) \
+ /**/
+
+#define HUNK_SEQ_TRANS_ARRAY(seq, array) \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TRANSFORMER, array, seq) \
+ /**/
+
+#define HUNK_PARAM(_, n, seq) \
+ args_results[n+1]. BOOST_PP_SEQ_ELEM(n, seq) \
+ /**/
+
+#define HUNK_RESULT(_, n, seq) \
+ &args_results[n]. BOOST_PP_SEQ_ELEM(n, seq) \
+ /**/
+
+#define HUNK_IDENTITY(_, dummy, x) x
+#define CMD_HUNK_TEMPLATE(func) cmd_##func###_template
+
+#define DECLARE_CMD_HUNK_2(func, name, param_types, result_types, flags) \
+ static ResultCode cmd_##name##_hunk(parms args_results[]) \
+ { \
+ return cmd_##func( \
+ BOOST_PP_ENUM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(param_types)), HUNK_PARAM, HUNK_SEQ_TRANS_ARRAY(param_types, HUNK_ARRAY_LETTERS)) \
+ BOOST_PP_COMMA_IF(BOOST_PP_AND(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(param_types)), BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(result_types)))) \
+ BOOST_PP_ENUM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(result_types)), HUNK_RESULT, HUNK_SEQ_TRANS_ARRAY(result_types, HUNK_ARRAY_LETTERS)) \
+ ); \
+ } \
+ const struct CmdTemplate CMD_HUNK_TEMPLATE(name) = { \
+ #name, \
+ BOOST_PP_SEQ_FOR_EACH(HUNK_IDENTITY, _, HUNK_SEQ_TRANS_ARRAY(param_types, HUNK_ARRAY_STRINGS)), \
+ BOOST_PP_SEQ_FOR_EACH(HUNK_IDENTITY, _, HUNK_SEQ_TRANS_ARRAY(result_types, HUNK_ARRAY_STRINGS)), \
+ cmd_##name##_hunk, \
+ flags \
+ } \
+ /**/
+
+#define DECLARE_CMD_HUNK(func, param_types, result_types) \
+ DECLARE_CMD_HUNK_2(func, func, \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
+ 0) \
+ /**/
+
+#define DECLARE_CMD_HUNK_NAME(func, name, param_types, result_types) \
+ DECLARE_CMD_HUNK_2(func, name, \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
+ 0) \
+ /**/
+
+#define DECLARE_CMD_HUNK_FLAGS(func, param_types, result_types, flags) \
+ DECLARE_CMD_HUNK_2(func, func, \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
+ BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
+ flags) \
+ /**/
+
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Events handling implementation
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+
+#include "event.h"
+
+void event_hook_ignore(UNUSED_ARG(Event *, e))
+{
+}
+
+#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
+void event_hook_signal(Event *e)
+{
+ sig_signal((e)->Ev.Sig.sig_proc, (e)->Ev.Sig.sig_bit);
+}
+#endif
+
+void event_hook_softint(Event *e)
+{
+ e->Ev.Int.func(e->Ev.Int.user_data);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Events handling
+ *
+ * This module implements a common system for executing
+ * a user defined action calling a hook function.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef KERN_EVENT_H
+#define KERN_EVENT_H
+
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+#if CONFIG_KERNEL
+ #include <config_kern.h>
+ #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
+ #include <kern/signal.h>
+ #endif
+
+ /* Forward decl */
+ struct Process;
+#endif
+
+
+/// User defined callback type
+typedef void (*Hook)(void *);
+
+typedef struct Event
+{
+ void (*action)(struct Event *);
+ union
+ {
+#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
+ struct
+ {
+ struct Process *sig_proc; /* Process to be signalled */
+ sigbit_t sig_bit; /* Signal to send */
+ } Sig;
+#endif
+ struct
+ {
+ Hook func; /* Pointer to softint hook */
+ void *user_data; /* Data to be passed back to user hook */
+ } Int;
+ } Ev;
+} Event;
+
+void event_hook_ignore(Event *event);
+void event_hook_signal(Event *event);
+void event_hook_softint(Event *event);
+
+/** Initialize the event \a e as a no-op */
+#define event_initNone(e) \
+ ((e)->action = event_hook_ignore)
+
+/** Same as event_initNone(), but returns the initialized event */
+INLINE Event event_createNone(void);
+INLINE Event event_createNone(void)
+{
+ Event e;
+ e.action = event_hook_ignore;
+ return e;
+}
+
+/** Initialize the event \a e with a software interrupt (call function \a f, with parameter \a u) */
+#define event_initSoftInt(e,f,u) \
+ ((e)->action = event_hook_softint,(e)->Ev.Int.func = (f), (e)->Ev.Int.user_data = (u))
+
+/** Same as event_initSoftInt(), but returns the initialized event */
+INLINE Event event_createSoftInt(Hook func, void *user_data)
+{
+ Event e;
+ e.action = event_hook_softint;
+ e.Ev.Int.func = func;
+ e.Ev.Int.user_data = user_data;
+ return e;
+}
+
+
+#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
+
+/** Initialize the event \a e with a signal (send signal \a s to process \a p) */
+#define event_initSignal(e,p,s) \
+ ((e)->action = event_hook_signal,(e)->Ev.Sig.sig_proc = (p), (e)->Ev.Sig.sig_bit = (s))
+
+/** Same as event_initSignal(), but returns the initialized event */
+INLINE Event event_createSignal(struct Process *proc, sigbit_t bit)
+{
+ Event e;
+ e.action = event_hook_signal;
+ e.Ev.Sig.sig_proc = proc;
+ e.Ev.Sig.sig_bit = bit;
+ return e;
+}
+
+#endif
+
+/** Trigger an event */
+INLINE void event_do(struct Event *e)
+{
+ e->action(e);
+}
+
+#endif /* KERN_EVENT_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief C++-like structured exception handling for C programs
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+#ifndef MWARE_EXCEPT_H
+#define MWARE_EXCEPT_H
+
+#include <cfg/debug.h>
+
+#include <setjmp.h>
+
+#define EXCEPT_CONTEXTS 8
+
+/**
+ * A stack of jump buffers used to record try sites
+ * so they can be reached from throw sites.
+ *
+ * The stack contains return points for each nested
+ * context. jmp_buf's are pushed into the stack at
+ * try points and popped out when the try block ends
+ * normally or when an exception is thrown.
+ */
+extern jmp_buf except_stack[EXCEPT_CONTEXTS];
+extern int except_top;
+
+#define PUSH_EXCEPT (ASSERT(except_top < EXCEPT_CONTEXTS), setjmp(except_stack[except_top++]))
+#define POP_EXCEPT (ASSERT(except_top > 0), --except_top)
+#define DO_EXCEPT (ASSERT(except_top > 0), longjmp(except_stack[--except_top], true))
+
+/**
+ * Jump buffer to use when throwing an exception or aborting an operation
+ *
+ * User code can throw exceptions like this:
+ *
+ * \code
+ * void a_function_throwing_exceptions(void)
+ * {
+ * if (some_error_condition)
+ * THROW;
+ * }
+ * \endcode
+ *
+ * Catching exceptions (brackets are optional):
+ *
+ * \code
+ * EXCEPT_DEFINE;
+ *
+ * void a_function_catching_an_exception(void)
+ * {
+ * TRY
+ * {
+ * printf("Entered try block\n");
+ * a_function_throwing_exceptions();
+ * printf("Survived execution of critical code\n");
+ * }
+ * CATCH
+ * {
+ * printf("Exception caught!\n");
+ * }
+ * CATCH_END
+ * }
+ * \endcode
+ *
+ * Simple syntax when you don't need to do anything when catching an excaption:
+ *
+ * \code
+ * TRY
+ * printf("Entered try block\n");
+ * a_function_throwing_exceptions();
+ * printf("Survived execution of critical code\n");
+ * TRY_END
+ * \endcode
+ *
+ * You also need to declare the exception stack once in
+ * your global declarations:
+ * \code
+ * EXCEPT_DEFINE;
+ * \endcode
+ */
+#define TRY if (PUSH_EXCEPT) { {
+#define TRY_END } POP_EXCEPT; }
+#define CATCH } POP_EXCEPT; } else {
+#define CATCH_END }
+#define THROW DO_EXCEPT
+
+
+#define EXCEPT_DEFINE \
+ jmp_buf except_stack[EXCEPT_CONTEXTS]; \
+ int except_top;
+
+#endif /* MWARE_EXCEPT_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief General pourpose FIFO buffer implemented with a ring buffer
+ *
+ * \li \c begin points to the first buffer element;
+ * \li \c end points to the last buffer element (unlike the STL convention);
+ * \li \c head points to the element to be extracted next;
+ * \li \c tail points to the location following the last insertion;
+ * \li when any of the pointers advances beyond \c end, it is reset
+ * back to \c begin.
+ *
+ * \code
+ *
+ * +-----------------------------------+
+ * | empty | valid data | empty |
+ * +-----------------------------------+
+ * ^ ^ ^ ^
+ * begin head tail end
+ *
+ * \endcode
+ *
+ * The buffer is EMPTY when \c head and \c tail point to the same location:
+ * \code head == tail \endcode
+ *
+ * The buffer is FULL when \c tail points to the location immediately
+ * after \c head:
+ * \code tail == head - 1 \endcode
+ *
+ * The buffer is also FULL when \c tail points to the last buffer
+ * location and head points to the first one:
+ * \code head == begin && tail == end \endcode
+ */
+
+#ifndef MWARE_FIFO_H
+#define MWARE_FIFO_H
+
+#include <cpu/types.h>
+#include <cpu/irq.h>
+#include <cfg/debug.h>
+
+typedef struct FIFOBuffer
+{
+ unsigned char * volatile head;
+ unsigned char * volatile tail;
+ unsigned char *begin;
+ unsigned char *end;
+} FIFOBuffer;
+
+
+#define ASSERT_VALID_FIFO(fifo) \
+ ATOMIC( \
+ ASSERT((fifo)->head >= (fifo)->begin); \
+ ASSERT((fifo)->head <= (fifo)->end); \
+ ASSERT((fifo)->tail >= (fifo)->begin); \
+ ASSERT((fifo)->tail <= (fifo)->end); \
+ )
+
+
+/**
+ * Check whether the fifo is empty
+ *
+ * \note Calling fifo_isempty() is safe while a concurrent
+ * execution context is calling fifo_push() or fifo_pop()
+ * only if the CPU can atomically update a pointer
+ * (which the AVR and other 8-bit processors can't do).
+ *
+ * \sa fifo_isempty_locked
+ */
+INLINE bool fifo_isempty(const FIFOBuffer *fb)
+{
+ //ASSERT_VALID_FIFO(fb);
+ return fb->head == fb->tail;
+}
+
+
+/**
+ * Check whether the fifo is full
+ *
+ * \note Calling fifo_isfull() is safe while a concurrent
+ * execution context is calling fifo_pop() and the
+ * CPU can update a pointer atomically.
+ * It is NOT safe when the other context calls
+ * fifo_push().
+ * This limitation is not usually problematic in a
+ * consumer/producer scenario because the
+ * fifo_isfull() and fifo_push() are usually called
+ * in the producer context.
+ */
+INLINE bool fifo_isfull(const FIFOBuffer *fb)
+{
+ //ASSERT_VALID_FIFO(fb);
+ return
+ ((fb->head == fb->begin) && (fb->tail == fb->end))
+ || (fb->tail == fb->head - 1);
+}
+
+
+/**
+ * Push a character on the fifo buffer.
+ *
+ * \note Calling \c fifo_push() on a full buffer is undefined.
+ * The caller must make sure the buffer has at least
+ * one free slot before calling this function.
+ *
+ * \note It is safe to call fifo_pop() and fifo_push() from
+ * concurrent contexts, unless the CPU can't update
+ * a pointer atomically (which the AVR and other 8-bit
+ * processors can't do).
+ *
+ * \sa fifo_push_locked
+ */
+INLINE void fifo_push(FIFOBuffer *fb, unsigned char c)
+{
+#ifdef __MWERKS__
+#pragma interrupt called
+#endif
+ //ASSERT_VALID_FIFO(fb);
+
+ /* Write at tail position */
+ *(fb->tail) = c;
+
+ if (UNLIKELY(fb->tail == fb->end))
+ /* wrap tail around */
+ fb->tail = fb->begin;
+ else
+ /* Move tail forward */
+ fb->tail++;
+}
+
+
+/**
+ * Pop a character from the fifo buffer.
+ *
+ * \note Calling \c fifo_pop() on an empty buffer is undefined.
+ * The caller must make sure the buffer contains at least
+ * one character before calling this function.
+ *
+ * \note It is safe to call fifo_pop() and fifo_push() from
+ * concurrent contexts.
+ */
+INLINE unsigned char fifo_pop(FIFOBuffer *fb)
+{
+#ifdef __MWERKS__
+#pragma interrupt called
+#endif
+ //ASSERT_VALID_FIFO(fb);
+
+ if (UNLIKELY(fb->head == fb->end))
+ {
+ /* wrap head around */
+ fb->head = fb->begin;
+ return *(fb->end);
+ }
+ else
+ /* move head forward */
+ return *(fb->head++);
+}
+
+
+/**
+ * Make the fifo empty, discarding all its current contents.
+ */
+INLINE void fifo_flush(FIFOBuffer *fb)
+{
+ //ASSERT_VALID_FIFO(fb);
+ fb->head = fb->tail;
+}
+
+
+#if CPU_REG_BITS >= CPU_BITS_PER_PTR
+
+ /*
+ * 16/32bit CPUs that can update a pointer with a single write
+ * operation, no need to disable interrupts.
+ */
+ #define fifo_isempty_locked(fb) fifo_isempty((fb))
+ #define fifo_push_locked(fb, c) fifo_push((fb), (c))
+ #define fifo_pop_locked(fb) fifo_pop((fb))
+ #define fifo_flush_locked(fb) fifo_flush((fb))
+
+#else /* CPU_REG_BITS < CPU_BITS_PER_PTR */
+
+ /**
+ * Similar to fifo_isempty(), but with stronger guarantees for
+ * concurrent access between user and interrupt code.
+ *
+ * \note This is actually only needed for 8-bit processors.
+ *
+ * \sa fifo_isempty()
+ */
+ INLINE bool fifo_isempty_locked(const FIFOBuffer *fb)
+ {
+ bool result;
+ ATOMIC(result = fifo_isempty(fb));
+ return result;
+ }
+
+
+ /**
+ * Similar to fifo_push(), but with stronger guarantees for
+ * concurrent access between user and interrupt code.
+ *
+ * \note This is actually only needed for 8-bit processors.
+ *
+ * \sa fifo_push()
+ */
+ INLINE void fifo_push_locked(FIFOBuffer *fb, unsigned char c)
+ {
+ ATOMIC(fifo_push(fb, c));
+ }
+
+ /* Probably not really needed, but hard to prove. */
+ INLINE unsigned char fifo_pop_locked(FIFOBuffer *fb)
+ {
+ unsigned char c;
+ ATOMIC(c = fifo_pop(fb));
+ return c;
+ }
+
+ /**
+ * Similar to fifo_flush(), but with stronger guarantees for
+ * concurrent access between user and interrupt code.
+ *
+ * \note This is actually only needed for 8-bit processors.
+ *
+ * \sa fifo_flush()
+ */
+ INLINE void fifo_flush_locked(FIFOBuffer *fb)
+ {
+ ATOMIC(fifo_flush(fb));
+ }
+
+#endif /* CPU_REG_BITS < BITS_PER_PTR */
+
+
+/**
+ * Thread safe version of fifo_isfull()
+ */
+INLINE bool fifo_isfull_locked(const FIFOBuffer *_fb)
+{
+ bool result;
+ ATOMIC(result = fifo_isfull(_fb));
+ return result;
+}
+
+
+/**
+ * FIFO Initialization.
+ */
+INLINE void fifo_init(FIFOBuffer *fb, unsigned char *buf, size_t size)
+{
+ /* FIFO buffers have a known bug with 1-byte buffers. */
+ ASSERT(size > 1);
+
+ fb->head = fb->tail = fb->begin = buf;
+ fb->end = buf + size - 1;
+}
+
+
+#if 0
+
+/*
+ * UNTESTED: if uncommented, to be moved in fifobuf.c
+ */
+void fifo_pushblock(FIFOBuffer *fb, unsigned char *block, size_t len)
+{
+ size_t freelen;
+
+ /* Se c'e' spazio da tail alla fine del buffer */
+ if (fb->tail >= fb->head)
+ {
+ freelen = fb->end - fb->tail + 1;
+
+ /* C'e' abbastanza spazio per scrivere tutto il blocco? */
+ if (freelen < len)
+ {
+ /* Scrivi quello che entra fino alla fine del buffer */
+ memcpy(fb->tail, block, freelen);
+ block += freelen;
+ len -= freelen;
+ fb->tail = fb->begin;
+ }
+ else
+ {
+ /* Scrivi tutto il blocco */
+ memcpy(fb->tail, block, len);
+ fb->tail += len;
+ return;
+ }
+ }
+
+ for(;;)
+ {
+ while (!(freelen = fb->head - fb->tail - 1))
+ Delay(FIFO_POLLDELAY);
+
+ /* C'e' abbastanza spazio per scrivere tutto il blocco? */
+ if (freelen < len)
+ {
+ /* Scrivi quello che entra fino alla fine del buffer */
+ memcpy(fb->tail, block, freelen);
+ block += freelen;
+ len -= freelen;
+ fb->tail += freelen;
+ }
+ else
+ {
+ /* Scrivi tutto il blocco */
+ memcpy(fb->tail, block, len);
+ fb->tail += len;
+ return;
+ }
+ }
+}
+#endif
+
+#endif /* MWARE_FIFO_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Basic "printf", "sprintf" and "fprintf" formatter.
+ *
+ * This module is 100% reentrant and can be adapted to user-defined routines
+ * that needs formatters with special properties like different output
+ * channels or new format specifiers.
+ *
+ * To reduce size in applications not using real numbers or long integers
+ * the formatter may be compiled to exclude certain parts. This is
+ * controlled by giving a -D option a compilation time:
+ *
+ * \code
+ * -D CONFIG_PRINTF=PRINTF_FULL Full ANSI printf formatter
+ * -D CONFIG_PRINTF=PRINTF_NOFLOAT Exclude support for floats
+ * -D CONFIG_PRINTF=PRINTF_REDUCED Simplified formatter (see below)
+ * -D CONFIG_PRINTF=PRINTF_NOMODIFIERS Exclude 'l' and 'h' modifiers in reduced version
+ * -D CONFIG_PRINTF=PRINTF_DISABLED No formatter at all
+ * \endcode
+ *
+ * Code size on AVR4 with GCC 3.4.1 (-O2):
+ * PRINTF_FULL 2912byte (0xB60)
+ * PRINTF_NOFLOAT 1684byte (0x694)
+ * PRINTF_REDUCED 924byte (0x39C)
+ * PRINTF_NOMODIFIERS 416byte (0x1A0)
+ *
+ * Code/data size in words on DSP56K with CodeWarrior 6.0:
+ * PRINTF_FULL 1493/45
+ * PRINTF_NOFLOAT 795/45
+ * PRINTF_REDUCED 482/0
+ * PRINTF_NOMODIFIERS 301/0
+ *
+ * The reduced version of formatter is suitable when program size is critical
+ * rather than formatting power. This routine uses less than 20 bytes of
+ * stack space which makes it practical even in systems with less than 256
+ * bytes of user RAM.
+ *
+ * The only formatting specifiers supported by the reduced formatter are:
+ * \code
+ * %% %c %s %d %o %x %X and %hd %ho %hx %hX %ld %lo %lx %lX
+ * \endcode
+ *
+ * It means that real variables are not supported as well as field
+ * width and precision arguments.
+ */
+
+
+#include "formatwr.h"
+#include <mware/pgm.h>
+#include <mware/hex.h>
+#include <cfg/debug.h> /* ASSERT */
+#include <appconfig.h> /* CONFIG_ macros */
+
+#ifndef CONFIG_PRINTF_N_FORMATTER
+ /** Disable the arcane %n formatter. */
+ #define CONFIG_PRINTF_N_FORMATTER 0
+#endif
+
+#ifndef CONFIG_PRINTF_OCTAL_FORMATTER
+ /** Disable the %o formatter. */
+ #define CONFIG_PRINTF_OCTAL_FORMATTER 0
+#endif
+
+/* True if we must keep a count of the number of characters we print. */
+#define CONFIG_PRINTF_COUNT_CHARS (CONFIG_PRINTF_RETURN_COUNT || CONFIG_PRINTF_N_FORMATTER)
+
+#if CONFIG_PRINTF
+
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
+ #include <float.h>
+
+ /* Maximum precision for floating point values */
+ typedef long double max_float_t;
+
+ /*bernie: save some memory, who cares about floats with lots of decimals? */
+ #define FRMWRI_BUFSIZE 134
+ #warning 134 is too much, the code must be fixed to have a lower precision limit
+#else
+ /*
+ * Conservative estimate. Should be (probably) 12 (which is the size necessary
+ * to represent (2^32-1) in octal plus the sign bit.
+ */
+ #define FRMWRI_BUFSIZE 16
+#endif
+
+/* Probably useful for fancy microcontrollers such as the PIC, nobody knows. */
+#ifndef MEM_ATTRIBUTE
+#define MEM_ATTRIBUTE
+#endif
+
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
+ #define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
+#else
+ #define IS_SHORT (sizeof(int) == 2)
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
+
+
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
+
+static char *float_conversion(MEM_ATTRIBUTE max_float_t value,
+ MEM_ATTRIBUTE short nr_of_digits,
+ MEM_ATTRIBUTE char *buf,
+ MEM_ATTRIBUTE char format_flag,
+ MEM_ATTRIBUTE char g_flag,
+ MEM_ATTRIBUTE bool alternate_flag)
+{
+ MEM_ATTRIBUTE char *cp;
+ MEM_ATTRIBUTE char *buf_pointer;
+ MEM_ATTRIBUTE short n, i, dec_point_pos, integral_10_log;
+
+ buf_pointer = buf;
+ integral_10_log = 0;
+
+ if (value >= 1)
+ {
+ while (value >= 1e11) /* To speed up things a bit */
+ {
+ value /= 1e10;
+ integral_10_log += 10;
+ }
+ while (value >= 10)
+ {
+ value /= 10;
+ integral_10_log++;
+ }
+ }
+ else if (value) /* Not just 0.0 */
+ {
+ while (value <= 1e-10) /* To speed up things a bit */
+ {
+ value *= 1e10;
+ integral_10_log -= 10;
+ }
+ while (value < 1)
+ {
+ value *= 10;
+ integral_10_log--;
+ }
+ }
+ if (g_flag)
+ {
+ if (integral_10_log < nr_of_digits && integral_10_log >= -4)
+ {
+ format_flag = 0;
+ nr_of_digits -= integral_10_log;
+ }
+ nr_of_digits--;
+ if (alternate_flag)
+ /* %#G - No removal of trailing zeros */
+ g_flag = 0;
+ else
+ /* %G - Removal of trailing zeros */
+ alternate_flag = true;
+ }
+
+ /* %e or %E */
+ if (format_flag)
+ {
+ dec_point_pos = 0;
+ }
+ else
+ {
+ /* Less than one... */
+ if (integral_10_log < 0)
+ {
+ *buf_pointer++ = '0';
+ if ((n = nr_of_digits) || alternate_flag)
+ *buf_pointer++ = '.';
+ i = 0;
+ while (--i > integral_10_log && nr_of_digits)
+ {
+ *buf_pointer++ = '0';
+ nr_of_digits--;
+ }
+ if (integral_10_log < (-n - 1))
+ /* Nothing more to do */
+ goto CLEAN_UP;
+ dec_point_pos = 1;
+ }
+ else
+ {
+ dec_point_pos = - integral_10_log;
+ }
+ }
+
+ i = dec_point_pos;
+ while (i <= nr_of_digits )
+ {
+ value -= (max_float_t)(n = (short)value); /* n=Digit value=Remainder */
+ value *= 10; /* Prepare for next shot */
+ *buf_pointer++ = n + '0';
+ if ( ! i++ && (nr_of_digits || alternate_flag))
+ *buf_pointer++ = '.';
+ }
+
+ /* Rounding possible */
+ if (value >= 5)
+ {
+ n = 1; /* Carry */
+ cp = buf_pointer - 1;
+ do
+ {
+ if (*cp != '.')
+ {
+ if ( (*cp += n) == ('9' + 1) )
+ {
+ *cp = '0';
+ n = 1;
+ }
+ else
+ n = 0;
+ }
+ } while (cp-- > buf);
+ if (n)
+ {
+ /* %e or %E */
+ if (format_flag)
+ {
+ cp = buf_pointer;
+ while (cp > buf)
+ {
+ if (*(cp - 1) == '.')
+ {
+ *cp = *(cp - 2);
+ cp--;
+ }
+ else
+ *cp = *(cp - 1);
+ cp--;
+ }
+ integral_10_log++;
+ }
+ else
+ {
+ cp = ++buf_pointer;
+ while (cp > buf)
+ {
+ *cp = *(cp - 1);
+ cp--;
+ }
+ }
+ *buf = '1';
+ }
+ }
+
+CLEAN_UP:
+ /* %G - Remove trailing zeros */
+ if (g_flag)
+ {
+ while (*(buf_pointer - 1) == '0')
+ buf_pointer--;
+ if (*(buf_pointer - 1) == '.')
+ buf_pointer--;
+ }
+
+ /* %e or %E */
+ if (format_flag)
+ {
+ *buf_pointer++ = format_flag;
+ if (integral_10_log < 0)
+ {
+ *buf_pointer++ = '-';
+ integral_10_log = -integral_10_log;
+ }
+ else
+ *buf_pointer++ = '+';
+ n = 0;
+ buf_pointer +=10;
+ do
+ {
+ n++;
+ *buf_pointer++ = (integral_10_log % 10) + '0';
+ integral_10_log /= 10;
+ } while ( integral_10_log || n < 2 );
+ for ( i = n ; n > 0 ; n-- )
+ *(buf_pointer - 11 - i + n) = *(buf_pointer - n);
+ buf_pointer -= 10;
+ }
+ return (buf_pointer);
+}
+
+#endif /* CONFIG_PRINTF > PRINTF_NOFLOAT */
+
+/**
+ * This routine forms the core and entry of the formatter.
+ *
+ * The conversion performed conforms to the ANSI specification for "printf".
+ */
+int
+PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
+ void put_one_char(char, void *),
+ void *secret_pointer,
+ va_list ap)
+{
+#if CONFIG_PRINTF > PRINTF_REDUCED
+ MEM_ATTRIBUTE static char bad_conversion[] = "???";
+ MEM_ATTRIBUTE static char null_pointer[] = "<NULL>";
+
+ MEM_ATTRIBUTE int precision;
+ MEM_ATTRIBUTE int n;
+#if CONFIG_PRINTF_COUNT_CHARS
+ MEM_ATTRIBUTE int nr_of_chars;
+#endif
+ MEM_ATTRIBUTE int field_width;
+ MEM_ATTRIBUTE char format_flag;
+ enum PLUS_SPACE_FLAGS {
+ PSF_NONE, PSF_PLUS, PSF_MINUS
+ };
+ enum DIV_FACTOR {
+ DIV_DEC, DIV_HEX,
+#if CONFIG_PRINTF_OCTAL_FORMATTER
+ DIV_OCT,
+#endif
+ };
+ MEM_ATTRIBUTE struct {
+ enum PLUS_SPACE_FLAGS plus_space_flag : 2;
+#if CONFIG_PRINTF_OCTAL_FORMATTER
+ enum DIV_FACTOR div_factor : 2;
+#else
+ enum DIV_FACTOR div_factor : 1;
+#endif
+ bool left_adjust : 1;
+ bool l_L_modifier : 1;
+ bool h_modifier : 1;
+ bool alternate_flag : 1;
+ bool nonzero_value : 1;
+ bool zeropad : 1;
+#if CPU_HARVARD
+ bool progmem : 1;
+#endif
+ } flags;
+ MEM_ATTRIBUTE unsigned long ulong;
+
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
+ MEM_ATTRIBUTE max_float_t fvalue;
+#endif
+
+ MEM_ATTRIBUTE char *buf_pointer;
+ MEM_ATTRIBUTE char *ptr;
+ MEM_ATTRIBUTE const char *hex;
+ MEM_ATTRIBUTE char buf[FRMWRI_BUFSIZE];
+
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars = 0;
+#endif
+ for (;;) /* Until full format string read */
+ {
+ while ((format_flag = PGM_READ_CHAR(format++)) != '%') /* Until '%' or '\0' */
+ {
+ if (!format_flag)
+#if CONFIG_PRINTF_RETURN_COUNT
+ return (nr_of_chars);
+#else
+ return 0;
+#endif
+ put_one_char(format_flag, secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ }
+ if (PGM_READ_CHAR(format) == '%') /* %% prints as % */
+ {
+ format++;
+ put_one_char('%', secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ continue;
+ }
+
+ flags.left_adjust = false;
+ flags.alternate_flag = false;
+ flags.plus_space_flag = PSF_NONE;
+ flags.zeropad = false;
+#if CPU_HARVARD
+ flags.progmem = false;
+#endif
+ ptr = buf_pointer = &buf[0];
+ hex = HEX_tab;
+
+ /* check for leading '-', '+', ' ','#' or '0' flags */
+ for (;;)
+ {
+ switch (PGM_READ_CHAR(format))
+ {
+ case ' ':
+ if (flags.plus_space_flag)
+ goto NEXT_FLAG;
+ case '+':
+ flags.plus_space_flag = PSF_PLUS;
+ goto NEXT_FLAG;
+ case '-':
+ flags.left_adjust = true;
+ goto NEXT_FLAG;
+ case '#':
+ flags.alternate_flag = true;
+ goto NEXT_FLAG;
+ case '0':
+ flags.zeropad = true;
+ goto NEXT_FLAG;
+ }
+ break;
+NEXT_FLAG:
+ format++;
+ }
+
+ /* Optional field width (may be '*') */
+ if (PGM_READ_CHAR(format) == '*')
+ {
+ field_width = va_arg(ap, int);
+ if (field_width < 0)
+ {
+ field_width = -field_width;
+ flags.left_adjust = true;
+ }
+ format++;
+ }
+ else
+ {
+ field_width = 0;
+ while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
+ field_width = field_width * 10 + (PGM_READ_CHAR(format++) - '0');
+ }
+
+ if (flags.left_adjust)
+ flags.zeropad = false;
+
+ /* Optional precision (or '*') */
+ if (PGM_READ_CHAR(format) == '.')
+ {
+ if (PGM_READ_CHAR(++format) == '*')
+ {
+ precision = va_arg(ap, int);
+ format++;
+ }
+ else
+ {
+ precision = 0;
+ while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
+ precision = precision * 10 + (PGM_READ_CHAR(format++) - '0');
+ }
+ }
+ else
+ precision = -1;
+
+ /* At this point, "left_adjust" is nonzero if there was
+ * a sign, "zeropad" is 1 if there was a leading zero
+ * and 0 otherwise, "field_width" and "precision"
+ * contain numbers corresponding to the digit strings
+ * before and after the decimal point, respectively,
+ * and "plus_space_flag" is either 0 (no flag) or
+ * contains a plus or space character. If there was no
+ * decimal point, "precision" will be -1.
+ */
+
+ flags.l_L_modifier = false;
+ flags.h_modifier = false;
+
+ /* Optional 'l','L','z' or 'h' modifier? */
+ switch (PGM_READ_CHAR(format))
+ {
+ case 'l':
+ case 'L':
+ case 'z':
+ flags.l_L_modifier = true;
+ format++;
+ break;
+ case 'h':
+ flags.h_modifier = true;
+ format++;
+ break;
+ }
+
+ /*
+ * At exit from the following switch, we will emit
+ * the characters starting at "buf_pointer" and
+ * ending at "ptr"-1
+ */
+ switch (format_flag = PGM_READ_CHAR(format++))
+ {
+#if CONFIG_PRINTF_N_FORMATTER
+ case 'n':
+ if (sizeof(short) != sizeof(int))
+ {
+ if (sizeof(int) != sizeof(long))
+ {
+ if (h_modifier)
+ *va_arg(ap, short *) = nr_of_chars;
+ else if (flags.l_L_modifier)
+ *va_arg(ap, long *) = nr_of_chars;
+ else
+ *va_arg(ap, int *) = nr_of_chars;
+ }
+ else
+ {
+ if (h_modifier)
+ *va_arg(ap, short *) = nr_of_chars;
+ else
+ *va_arg(ap, int *) = nr_of_chars;
+ }
+ }
+ else
+ {
+ if (flags.l_L_modifier)
+ *va_arg(ap, long *) = nr_of_chars;
+ else
+ *va_arg(ap, int *) = nr_of_chars;
+ }
+ continue;
+#endif
+ case 'c':
+ buf[0] = va_arg(ap, int);
+ ptr++;
+ break;
+
+ /* Custom formatter for strings in program memory. */
+ case 'S':
+#if CPU_HARVARD
+ flags.progmem = true;
+#endif
+ /* Fall trough */
+
+ case 's':
+ if ( !(buf_pointer = va_arg(ap, char *)) )
+ buf_pointer = null_pointer;
+ if (precision < 0)
+ precision = 10000;
+
+ /*
+ * Move `ptr' to the last character of the
+ * string that will be actually printed.
+ */
+ ptr = buf_pointer;
+#if CPU_HARVARD
+ if (flags.progmem)
+ {
+ for (n=0; pgm_read_char(ptr) && n < precision; n++)
+ ++ptr;
+ }
+ else
+#endif
+ for (n=0; *ptr && n < precision; n++)
+ ++ptr;
+ break;
+
+#if CONFIG_PRINTF_OCTAL_FORMATTER
+ case 'o':
+ if (flags.alternate_flag && !precision)
+ precision++;
+#endif
+ case 'x':
+ hex = hex_tab;
+ case 'u':
+ case 'p':
+ case 'X':
+ if (format_flag == 'p')
+#if defined(__AVR__) || defined(__I196__) /* 16bit pointers */
+ ulong = (unsigned long)(unsigned short)va_arg(ap, char *);
+#else /* 32bit pointers */
+ ulong = (unsigned long)va_arg(ap, char *);
+#endif /* 32bit pointers */
+ else if (flags.l_L_modifier)
+ ulong = va_arg(ap, unsigned long);
+ else if (flags.h_modifier)
+ ulong = (unsigned long)(unsigned short)va_arg(ap, unsigned int);
+ else
+ ulong = va_arg(ap, unsigned int);
+
+ flags.div_factor =
+#if CONFIG_PRINTF_OCTAL_FORMATTER
+ (format_flag == 'o') ? DIV_OCT :
+#endif
+ (format_flag == 'u') ? DIV_DEC : DIV_HEX;
+ flags.plus_space_flag = PSF_NONE;
+ goto INTEGRAL_CONVERSION;
+
+ case 'd':
+ case 'i':
+ if (flags.l_L_modifier)
+ ulong = (unsigned long)(long)va_arg(ap, long);
+ else
+ ulong = (unsigned long)(long)va_arg(ap, int);
+
+ /* Extract sign */
+ if ((signed long)ulong < 0)
+ {
+ flags.plus_space_flag = PSF_MINUS;
+ ulong = (unsigned long)(-((signed long)ulong));
+ }
+
+ flags.div_factor = DIV_DEC;
+
+ /* Now convert to digits */
+INTEGRAL_CONVERSION:
+ ptr = buf_pointer = &buf[FRMWRI_BUFSIZE - 1];
+ flags.nonzero_value = (ulong != 0);
+
+ /* No char if zero and zero precision */
+ if (precision != 0 || flags.nonzero_value)
+ {
+ switch (flags.div_factor)
+ {
+ case DIV_DEC:
+ do
+ *--buf_pointer = hex[ulong % 10];
+ while (ulong /= 10);
+ break;
+
+ case DIV_HEX:
+ do
+ *--buf_pointer = hex[ulong % 16];
+ while (ulong /= 16);
+ break;
+#if CONFIG_PRINTF_OCTAL_FORMATTER
+ case DIV_OCT:
+ do
+ *--buf_pointer = hex[ulong % 8];
+ while (ulong /= 8);
+ break;
+#endif
+ }
+ }
+
+ /* "precision" takes precedence */
+ if (precision < 0)
+ if (flags.zeropad)
+ precision = field_width - (flags.plus_space_flag != PSF_NONE);
+ while (precision > (int)(ptr - buf_pointer))
+ *--buf_pointer = '0';
+
+ if (flags.alternate_flag && flags.nonzero_value)
+ {
+ if (format_flag == 'x' || format_flag == 'X')
+ {
+ *--buf_pointer = format_flag;
+ *--buf_pointer = '0';
+ }
+#if CONFIG_PRINTF_OCTAL_FORMATTER
+ else if ((format_flag == 'o') && (*buf_pointer != '0'))
+ {
+ *--buf_pointer = '0';
+ }
+#endif
+ }
+ ASSERT(buf_pointer >= buf);
+ break;
+
+#if CONFIG_PRINTF > PRINTF_NOFLOAT
+ case 'g':
+ case 'G':
+ n = 1;
+ format_flag -= 2;
+ if (! precision)
+ {
+ precision = 1;
+ }
+ goto FLOATING_CONVERSION;
+ case 'f':
+ format_flag = 0;
+ case 'e':
+ case 'E':
+ n = 0;
+FLOATING_CONVERSION:
+ if (precision < 0)
+ {
+ precision = 6;
+ }
+
+ if (sizeof(double) != sizeof(max_float_t))
+ {
+ fvalue = flags.l_L_modifier ?
+ va_arg(ap,max_float_t) : va_arg(ap,double);
+ }
+ else
+ fvalue = va_arg(ap,max_float_t);
+
+ if (fvalue < 0)
+ {
+ flags.plus_space_flag = PSF_MINUS;
+ fvalue = -fvalue;
+ }
+ ptr = float_conversion (fvalue,
+ (short)precision,
+ buf_pointer += field_width,
+ format_flag,
+ (char)n,
+ flags.alternate_flag);
+ if (flags.zeropad)
+ {
+ precision = field_width - (flags.plus_space_flag != PSF_NONE);
+ while (precision > ptr - buf_pointer)
+ *--buf_pointer = '0';
+ }
+ break;
+
+#endif /* CONFIG_PRINTF <= PRINTF_NOFLOAT */
+
+ case '\0': /* Really bad place to find NUL in */
+ format--;
+
+ default:
+ /* Undefined conversion! */
+ ptr = buf_pointer = bad_conversion;
+ ptr += sizeof(bad_conversion) - 1;
+ break;
+
+ }
+
+ /*
+ * This part emittes the formatted string to "put_one_char".
+ */
+
+ /* If field_width == 0 then nothing should be written. */
+ precision = ptr - buf_pointer;
+
+ if ( precision > field_width)
+ {
+ n = 0;
+ }
+ else
+ {
+ n = field_width - precision - (flags.plus_space_flag != PSF_NONE);
+ }
+
+ /* emit any leading pad characters */
+ if (!flags.left_adjust)
+ while (--n >= 0)
+ {
+ put_one_char(' ', secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ }
+
+ /* emit flag characters (if any) */
+ if (flags.plus_space_flag)
+ {
+ put_one_char(flags.plus_space_flag == PSF_PLUS ? '+' : '-', secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ }
+
+#if CPU_HARVARD
+ if (flags.progmem)
+ {
+ while (--precision >= 0)
+ {
+ put_one_char(pgm_read_char(buf_pointer++), secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ }
+ }
+ else
+#endif /* CPU_HARVARD */
+ {
+ /* emit the string itself */
+ while (--precision >= 0)
+ {
+ put_one_char(*buf_pointer++, secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ }
+ }
+
+ /* emit trailing space characters */
+ if (flags.left_adjust)
+ while (--n >= 0)
+ {
+ put_one_char(' ', secret_pointer);
+#if CONFIG_PRINTF_COUNT_CHARS
+ nr_of_chars++;
+#endif
+ }
+ }
+
+#else /* PRINTF_REDUCED starts here */
+
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
+ bool l_modifier, h_modifier;
+ unsigned long u_val, div_val;
+#else
+ unsigned int u_val, div_val;
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
+
+ char format_flag;
+ unsigned int nr_of_chars, base;
+ char outChar;
+ char *ptr;
+
+ nr_of_chars = 0;
+ for (;;) /* Until full format string read */
+ {
+ while ((format_flag = PGM_READ_CHAR(format++)) != '%') /* Until '%' or '\0' */
+ {
+ if (!format_flag)
+ return (nr_of_chars);
+ put_one_char(format_flag, secret_pointer);
+ nr_of_chars++;
+ }
+
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
+ /*=================================*/
+ /* Optional 'l' or 'h' modifiers ? */
+ /*=================================*/
+ l_modifier = h_modifier = false;
+ switch (PGM_READ_CHAR(format))
+ {
+ case 'l':
+ l_modifier = true;
+ format++;
+ break;
+
+ case 'h':
+ h_modifier = true;
+ format++;
+ break;
+ }
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
+
+ switch (format_flag = PGM_READ_CHAR(format++))
+ {
+ case 'c':
+ format_flag = va_arg(ap, int);
+ default:
+ put_one_char(format_flag, secret_pointer);
+ nr_of_chars++;
+ continue;
+
+ case 's':
+ ptr = va_arg(ap, char *);
+ while ((format_flag = *ptr++))
+ {
+ put_one_char(format_flag, secret_pointer);
+ nr_of_chars++;
+ }
+ continue;
+
+ case 'o':
+ base = 8;
+ if (IS_SHORT)
+ div_val = 0x8000;
+ else
+ div_val = 0x40000000;
+ goto CONVERSION_LOOP;
+
+ case 'd':
+ base = 10;
+ if (IS_SHORT)
+ div_val = 10000;
+ else
+ div_val = 1000000000;
+ goto CONVERSION_LOOP;
+
+ case 'X':
+ case 'x':
+ base = 16;
+ if (IS_SHORT)
+ div_val = 0x1000;
+ else
+ div_val = 0x10000000;
+
+CONVERSION_LOOP:
+#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
+ if (h_modifier)
+ u_val = (format_flag == 'd') ?
+ (short)va_arg(ap, int) : (unsigned short)va_arg(ap, int);
+ else if (l_modifier)
+ u_val = va_arg(ap, long);
+ else
+ u_val = (format_flag == 'd') ?
+ va_arg(ap,int) : va_arg(ap,unsigned int);
+#else /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
+ u_val = va_arg(ap,int);
+#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
+ if (format_flag == 'd')
+ {
+ if (((int)u_val) < 0)
+ {
+ u_val = - u_val;
+ put_one_char('-', secret_pointer);
+ nr_of_chars++;
+ }
+ }
+ while (div_val > 1 && div_val > u_val)
+ {
+ div_val /= base;
+ }
+ do
+ {
+ outChar = (u_val / div_val) + '0';
+ if (outChar > '9')
+ {
+ if (format_flag == 'x')
+ outChar += 'a'-'9'-1;
+ else
+ outChar += 'A'-'9'-1;
+ }
+ put_one_char(outChar, secret_pointer);
+ nr_of_chars++;
+ u_val %= div_val;
+ div_val /= base;
+ }
+ while (div_val);
+
+ } /* end switch(format_flag...) */
+ }
+#endif /* CONFIG_PRINTF > PRINTF_REDUCED */
+}
+
+#endif /* CONFIG_PRINTF */
--- /dev/null
+/**
+ * \file
+ * <!--
+* This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Basic "printf", "sprintf" and "fprintf" formatter.
+ */
+
+#ifndef MWARE_FORMATWR_H
+#define MWARE_FORMATWR_H
+
+#include <stdarg.h> /* va_list */
+#include <appconfig.h>
+#include <cpu/attr.h> /* CPU_HARVARD */
+
+/**
+ * \name _formatted_write() configuration
+ * \{
+ */
+#define PRINTF_DISABLED 0
+#define PRINTF_NOMODIFIERS 1
+#define PRINTF_REDUCED 2
+#define PRINTF_NOFLOAT 3
+#define PRINTF_FULL 4
+/* \} */
+
+#ifndef CONFIG_PRINTF_RETURN_COUNT
+ /** Enable/disable _formatted_write return value */
+ #define CONFIG_PRINTF_RETURN_COUNT 1
+#endif
+
+int
+_formatted_write(
+ const char *format,
+ void put_char_func(char c, void *user_data),
+ void *user_data,
+ va_list ap);
+
+#if CPU_HARVARD
+ #include <mware/pgm.h>
+ int _formatted_write_P(
+ const char * PROGMEM format,
+ void put_char_func(char c, void *user_data),
+ void *user_data,
+ va_list ap);
+#endif /* CPU_HARVARD */
+
+#endif /* MWARE_FORMATWR_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Portable hash table implementation
+ *
+ * Some rationales of our choices in implementation:
+ *
+ * \li For embedded systems, it is vital to allocate the table in static memory. To do
+ * so, it is necessary to expose the \c HashNode and \c HashTable structures in the header file.
+ * Nevertheless, they should be used as opaque types (that is, the users should not
+ * access the structure fields directly).
+ *
+ * \li To statically allocate the structures, a macro is provided. With this macro, we
+ * are hiding completely \c HashNode to the user (who only manipulates \c HashTable). Without
+ * the macro, the user would have had to define both the \c HashNode and the \c HashTable
+ * manually, and pass both of them to \c ht_init() (which would have created the link between
+ * the two). Instead, the link is created with a literal initialization.
+ *
+ * \li The hash table is created as power of two to remove the divisions from the code.
+ * Of course, hash functions work at their best when the table size is a prime number.
+ * When calculating the modulus to convert the hash value to an index, the actual operation
+ * becomes a bitwise AND: this is fast, but truncates the value losing bits. Thus, the higher
+ * bits are first "merged" with the lower bits through some XOR operations (see the last line of
+ * \c calc_hash()).
+ *
+ * \li To minimize the memory occupation, there is no flag to set for the empty node. An
+ * empty node is recognized by its data pointer set to NULL. It is then invalid to store
+ * NULL as data pointer in the table.
+ *
+ * \li The visiting interface through iterators is implemented with pass-by-value semantic.
+ * While this is overkill for medium-to-stupid compilers, it is the best designed from an
+ * user point of view. Moreover, being totally inlined (defined completely in the header),
+ * even a stupid compiler should be able to perform basic optimizations on it.
+ * We thought about using a pass-by-pointer semantic but it was much more awful to use, and
+ * the compiler is then forced to spill everything to the stack (unless it is *very* smart).
+ *
+ * \li The current implementation allows to either store the key internally (that is, copy
+ * the key within the hash table) or keep it external (that is, a hook is used to extract
+ * the key from the data in the node). The former is more memory-hungry of course, as it
+ * allocated static space to store the key copies. The overhead to keep both methods at
+ * the same time is minimal:
+ * <ul>
+ * <li>There is a run-time check in node_get_key which is execute per each node visited.</li>
+ * <li>Theoretically, there is no memory overhead. In practice, there were no
+ * flags in \c struct HashTable till now, so we had to add a first bit flag, but the
+ * overhead will disappear if a second flag is added for a different reason later.</li>
+ * <li>There is a little interface overhead, since we have two different versions of
+ * \c ht_insert(), one with the key passed as parameter and one without, but in
+ * the common case (external keys) both can be used.</li>
+ * </ul>
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.8 2007/02/06 16:05:01 asterix
+ *#* Replaced ROTATE_* with ROT* defined in macros.h
+ *#*
+ *#* Revision 1.7 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2006/06/01 12:27:39 marco
+ *#* Added utilities for protocols
+ *#*
+ *#*/
+
+#include "hashtable.h"
+#include <cfg/debug.h>
+#include <cfg/compiler.h>
+#include <cfg/macros.h> //ROTL(), ROTR();
+
+#include <string.h>
+
+
+
+typedef const void** HashNodePtr;
+#define NODE_EMPTY(node) (!*(node))
+#define HT_HAS_INTERNAL_KEY(ht) (CONFIG_HT_OPTIONAL_INTERNAL_KEY && ht->flags.key_internal)
+
+/** For hash tables with internal keys, compute the pointer to the internal key for a given \a node. */
+INLINE uint8_t *key_internal_get_ptr(struct HashTable *ht, HashNodePtr node)
+{
+ uint8_t* key_buf = ht->key_data.mem;
+ size_t index;
+
+ // Compute the index of the node and use it to move within the whole key buffer
+ index = node - &ht->mem[0];
+ ASSERT(index < (size_t)(1 << ht->max_elts_log2));
+ key_buf += index * (INTERNAL_KEY_MAX_LENGTH + 1);
+
+ return key_buf;
+}
+
+
+INLINE void node_get_key(struct HashTable* ht, HashNodePtr node, const void** key, uint8_t* key_length)
+{
+ if (HT_HAS_INTERNAL_KEY(ht))
+ {
+ uint8_t* k = key_internal_get_ptr(ht, node);
+
+ // Key has its length stored in the first byte
+ *key_length = *k++;
+ *key = k;
+ }
+ else
+ *key = ht->key_data.hook(*node, key_length);
+}
+
+
+INLINE bool node_key_match(struct HashTable* ht, HashNodePtr node, const void* key, uint8_t key_length)
+{
+ const void* key2;
+ uint8_t key2_length;
+
+ node_get_key(ht, node, &key2, &key2_length);
+
+ return (key_length == key2_length && memcmp(key, key2, key_length) == 0);
+}
+
+
+static uint16_t calc_hash(const void* _key, uint8_t key_length)
+{
+ const char* key = (const char*)_key;
+ uint16_t hash = key_length;
+ int i;
+ int len = (int)key_length;
+
+ for (i = 0; i < len; ++i)
+ hash = ROTL(hash, 4) ^ key[i];
+
+ return hash ^ (hash >> 6) ^ (hash >> 13);
+}
+
+
+static HashNodePtr perform_lookup(struct HashTable* ht,
+ const void* key, uint8_t key_length)
+{
+ uint16_t hash = calc_hash(key, key_length);
+ uint16_t mask = ((1 << ht->max_elts_log2) - 1);
+ uint16_t index = hash & mask;
+ uint16_t first_index = index;
+ uint16_t step;
+ HashNodePtr node;
+
+ // Fast-path optimization: we check immediately if the current node
+ // is the one we were looking for, so we save the computation of the
+ // increment step in the common case.
+ node = &ht->mem[index];
+ if (NODE_EMPTY(node)
+ || node_key_match(ht, node, key, key_length))
+ return node;
+
+ // Increment while going through the hash table in case of collision.
+ // This implements the double-hash technique: we use the higher part
+ // of the hash as a step increment instead of just going to the next
+ // element, to minimize the collisions.
+ // Notice that the number must be odd to be sure that the whole table
+ // is traversed. Actually MCD(table_size, step) must be 1, but
+ // table_size is always a power of 2, so we just ensure that step is
+ // never a multiple of 2.
+ step = (ROTR(hash, ht->max_elts_log2) & mask) | 1;
+
+ do
+ {
+ index += step;
+ index &= mask;
+
+ node = &ht->mem[index];
+ if (NODE_EMPTY(node)
+ || node_key_match(ht, node, key, key_length))
+ return node;
+
+ // The check is done after the key compare. This actually causes
+ // one more compare in the case the table is full (since the first
+ // element was compared at the very start, and then at the end),
+ // but it makes faster the common path where we enter this loop
+ // for the first time, and index will not match first_index for
+ // sure.
+ } while (index != first_index);
+
+ return NULL;
+}
+
+
+void ht_init(struct HashTable* ht)
+{
+ memset(ht->mem, 0, sizeof(ht->mem[0]) * (1 << ht->max_elts_log2));
+}
+
+
+static bool insert(struct HashTable* ht, const void* key, uint8_t key_length, const void* data)
+{
+ HashNodePtr node;
+
+ if (!data)
+ return false;
+
+ if (HT_HAS_INTERNAL_KEY(ht))
+ key_length = MIN(key_length, (uint8_t)INTERNAL_KEY_MAX_LENGTH);
+
+ node = perform_lookup(ht, key, key_length);
+ if (!node)
+ return false;
+
+ if (HT_HAS_INTERNAL_KEY(ht))
+ {
+ uint8_t* k = key_internal_get_ptr(ht, node);
+ *k++ = key_length;
+ memcpy(k, key, key_length);
+ }
+
+ *node = data;
+ return true;
+}
+
+
+bool ht_insert_with_key(struct HashTable* ht, const void* key, uint8_t key_length, const void* data)
+{
+#ifdef _DEBUG
+ if (!HT_HAS_INTERNAL_KEY(ht))
+ {
+ // Construct a fake node and use it to match the key
+ HashNodePtr node = &data;
+ if (!node_key_match(ht, node, key, key_length))
+ {
+ ASSERT2(0, "parameter key is different from the external key");
+ return false;
+ }
+ }
+#endif
+
+ return insert(ht, key, key_length, data);
+}
+
+
+bool ht_insert(struct HashTable* ht, const void* data)
+{
+ const void* key;
+ uint8_t key_length;
+
+#ifdef _DEBUG
+ if (HT_HAS_INTERNAL_KEY(ht))
+ {
+ ASSERT("parameter cannot be a hash table with internal keys - use ht_insert_with_key()"
+ && 0);
+ return false;
+ }
+#endif
+
+ key = ht->key_data.hook(data, &key_length);
+
+ return insert(ht, key, key_length, data);
+}
+
+
+const void* ht_find(struct HashTable* ht, const void* key, uint8_t key_length)
+{
+ HashNodePtr node;
+
+ if (HT_HAS_INTERNAL_KEY(ht))
+ key_length = MIN(key_length, (uint8_t)INTERNAL_KEY_MAX_LENGTH);
+
+ node = perform_lookup(ht, key, key_length);
+
+ if (!node || NODE_EMPTY(node))
+ return NULL;
+
+ return *node;
+}
+
+
+#if 0
+
+#include <stdlib.h>
+
+bool ht_test(void);
+
+static const void* test_get_key(const void* ptr, uint8_t* length)
+{
+ const char* s = ptr;
+ *length = strlen(s);
+ return s;
+}
+
+#define NUM_ELEMENTS 256
+DECLARE_HASHTABLE_STATIC(test1, 256, test_get_key);
+DECLARE_HASHTABLE_INTERNALKEY_STATIC(test2, 256);
+
+static char data[NUM_ELEMENTS][10];
+static char keydomain[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+static bool single_test(void)
+{
+ int i;
+
+ ht_init(&test1);
+ ht_init(&test2);
+
+ for (i=0;i<NUM_ELEMENTS;i++)
+ {
+ int k;
+ int klen;
+
+ do
+ {
+ klen = (rand() % 8) + 1;
+ for (k=0;k<klen;k++)
+ data[i][k] = keydomain[rand() % (sizeof(keydomain)-1)];
+ data[i][k]=0;
+ } while (ht_find_str(&test1, data[i]) != NULL);
+
+ ASSERT(ht_insert(&test1, data[i]));
+ ASSERT(ht_insert_str(&test2, data[i], data[i]));
+ }
+
+ for (i=0;i<NUM_ELEMENTS;i++)
+ {
+ char *found1, *found2;
+
+ found1 = (char*)ht_find_str(&test1, data[i]);
+ if (strcmp(found1, data[i]) != 0)
+ {
+ ASSERT(strcmp(found1,data[i]) == 0);
+ return false;
+ }
+
+ found2 = (char*)ht_find_str(&test2, data[i]);
+ if (strcmp(found2, data[i]) != 0)
+ {
+ ASSERT(strcmp(found2,data[i]) == 0);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static uint16_t rand_seeds[] = { 1, 42, 666, 0xDEAD, 0xBEEF, 0x1337, 0xB00B };
+
+bool ht_test(void)
+{
+ int i;
+
+ for (i=0;i<countof(rand_seeds);++i)
+ {
+ srand(rand_seeds[i]);
+ if (!single_test())
+ {
+ kprintf("ht_test failed\n");
+ return false;
+ }
+ }
+
+ kprintf("ht_test successful\n");
+ return true;
+}
+
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Portable hash table
+ *
+ * This file implements a portable hash table, with the following features:
+ *
+ * \li Open double-hashing. The maximum number of elements is fixed. The double hashing
+ * function improves recovery in case of collisions.
+ * \li Configurable size (which is clamped to a power of two)
+ * \li Visiting interface through iterator (returns the element in random order).
+ * \li The key is stored within the data and a hook is used to extract it. Optionally, it
+ * is possible to store a copy of the key within the hash table.
+ *
+ * Since the hashing is open, there is no way to remove elements from the table. Instead, a
+ * function is provided to clear the table completely.
+ *
+ * The data stored within the table must be a pointer. The NULL pointer is used as
+ * a marker for a free node, so it is invalid to store a NULL pointer in the table
+ * with \c ht_insert().
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.8 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.7 2006/06/01 12:27:39 marco
+ *#* Added utilities for protocols
+ *#*
+ *#*/
+
+#ifndef MWARE_HASHTABLE_H
+#define MWARE_HASHTABLE_H
+
+#include <cfg/compiler.h>
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+/**
+ * Enable/disable support to declare special hash tables which maintain a copy of
+ * the key internally instead of relying on the hook to extract it from the data.
+ */
+#define CONFIG_HT_OPTIONAL_INTERNAL_KEY 1
+
+/// Maximum length of the internal key (use (2^n)-1 for slight speedup)
+#define INTERNAL_KEY_MAX_LENGTH 15
+
+/**
+ * Hook to get the key from \a data, which is an element of the hash table. The
+ * key must be returned together with \a key_length (in words).
+ */
+typedef const void *(*hook_get_key)(const void *data, uint8_t *key_length);
+
+
+/**
+ * Hash table description
+ *
+ * \note This structures MUST NOT be accessed directly. Its definition is
+ * provided in the header file only for optimization purposes (see the rationale
+ * in hashtable.c).
+ *
+ * \note If new elements must be added to this list, please double check
+ * \c DECLARE_HASHTABLE, which requires the existing elements to be at the top.
+ */
+struct HashTable
+{
+ const void **mem; ///< Buckets of data
+ uint16_t max_elts_log2; ///< Log2 of the size of the table
+ struct {
+ bool key_internal : 1; ///< true if the key is copied internally
+ } flags;
+ union {
+ hook_get_key hook; ///< Hook to get the key
+ uint8_t *mem; ///< Pointer to the key memory
+ } key_data;
+};
+
+
+/// Iterator to walk the hash table
+typedef struct
+{
+ const void** pos;
+ const void** end;
+} HashIterator;
+
+
+/**
+ * Declare a hash table in the current scope
+ *
+ * \param name Variable name
+ * \param size Number of elements
+ * \param hook_gk Hook to be used to extract the key from the node
+ *
+ * \note The number of elements will be rounded down to the nearest
+ * power of two.
+ *
+ */
+#define DECLARE_HASHTABLE(name, size, hook_gk) \
+ static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
+ struct HashTable name = { name##_nodes, UINT32_LOG2(size), { false }, hook_gk }
+
+/** Exactly like \c DECLARE_HASHTABLE, but the variable will be declared as static. */
+#define DECLARE_HASHTABLE_STATIC(name, size, hook_gk) \
+ static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
+ static struct HashTable name = { name##_nodes, UINT32_LOG2(size), { false }, { hook_gk } }
+
+#if CONFIG_HT_OPTIONAL_INTERNAL_KEY
+ /** Declare a hash table with internal copies of the keys. This version does not
+ * require a hook, nor it requires the user to allocate static memory for the keys.
+ * It is mostly suggested for tables whose keys are computed on the fly and need
+ * to be stored somewhere.
+ */
+ #define DECLARE_HASHTABLE_INTERNALKEY(name, size) \
+ static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
+ static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
+ struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
+
+ /** Exactly like \c DECLARE_HASHTABLE_INTERNALKEY, but the variable will be declared as static. */
+ #define DECLARE_HASHTABLE_INTERNALKEY_STATIC(name, size) \
+ static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
+ static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
+ static struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
+#endif
+
+/**
+ * Initialize (and clear) a hash table in a memory buffer.
+ *
+ * \param ht Hash table declared with \c DECLARE_HASHTABLE
+ *
+ * \note This function must be called before using the hash table. Optionally,
+ * it can be called later in the program to clear the hash table,
+ * removing all its elements.
+ */
+void ht_init(struct HashTable* ht);
+
+/**
+ * Insert an element into the hash table
+ *
+ * \param ht Handle of the hash table
+ * \param data Data to be inserted into the table
+ * \return true if insertion was successful, false otherwise (table is full)
+ *
+ * \note The key for the element to insert is extract from the data with
+ * the hook. This means that this function cannot be called for hashtables
+ * with internal keys.
+ *
+ * \note If an element with the same key already exists in the table,
+ * it will be overwritten.
+ *
+ * \note It is not allowed to store NULL in the table. If you pass NULL as data,
+ * the function call will fail.
+ */
+bool ht_insert(struct HashTable* ht, const void* data);
+
+/**
+ * Insert an element into the hash table
+ *
+ * \param ht Handle of the hash table
+ * \param key Key of the element
+ * \param key_length Length of the key in characters
+ * \param data Data to be inserted into the table
+ * \return true if insertion was successful, false otherwise (table is full)
+ *
+ * \note If this function is called for hash table with external keys,
+ * the key provided must be match the key that would be extracted with the
+ * hook, otherwise the function will fail.
+ *
+ * \note If an element with the same key already exists in the table,
+ * it will be overwritten.
+ *
+ * \note It is not allowed to store NULL in the table. If you pass NULL as data,
+ * the function call will fail.
+ */
+bool ht_insert_with_key(struct HashTable* ht, const void* key, uint8_t key_length, const void* data);
+
+/**
+ * Find an element in the hash table
+ *
+ * \param ht Handle of the hash table
+ * \param key Key of the element
+ * \param key_length Length of the key in characters
+ * \return Data of the element, or NULL if no element was found for the given key.
+ */
+const void* ht_find(struct HashTable* ht, const void* key, uint8_t key_length);
+
+/** Similar to \c ht_insert_with_key() but \a key is an ASCIIZ string */
+#define ht_insert_str(ht, key, data) ht_insert_with_key(ht, key, strlen(key), data)
+
+/** Similar to \c ht_find() but \a key is an ASCIIZ string */
+#define ht_find_str(ht, key) ht_find(ht, key, strlen(key))
+
+/// Get an iterator to the begin of the hash table \a ht
+INLINE HashIterator ht_iter_begin(struct HashTable* ht)
+{
+ HashIterator h;
+
+ h.pos = &ht->mem[0];
+ h.end = &ht->mem[1 << ht->max_elts_log2];
+
+ while (h.pos != h.end && !*h.pos)
+ ++h.pos;
+
+ return h;
+}
+
+/**
+ * Get an iterator to the (exclusive) end of the hash table \a ht
+ *
+ * \note Like in STL, the end iterator is not a valid iterator (you
+ * cannot call \c ht_iter_get() on it), and it must be used only to
+ * detect if we reached the end of the iteration (through \c ht_iter_cmp()).
+ */
+INLINE HashIterator ht_iter_end(struct HashTable* ht)
+{
+ HashIterator h;
+
+ h.pos = h.end = &ht->mem[1 << ht->max_elts_log2];
+
+ return h;
+}
+
+/// Compare \a it1 and \a it2 for equality
+INLINE bool ht_iter_cmp(HashIterator it1, HashIterator it2)
+{
+ ASSERT(it1.end == it2.end);
+ return it1.pos == it2.pos;
+}
+
+/// Get the element within the hash table \a ht pointed by the iterator \a iter
+INLINE const void* ht_iter_get(HashIterator iter)
+{ return *iter.pos; }
+
+/** Return an iterator pointing to the element following \a h
+ *
+ * \note The order of the elements visited during the iteration is casual,
+ * and depends on the implementation.
+ *
+ */
+INLINE HashIterator ht_iter_next(HashIterator h)
+{
+ ++h.pos;
+ while (h.pos != h.end && !(*h.pos))
+ ++h.pos;
+
+ return h;
+}
+
+#endif /* MWARE_HASHTABLE_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Heap subsystem (public interface).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.9 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.8 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.7 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.6 2004/10/26 09:02:13 bernie
+ *#* heap_free(): Handle NULL pointers like free(), write documentation.
+ *#*
+ *#* Revision 1.5 2004/10/03 20:43:22 bernie
+ *#* Import changes from sc/firmware.
+ *#*
+ *#* Revision 1.1 2004/07/31 16:33:58 rasky
+ *#* Spostato lo heap da kern/ a mware/
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 17:27:00 bernie
+ *#* Import kern/ subdirectory.
+ *#*
+ *#*/
+
+#include "heap.h"
+#include <string.h> // memset()
+#include <cfg/macros.h> // IS_POW2()
+#include <cfg/debug.h> // ASSERT()
+
+/* NOTE: struct size must be a 2's power! */
+typedef struct _MemChunk
+{
+ struct _MemChunk *next;
+ size_t size;
+} MemChunk;
+
+STATIC_ASSERT(IS_POW2(sizeof(MemChunk)));
+
+#define FREE_FILL_CODE 0xDEAD
+#define ALLOC_FILL_CODE 0xBEEF
+
+void heap_init(struct Heap* h, void* memory, size_t size)
+{
+#ifdef _DEBUG
+ memset(memory, FREE_FILL_CODE, size);
+#endif
+
+ /* Initialize heap with a single big chunk */
+ h->FreeList = (MemChunk *)memory;
+ h->FreeList->next = NULL;
+ h->FreeList->size = size;
+}
+
+
+void *heap_allocmem(struct Heap* h, size_t size)
+{
+ MemChunk *chunk, *prev;
+
+ /* Round size up to the allocation granularity */
+ size = ROUND2(size, sizeof(MemChunk));
+
+ /* Handle allocations of 0 bytes */
+ if (!size)
+ size = sizeof(MemChunk);
+
+ /* Walk on the free list looking for any chunk big enough to
+ * fit the requested block size.
+ */
+ for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
+ chunk;
+ prev = chunk, chunk = chunk->next)
+ {
+ if (chunk->size >= size)
+ {
+ if (chunk->size == size)
+ {
+ /* Just remove this chunk from the free list */
+ prev->next = chunk->next;
+ #ifdef _DEBUG
+ memset(chunk, ALLOC_FILL_CODE, size);
+ #endif
+ return (void *)chunk;
+ }
+ else
+ {
+ /* Allocate from the END of an existing chunk */
+ chunk->size -= size;
+ #ifdef _DEBUG
+ memset((uint8_t *)chunk + chunk->size, ALLOC_FILL_CODE, size);
+ #endif
+ return (void *)((uint8_t *)chunk + chunk->size);
+ }
+ }
+ }
+
+ return NULL; /* fail */
+}
+
+
+void heap_freemem(struct Heap* h, void *mem, size_t size)
+{
+ MemChunk *prev;
+
+ ASSERT(mem);
+
+#ifdef _DEBUG
+ memset(mem, FREE_FILL_CODE, size);
+#endif
+
+ /* Round size up to the allocation granularity */
+ size = ROUND2(size, sizeof(MemChunk));
+
+ /* Handle allocations of 0 bytes */
+ if (!size)
+ size = sizeof(MemChunk);
+
+ /* Special case: first chunk in the free list */
+ ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList);
+ if (((uint8_t *)mem) < ((uint8_t *)h->FreeList))
+ {
+ /* Insert memory block before the current free list head */
+ prev = (MemChunk *)mem;
+ prev->next = h->FreeList;
+ prev->size = size;
+ h->FreeList = prev;
+ }
+ else /* Normal case: not the first chunk in the free list */
+ {
+ /*
+ * Walk on the free list. Stop at the insertion point (when mem
+ * is between prev and prev->next)
+ */
+ prev = h->FreeList;
+ while (prev->next < (MemChunk *)mem && prev->next)
+ prev = prev->next;
+
+ /* Make sure mem is not *within* prev */
+ ASSERT((uint8_t*)mem >= (uint8_t*)prev + prev->size);
+
+ /* Should it be merged with previous block? */
+ if (((uint8_t *)prev) + prev->size == ((uint8_t *)mem))
+ {
+ /* Yes */
+ prev->size += size;
+ }
+ else /* not merged with previous chunk */
+ {
+ MemChunk *curr = (MemChunk*)mem;
+
+ /* insert it after the previous node
+ * and move the 'prev' pointer forward
+ * for the following operations
+ */
+ curr->next = prev->next;
+ curr->size = size;
+ prev->next = curr;
+
+ /* Adjust for the following test */
+ prev = curr;
+ }
+ }
+
+ /* Also merge with next chunk? */
+ if (((uint8_t *)prev) + prev->size == ((uint8_t *)prev->next))
+ {
+ prev->size += prev->next->size;
+ prev->next = prev->next->next;
+
+ /* There should be only one merge opportunity, becuase we always merge on free */
+ ASSERT((uint8_t*)prev + prev->size != (uint8_t*)prev->next);
+ }
+}
+
+#if CONFIG_HEAP_MALLOC
+
+void *heap_malloc(struct Heap* h, size_t size)
+{
+ size_t *mem;
+
+ size += sizeof(size_t);
+ if ((mem = (size_t*)heap_allocmem(h, size)))
+ *mem++ = size;
+
+ return mem;
+}
+
+void *heap_calloc(struct Heap* h, size_t size)
+{
+ void *mem;
+
+ if ((mem = heap_malloc(h, size)))
+ memset(mem, 0, size);
+
+ return mem;
+}
+
+/**
+ * Free a block of memory, determining its size automatically.
+ *
+ * \param h Heap from which the block was allocated.
+ * \param mem Pointer to a block of memory previously allocated with
+ * either heap_malloc() or heap_calloc().
+ *
+ * \note If \a mem is a NULL pointer, no operation is performed.
+ *
+ * \note Freeing the same memory block twice has undefined behavior.
+ *
+ * \note This function works like the ANSI C free().
+ */
+void heap_free(struct Heap *h, void *mem)
+{
+ size_t *_mem = (size_t *)mem;
+
+ if (_mem)
+ {
+ --_mem;
+ heap_freemem(h, _mem, *_mem);
+ }
+}
+
+#endif /* CONFIG_HEAP_MALLOC */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Heap subsystem (public interface).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \todo Heap memory could be defined as an array of MemChunk, and used
+ * in this form also within the implementation. This would probably remove
+ * memory alignment problems, and also some aliasing issues.
+ *
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:27 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2005/11/27 23:36:19 bernie
+ *#* Use appconfig.h instead of cfg/config.h.
+ *#*
+ *#* Revision 1.5 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.4 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.3 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.2 2004/08/04 15:54:18 rasky
+ *#* Merge da SC: prima versione veramente funzionante
+ *#*
+ *#* Revision 1.1 2004/07/31 16:33:58 rasky
+ *#* Spostato lo heap da kern/ a mware/
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 17:27:00 bernie
+ *#* Import kern/ subdirectory.
+ *#*
+ *#*/
+
+#ifndef MWARE_HEAP_H
+#define MWARE_HEAP_H
+
+#include <cfg/compiler.h>
+#include <appconfig.h>
+
+struct _MemChunk;
+
+/// A heap
+struct Heap
+{
+ struct _MemChunk *FreeList; ///< Head of the free list
+};
+
+
+/// Initialize \a heap within the buffer pointed by \a memory which is of \a size bytes
+void heap_init(struct Heap* heap, void* memory, size_t size);
+
+/// Allocate a chunk of memory of \a size bytes from the heap
+void *heap_allocmem(struct Heap* heap, size_t size);
+
+/// Free a chunk of memory of \a size bytes from the heap
+void heap_freemem(struct Heap* heap, void *mem, size_t size);
+
+
+#define HNEW(heap, type) \
+ (type*)heap_allocmem(heap, sizeof(type))
+
+#define HNEWVEC(heap, type, nelem) \
+ (type*)heap_allocmem(heap, sizeof(type) * (nelem))
+
+#define HDELETE(heap, type, mem) \
+ heap_freemem(heap, mem, sizeof(type))
+
+#define HDELETEVEC(heap, type, nelem, mem) \
+ heap_freemem(heap, mem, sizeof(type) * (nelem))
+
+
+#if CONFIG_HEAP_MALLOC
+
+void *heap_malloc(struct Heap* heap, size_t size);
+void *heap_calloc(struct Heap* heap, size_t size);
+void heap_free(struct Heap* heap, void * mem);
+
+#endif
+
+#endif /* MWARE_HEAP_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Poor man's hex arrays (implementation).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+
+#include "hex.h"
+
+const char hex_tab[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+const char HEX_tab[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Poor man's hex arrays (implementation).
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#ifndef MWARE_HEX_H
+#define MWARE_HEX_H
+
+extern const char hex_tab[16];
+extern const char HEX_tab[16];
+
+#endif /* MWARE_HEX_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief General pourpose double-linked lists
+ */
+
+#ifndef MWARE_LIST_H
+#define MWARE_LIST_H
+
+#include <cfg/compiler.h> /* INLINE */
+#include <cfg/debug.h> /* ASSERT() */
+
+/**
+ * This structure represents a node for bidirectional lists.
+ *
+ * Data is usually appended to nodes by making them the first
+ * field of another struture, as a poor-man's form of inheritance.
+ */
+typedef struct _Node
+{
+ struct _Node *succ;
+ struct _Node *pred;
+} Node;
+
+/**
+ * Head of a doubly-linked list of \c Node structs.
+ *
+ * Lists must be initialized with LIST_INIT() prior to use.
+ *
+ * Nodes can be added and removed from either end of the list
+ * with O(1) performance. Iterating over these lists can be
+ * tricky: use the FOREACH_NODE() macro instead.
+ */
+typedef struct _List
+{
+ Node head;
+ Node tail;
+} List;
+
+/**
+ * Extended node for priority queues.
+ */
+typedef struct _PriNode
+{
+ Node link;
+ int pri;
+} PriNode;
+
+
+/**
+ * Template for a naked node in a list of \a T structures.
+ *
+ * To be used as data member in other structures:
+ *
+ * \code
+ * struct Foo
+ * {
+ * DECLARE_NODE_ANON(struct Foo)
+ * int a;
+ * float b;
+ * }
+ *
+ * DECLARE_LIST_TYPE(Foo);
+ *
+ * void foo(void)
+ * {
+ * static LIST_TYPE(Foo) foo_list;
+ * static Foo foo1, foo2;
+ * Foo *fp;
+ *
+ * LIST_INIT(&foo_list);
+ * ADDHEAD(&foo_list, &foo1);
+ * INSERT_BEFORE(&foo_list, &foo2);
+ * FOREACH_NODE(fp, &foo_list)
+ * fp->a = 10;
+ * }
+ *
+ * \endcode
+ */
+#define DECLARE_NODE_ANON(T) \
+ T *succ; T *pred;
+
+/** Declare a typesafe node for structures of type \a T. */
+#define DECLARE_NODE_TYPE(T) \
+ typedef struct T##Node { T *succ; T *pred; } T##Node
+
+/** Template for a list of \a T structures. */
+#define DECLARE_LIST_TYPE(T) \
+ DECLARE_NODE_TYPE(T); \
+ typedef struct T##List { \
+ T##Node head; \
+ T##Node tail; \
+ } T##List
+
+#define NODE_TYPE(T) T##Node
+#define LIST_TYPE(T) T##List
+
+/**
+ * Get a pointer to the first node in a list.
+ *
+ * If \a l is empty, result points to l->tail.
+ */
+#define LIST_HEAD(l) ((l)->head.succ)
+
+/**
+ * Get a pointer to the last node in a list.
+ *
+ * If \a l is empty, result points to l->head.
+ */
+#define LIST_TAIL(l) ((l)->tail.pred)
+
+// TODO: move in compiler.h
+#if COMPILER_TYPEOF
+ #define TYPEOF_OR_VOIDPTR(type) typeof(type)
+#else
+ #define TYPEOF_OR_VOIDPTR(type) void *
+#endif
+
+/**
+ * Iterate over all nodes in a list.
+ *
+ * This macro generates a "for" statement using the following parameters:
+ * \param n Node pointer to be used in each iteration.
+ * \param l Pointer to list.
+ */
+#define FOREACH_NODE(n, l) \
+ for( \
+ (n) = (TYPEOF_OR_VOIDPTR(n))LIST_HEAD(l); \
+ ((Node *)(n))->succ; \
+ (n) = (TYPEOF_OR_VOIDPTR(n))(((Node *)(n))->succ) \
+ )
+
+/**
+ * Iterate backwards over all nodes in a list.
+ *
+ * This macro generates a "for" statement using the following parameters:
+ * \param n Node pointer to be used in each iteration.
+ * \param l Pointer to list.
+ */
+#define REVERSE_FOREACH_NODE(n, l) \
+ for( \
+ (n) = (TYPEOF_OR_VOIDPTR(n))LIST_TAIL(l); \
+ ((Node *)(n))->pred; \
+ (n) = (TYPEOF_OR_VOIDPTR(n))(((Node *)(n))->pred) \
+ )
+
+/** Initialize a list. */
+#define LIST_INIT(l) \
+ do { \
+ (l)->head.succ = (TYPEOF_OR_VOIDPTR((l)->head.succ)) &(l)->tail; \
+ (l)->head.pred = NULL; \
+ (l)->tail.succ = NULL; \
+ (l)->tail.pred = (TYPEOF_OR_VOIDPTR((l)->tail.pred)) &(l)->head; \
+ } while (0)
+
+#ifdef _DEBUG
+ /** Make sure that a list is valid (it was initialized and is not corrupted). */
+ #define LIST_ASSERT_VALID(l) \
+ do { \
+ Node *n, *pred; \
+ ASSERT((l)->head.succ != NULL); \
+ ASSERT((l)->head.pred == NULL); \
+ ASSERT((l)->tail.succ == NULL); \
+ ASSERT((l)->tail.pred != NULL); \
+ pred = &(l)->head; \
+ FOREACH_NODE(n, l) \
+ { \
+ ASSERT(n->pred == pred); \
+ pred = n; \
+ } \
+ ASSERT(n == &(l)->tail); \
+ } while (0)
+
+ #define INVALIDATE_NODE(n) ((n)->succ = (n)->pred = NULL)
+#else
+ #define LIST_ASSERT_VALID(l) do {} while (0)
+ #define INVALIDATE_NODE(n) do {} while (0)
+#endif
+
+/** Add node to list head. */
+#define ADDHEAD(l,n) \
+ do { \
+ ASSERT(l); \
+ ASSERT(n); \
+ (n)->succ = (l)->head.succ; \
+ (n)->pred = (l)->head.succ->pred; \
+ (n)->succ->pred = (n); \
+ (n)->pred->succ = (n); \
+ } while (0)
+
+/** Add node to list tail. */
+#define ADDTAIL(l,n) \
+ do { \
+ ASSERT(l); \
+ ASSERT(n); \
+ (n)->succ = &(l)->tail; \
+ (n)->pred = (l)->tail.pred; \
+ (n)->pred->succ = (n); \
+ (l)->tail.pred = (n); \
+ } while (0)
+
+/**
+ * Insert node \a n before node \a ln.
+ *
+ * \note You can't pass in a list header as \a ln, but
+ * it is safe to pass list-\>head of an empty list.
+ */
+#define INSERT_BEFORE(n,ln) \
+ do { \
+ (n)->succ = (ln); \
+ (n)->pred = (ln)->pred; \
+ (ln)->pred->succ = (n); \
+ (ln)->pred = (n); \
+ } while (0)
+
+/**
+ * Remove \a n from whatever list it is in.
+ *
+ * \note Removing a node that has not previously been
+ * inserted into a list invokes undefined behavior.
+ */
+#define REMOVE(n) \
+ do { \
+ (n)->pred->succ = (n)->succ; \
+ (n)->succ->pred = (n)->pred; \
+ INVALIDATE_NODE(n); \
+ } while (0)
+
+/** Tell whether a list is empty. */
+#define LIST_EMPTY(l) ( (void *)((l)->head.succ) == (void *)(&(l)->tail) )
+
+/**
+ * Insert a priority node in a priority queue.
+ *
+ * The new node is inserted immediately before the
+ * first node with lower priority or appended to
+ * the tail if no such node exists.
+ */
+#define LIST_ENQUEUE(list, node) \
+ do { \
+ PriNode *ln; \
+ FOREACH_NODE(ln, (list)) \
+ if (ln->pri < (node)->pri) \
+ break; \
+ INSERT_BEFORE(&(node)->link, &ln->link); \
+ } while (0)
+
+
+/**
+ * Unlink a node from the head of the list \a l.
+ *
+ * \return Pointer to node, or NULL if the list was empty.
+ */
+INLINE Node *list_remHead(List *l)
+{
+ Node *n;
+
+ if (LIST_EMPTY(l))
+ return (Node *)0;
+
+ n = l->head.succ; /* Get first node. */
+ l->head.succ = n->succ; /* Link list head to second node. */
+ n->succ->pred = &l->head; /* Link second node to list head. */
+
+ INVALIDATE_NODE(n);
+ return n;
+}
+
+/**
+ * Unlink a node from the tail of the list \a l.
+ *
+ * \return Pointer to node, or NULL if the list was empty.
+ */
+INLINE Node *list_remTail(List *l)
+{
+ Node *n;
+
+ if (LIST_EMPTY(l))
+ return (Node *)0;
+
+ n = l->tail.pred; /* Get last node. */
+ l->tail.pred = n->pred; /* Link list tail to second last node. */
+ n->pred->succ = &l->tail; /* Link second last node to list tail. */
+
+ INVALIDATE_NODE(n);
+ return n;
+}
+
+#endif /* MWARE_LIST_H */
--- /dev/null
+#warning revise me!
+
+
+/**
+ * DECLARE_SMEAN(temperature, uint8_t, uint16_t);
+ * for (i = 0; i < TEMP_MEANS; ++i)
+ * SMEAN_ADD(temperature, adc_get(), TEMP_MEANS);
+ * printf("mean temperature = %d\n", SMEAN_GET(temperature));
+ */
+
+/**
+ * Instantiate a mean instance
+ */
+#define DECLARE_SMEAN(name, Type, SumType) \
+ struct { \
+ SumType sum; \
+ Type result; \
+ int count; \
+ } name = { 0, 0, 0 }
+
+/**
+ * Insert a new sample into the mean.
+ *
+ * \note \a mean and \a max_samples are evaluated multiple times
+ */
+#define SMEAN_ADD(mean, sample, max_samples) \
+ do { \
+ (mean).sum += (sample); \
+ if ((mean).count++ >= (max_samples)) \
+ { \
+ (mean).result = (mean).sum / (max_samples); \
+ (mean).sum = 0; \
+ (mean).count = 0; \
+ } \
+ } while (0)
+
+/**
+ * Return current mean value.
+ */
+#define SMEAN_GET(mean) ((mean).result)
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Messages for LCD.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/07/19 12:56:28 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.1 2005/03/01 23:31:02 bernie
+ *#* String table and localization stuff.
+ *#*
+ *#*/
+
+#include "msg.h"
+
+/**
+ * Array of pointers to localized strings. Should be filled
+ * by localization stuff, but not for now.
+ */
+const char *msg_strings[MSG_COUNT] = {
+ 0,
+ // TODO: add your strings here
+};
+
+/* Buffer for catalog file */
+/* char msg_buf[MSG_BUFSIZE]; */
+
+
+/* The following does not work (move string tables into the DMSG/CMSG segments)
+ * #pragma memory=dataseg(DMSG)
+ * #pragma memory=constseg(CMSG)
+ */
+
+
+/**
+ * Untranslated constant strings used more than once are
+ * grouped here to save ROM space.
+ */
+const char
+ str_empty[] = "";
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Definitions of constant string messages.
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.2 2006/02/10 11:30:37 bernie
+ *#* C++ fixes.
+ *#*
+ *#* Revision 1.1 2005/03/01 23:31:02 bernie
+ *#* String table and localization stuff.
+ *#*
+ *#*/
+#ifndef MWARE_MSG_H
+#define MWARE_MSG_H
+
+enum
+{
+ MSG_NULL,
+
+ // TODO: add your labels here.
+
+ MSG_COUNT
+};
+
+
+#define MSG_BUFSIZE 6144 /* FIXME: how much? */
+
+/* String tables */
+extern const char *msg_strings const [MSG_COUNT];
+/* extern char msg_buf[MSG_BUFSIZE]; */
+
+
+/* Macros to access translated messages */
+#define MSG(x) msg_strings[x]
+#define PTRMSG(x) ((x) < (const_iptr_t)256 ? msg_strings[(unsigned int)(x)] : (const char *)(x))
+
+
+#endif /* MWARE_MSG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Simple notifier for the observer/subject pattern (implementation)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "observer.h"
+#include <cpu/irq.h> // IRQ_DISABLE/IRQ_ENABLE
+
+
+void observer_SetEvent(Observer *observer, void (*event)(int event_id, void *param))
+{
+ observer->event = event;
+}
+
+void observer_InitSubject(Subject *subject)
+{
+ LIST_INIT(&subject->observers);
+}
+
+void observer_Subscribe(Subject *subject, Observer *observer)
+{
+ ATOMIC(ADDHEAD(&subject->observers, &observer->link));
+}
+
+void observer_Unsubscribe(UNUSED_ARG(Subject *,subject), Observer *observer)
+{
+ ATOMIC(REMOVE(&observer->link));
+}
+
+void observer_notify(Subject *subject, int event_id, void *param)
+{
+ Observer *observer;
+ cpuflags_t irqstate;
+ IRQ_SAVE_DISABLE(irqstate);
+
+ /*
+ * Run over list with protection against other
+ * threads, but re-enable irqs in callbacks.
+ */
+ FOREACH_NODE(observer, &subject->observers)
+ {
+ IRQ_RESTORE(irqstate);
+ observer->event(event_id, param);
+ IRQ_SAVE_DISABLE(irqstate);
+ }
+
+ IRQ_RESTORE(irqstate);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Simple notifier for the subject/observer pattern (interface)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+#ifndef MWARE_OBSERVER_H
+#define MWARE_OBSERVER_H
+
+#include <mware/list.h>
+
+/**
+ *
+ * Here's a simple example:
+ *
+ * \code
+ * Subject kbd_driver;
+ *
+ * Observer kbd_observer;
+ *
+ * void key_pressed(int event, void *_param)
+ * {
+ * char *param = (char *)_param;
+ *
+ * if (event == EVENT_KBD_PRESSED)
+ * printf("You pressed %c\n", *param);
+ * }
+ *
+ * void register_kbd_listener(void)
+ * {
+ * observer_SetEvent(&kbd_observer, key_pressed);
+ * observer_Subscribe(&kbd_driver, &kbd_observer);
+ * }
+ * \endcode
+ */
+typedef struct Observer
+{
+ Node link;
+ void (*event)(int event_id, void *param);
+} Observer;
+
+typedef struct Subject
+{
+ /// Subscribed observers.
+ List observers;
+
+} Subject;
+
+void observer_SetEvent(Observer *observer, void (*event)(int event_id, void *param));
+
+#define OBSERVER_INITIALIZER(callback) { { NULL, NULL }, callback }
+
+void observer_InitSubject(Subject *subject);
+
+/// Aggiunge un Observer all'insieme
+void observer_Subscribe(Subject *subject, Observer *observer);
+
+/// Rimuove un Observer dall'insieme
+void observer_Unsubscribe(Subject *subject, Observer *observer);
+
+/// per tutti gli elementi nel set notifica l'evento, chiamando la relativa
+/// funzione event
+void observer_notify(Subject *subject, int event_id, void *param);
+
+#endif /* MWARE_OBSERVER_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2006 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ * \brief Serial protocol parser and commands.
+ *
+ * This file contains the serial protocol parser and
+ * the definition of the protocol commands. Commands are defined
+ * in a "CmdTemplate" type array, containing:
+ * - the name of the command,
+ * - the arguments it expects to receive,
+ * - the output values,
+ * - the name of the function implementing the command.
+ *
+ * The arguments and results are passed to command function
+ * using an union: the element of the union to use for each
+ * argument is determined by format strings present in the
+ * CmdTemplate table.
+ */
+
+
+#include "parser.h"
+#include <drv/ser.h>
+
+#include <stdlib.h> // atol(), NULL
+#include <string.h> // strchr(), strcmp()
+
+#include <mware/hashtable.h>
+
+#include "appconfig.h"
+
+#define ARG_SEP_S " "
+#define ARG_SEP_C ' '
+
+#define MAX_COMMANDS_NUMBER 128 // 64
+
+/// Hashtable hook to extract the key from a command
+static const void* get_key_from_command(const void* cmd, uint8_t* length);
+
+/// Hashtable that handles the commands that can be executed
+DECLARE_HASHTABLE_STATIC(commands, MAX_COMMANDS_NUMBER, get_key_from_command);
+
+
+/**
+ * \brief Tokenize one word at a time from a text.
+ *
+ * This function is similar to strtok, but does not use any implicit
+ * context, nor it does modify the input buffer in any form.
+ * The word is returned as a STL-like [begin,end) range.
+ *
+ * To extract the first word, make both begin and end point at the
+ * start of the text, and call the function. Then, subsequent
+ * calls will return the following words (assuming the begin/end
+ * variable are not modified between calls).
+ *
+ * \param begin Will contain the index of the first character of the word
+ * \param end Will contain the index of the character after the last
+ * character of the word
+ *
+ * \return True if a word was extracted, false if we got to the end
+ * of the string without extracting any word.
+ */
+static bool get_word(const char **begin, const char **end)
+{
+ const char *cur = *end;
+
+ while ((*cur == ' ' || *cur == '\t') && *cur)
+ ++cur;
+
+ *begin = cur;
+
+ while ((*cur != ' ' && *cur != '\t') && *cur)
+ ++cur;
+
+ *end = cur;
+
+ return (*end != *begin);
+}
+
+
+/**
+ * \brief Command arguments parser.
+ *
+ * Using the format pointed by the argument fmt
+ * parses the input string filling the array argv
+ * with input parameters of the correct type.
+ *
+ * \param fmt Parameters format string.
+ * \param input Input string.
+ * \param argv Array filled with parameters.
+ *
+ * \return False in case of errors, otherwise true.
+ */
+static bool parseArgs(const char *fmt, const char *input, parms argv[])
+{
+ const char *begin = input, *end = input;
+
+ while (*fmt)
+ {
+ // Extract the argument
+ if (!get_word(&begin, &end))
+ return false;
+
+ switch (*fmt)
+ {
+ case 'd':
+ (*argv++).l = atol(begin);
+ break;
+
+ case 's':
+ (*argv++).s = begin;
+ break;
+
+ default:
+ ASSERT2(0, "Unknown format for argument");
+ return false;
+ }
+
+ ++fmt;
+ }
+
+ /* check if there are remaining args */
+ if (get_word(&begin, &end))
+ return false;
+
+ return true;
+}
+
+
+#ifdef UNUSED_CODE
+/**
+ * \brief Command result formatting and printing.
+ *
+ * Prints out on device fd the values contained
+ * in the array result, using the format specified
+ * in fmt.
+ *
+ * \param ser Serial handle.
+ * \param fmt Values format string.
+ * \param result Array containing result to be printed.
+ *
+ * \return -1 in case of errors, otherwise 0.
+ */
+static int printResult(struct Serial *ser, const char *fmt, parms result[])
+{
+ long n;
+ char repeat_cnt = 0;
+
+ while (*fmt)
+ {
+ if (*fmt >= '0' && *fmt <= '9')
+ {
+ /* Collect repeat count digit (left to right order) */
+ repeat_cnt = (repeat_cnt * 10) + (*fmt - '0');
+ }
+ else
+ {
+ /* Set default repeat cnt of 1 when not specified */
+ if (repeat_cnt == 0)
+ repeat_cnt = 1;
+
+ /* Loop repeat_cnt times */
+ do
+ {
+ switch (*fmt)
+ {
+ case 'd':
+ ser_printf(ser, ARG_SEP_S "%ld", (*result).l);
+ result++;
+ break;
+ case 'c':
+ ser_print(ser, ARG_SEP_S);
+ ser_print(ser, (*result).s);
+ result++;
+ break;
+ case 's':
+ ser_printf(ser, ARG_SEP_S "%s", (*result).s);
+ result++;
+ break;
+ case 'n':
+ n = (*result++).l;
+ ser_printf(ser, ARG_SEP_S "%ld", n);
+ while (n--) {
+ ser_printf(ser, ARG_SEP_S "%ld", (*result).l);
+ result++;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ while (--repeat_cnt);
+ }
+
+ /* Skip to next format char */
+ ++fmt;
+
+ } /* while (*fmt) */
+
+
+ ser_print(ser, "\r\n");
+ return 0;
+}
+#endif /* UNUSED_CODE */
+
+/// Hook provided by the parser for matching of command names (TAB completion) for readline
+const char* parser_rl_match(UNUSED_ARG(void *,dummy), const char *word, int word_len)
+{
+ HashIterator cur;
+ HashIterator end = ht_iter_end(&commands);
+ const char *found = NULL;
+
+ for (cur = ht_iter_begin(&commands);
+ !ht_iter_cmp(cur, end);
+ cur = ht_iter_next(cur))
+ {
+ const struct CmdTemplate* cmdp = (const struct CmdTemplate*)ht_iter_get(cur);
+ if (strncmp(cmdp->name, word, word_len) == 0)
+ {
+ // If there was another matching word, it means that we have a multiple
+ // match: then return NULL.
+ if (found)
+ return NULL;
+
+ found = cmdp->name;
+ }
+ }
+
+ return found;
+}
+
+bool parser_get_cmd_id(const char* line, unsigned long* ID)
+{
+ const char *begin = line, *end = line;
+ char *end2;
+
+ // The first word is the ID
+ if (!get_word(&begin, &end))
+ return false;
+
+ *ID = strtoul(begin, &end2, 10);
+ if (end2 != end)
+ return false;
+
+ return true;
+}
+
+const struct CmdTemplate* parser_get_cmd_template(const char *input)
+{
+// const struct CmdTemplate *cmdp;
+// int cmdlen;
+ const char *begin = input, *end = input;
+
+ // Skip the ID, and get the command
+ if (!get_word(&begin, &end))
+ return NULL;
+ if (!get_word(&begin, &end))
+ return NULL;
+
+ return (const struct CmdTemplate*)ht_find(&commands, begin, end-begin);
+}
+
+static const char *skip_to_params(const char *input, const struct CmdTemplate *cmdp)
+{
+ const char *begin = input, *end = input;
+
+ // Skip the ID, and get the command
+ if (!get_word(&begin, &end))
+ return NULL;
+ if (!get_word(&begin, &end))
+ return NULL;
+
+ ASSERT2(strlen(cmdp->name) == (size_t)(end-begin), "Invalid command template specified");
+ ASSERT2(!strncmp(begin, cmdp->name, end-begin), "Invalid command template specified");
+
+ return end;
+}
+
+bool parser_get_cmd_arguments(const char* input, const struct CmdTemplate* cmdp, parms args[PARSER_MAX_ARGS])
+{
+ input = skip_to_params(input, cmdp);
+ if (!input)
+ return false;
+
+ args[0].s = cmdp->name;
+ if (!parseArgs(cmdp->arg_fmt, input, args + 1))
+ return false;
+
+ return true;
+}
+
+static const void* get_key_from_command(const void* cmd, uint8_t* length)
+{
+ const struct CmdTemplate* c = cmd;
+ *length = strlen(c->name);
+ return c->name;
+}
+
+bool parser_process_line(const char* input)
+{
+ const struct CmdTemplate *cmdp;
+ parms args[PARSER_MAX_ARGS];
+
+ cmdp = parser_get_cmd_template(input);
+ if (!cmdp)
+ return false;
+
+ if (!parser_get_cmd_arguments(input, cmdp, args))
+ return false;
+
+ if (!parser_execute_cmd(cmdp, args))
+ return false;
+
+ return true;
+}
+
+void parser_register_cmd(const struct CmdTemplate* cmd)
+{
+ ht_insert(&commands, cmd);
+}
+
+#if CONFIG_INTERNAL_COMMANDS
+static ResultCode cmd_help(void)
+{
+#ifdef _DEBUG
+
+ // FIXME: There is no way at the moment to access the serial port. Dump
+ // this through JTAG for now
+ for (HashIterator iter = ht_iter_begin(&commands);
+ !ht_iter_cmp(iter, ht_iter_end(&commands));
+ iter = ht_iter_next(iter))
+ {
+ struct CmdTemplate* cmd = (struct CmdTemplate*)ht_iter_get(iter);
+ kprintf("%-20s", cmd->name);
+ for (unsigned j = 0; cmd->arg_fmt[j]; ++j)
+ kprintf("%c ", 'a' + j);
+ kprintf("\r\n");
+ }
+#endif
+
+ return RC_OK;
+}
+
+#include "cmd_hunk.h"
+DECLARE_CMD_HUNK(help, (NIL), (NIL));
+
+#endif // CONFIG_INTERNAL_COMMANDS
+
+
+void parser_init(void)
+{
+ // Initialize the hashtable used to store the command description
+ ht_init(&commands);
+
+#if CONFIG_INTERNAL_COMMANDS
+ parser_register_cmd(&CMD_HUNK_TEMPLATE(help));
+#endif
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2006 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ * \brief serial protocol parser and commands.
+ */
+
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <drv/ser.h>
+
+/** Max number of arguments and results for each command */
+#define PARSER_MAX_ARGS 8
+
+/**
+ * Error generated by the commands through the return code.
+ */
+typedef enum
+{
+ RC_ERROR = -1, ///< Reply with error.
+ RC_OK = 0, ///< No reply (ignore reply arguments).
+ RC_REPLY = 1, ///< Reply command arguments.
+ RC_SKIP = 2 ///< Skip following commands
+} ResultCode;
+
+/** union that contains parameters passed to and from commands */
+typedef union { long l; const char *s; } parms;
+/** pointer to commands */
+typedef ResultCode (*CmdFuncPtr)(parms args_results[]);
+
+/**
+ * Define a command that can be tokenized by the parser.
+ *
+ * The format strings are sequences of characters, one for each
+ * parameter/result. Valid characters are:
+ *
+ * d - a long integer, in decimal format
+ * s - a var string (in RAM)
+ *
+ * \note To create and fill an instance for this function, it is strongly
+ * advised to use \c DECLARE_CMD_HUNK (cmd_hunk.h).
+ */
+struct CmdTemplate
+{
+ const char *name; ///< Name of command
+ const char *arg_fmt; ///< Format string for the input
+ const char *result_fmt; ///< Format string for the output
+ CmdFuncPtr func; ///< Pointer to the handler function
+ uint16_t flags; ///< Currently unused.
+};
+
+/**
+ * Initialize the parser module
+ *
+ * \note This function must be called before any other function in this module
+ */
+void parser_init(void);
+
+
+/**
+ * Register a new command into the parser
+ *
+ * \param cmd Command template describing the command
+ *
+ */
+void parser_register_cmd(const struct CmdTemplate* cmd);
+
+
+/**
+ * Hook for readline to provide completion support for the commands
+ * registered in the parser.
+ *
+ * \note This is meant to be used with mware/readline.c. See the
+ * documentation there for a description of this hook.
+ */
+const char* parser_rl_match(void* dummy, const char* word, int word_len);
+
+
+/**
+ * \brief Command input handler.
+ *
+ * Process the input, calling the requested command
+ * (if found) and calling printResult() to give out
+ * the result (on device specified with parameter fd).
+ *
+ * \param line Text line to be processed (ASCIIZ)
+ *
+ * \return true if everything is OK, false in case of errors
+ */
+bool parser_process_line(const char* line);
+
+
+/**
+ * Execute a command with its arguments, and fetch its results.
+ *
+ * \param templ Template of the command to be executed
+ * \param args Arguments for the command, and will contain the results
+ *
+ * \return False if the command returned an error, true otherwise
+ */
+INLINE bool parser_execute_cmd(const struct CmdTemplate* templ, parms args[PARSER_MAX_ARGS])
+{
+ return (templ->func(args) == 0);
+}
+
+
+/**
+ * Find the template for the command contained in the text line.
+ * The template can be used to tokenize the command and interpret
+ * it.
+ *
+ * This function can be used to find out which command is contained
+ * in a given text line without parsing all the parameters and
+ * executing it.
+ *
+ * \param line Text line to be processed (ASCIIZ)
+ *
+ * \return The command template associated with the command contained
+ * in the line, or NULL if the command is invalid.
+ */
+const struct CmdTemplate* parser_get_cmd_template(const char* line);
+
+
+/**
+ * Extract the arguments for the command contained in the text line.
+ *
+ * \param line Text line to be processed (ASCIIZ)
+ * \param templ Command template for this line
+ * \param args Will contain the extracted parameters
+ *
+ * \return True if everything OK, false in case of parsing error.
+ */
+bool parser_get_cmd_arguments(const char* line, const struct CmdTemplate* templ, parms args[PARSER_MAX_ARGS]);
+
+
+/**
+ * Extract the ID from the command text line.
+ *
+ * \param line Text line to be processed (ASCIIZ)
+ * \param ID Will contain the ID extracted.
+ *
+ * \return True if everything ok, false if there is no ID
+ *
+ */
+bool parser_get_cmd_id(const char* line, unsigned long* ID);
+
+
+#endif /* PARSER_H */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 ,2006, 2007 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Support for reading program memory on Harvard architectures.
+ *
+ * Support is currently provided for AVR microcontrollers only.
+ *
+ * These macros allow building code twice, with and without
+ * pgm support (e.g.: strcpy() and strcpy_P()).
+ *
+ * Set the _PROGMEM predefine to compile in conditional
+ * program-memory support.
+ *
+ *
+ * \note This module contains code ripped out from avr-libc,
+ * which is distributed under a 3-clause BSD license.
+ */
+#ifndef MWARE_PGM_H
+#define MWARE_PGM_H
+
+#include <cfg/compiler.h> /* For intXX_t */
+#include <cpu/detect.h>
+#include <cpu/attr.h> /* For CPU_HARVARD */
+#include <cpu/types.h> /* For SIZEOF_INT */
+
+#if CPU_AVR
+
+ #ifdef __AVR_ENHANCED__
+ #define pgm_read_char(addr) \
+ ({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+ uint8_t __result; \
+ __asm__ \
+ ( \
+ "lpm %0, Z" "\n\t" \
+ : "=r" (__result) \
+ : "z" (__addr16) \
+ ); \
+ __result; \
+ })
+ #define pgm_read_uint16_t(addr) \
+ ({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+ uint16_t __result; \
+ __asm__ \
+ ( \
+ "lpm %A0, Z+" "\n\t" \
+ "lpm %B0, Z" "\n\t" \
+ : "=r" (__result), "=z" (__addr16) \
+ : "1" (__addr16) \
+ ); \
+ __result; \
+ })
+
+
+ #else /* !__AVR_ENHANCED__ */
+
+ #define pgm_read_char(addr) \
+ ({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+ uint8_t __result; \
+ __asm__ \
+ ( \
+ "lpm" "\n\t" \
+ "mov %0, r0" "\n\t" \
+ : "=r" (__result) \
+ : "z" (__addr16) \
+ : "r0" \
+ ); \
+ __result; \
+ })
+ #define pgm_read_uint16_t(addr) \
+ ({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+ uint16_t __result; \
+ __asm__ \
+ ( \
+ "lpm" "\n\t" \
+ "mov %A0, r0" "\n\t" \
+ "adiw r30, 1" "\n\t" \
+ "lpm" "\n\t" \
+ "mov %B0, r0" "\n\t" \
+ : "=r" (__result), "=z" (__addr16) \
+ : "1" (__addr16) \
+ : "r0" \
+ ); \
+ __result; \
+ })
+
+ #endif /* !__AVR_ENHANCED__ */
+
+ #if SIZEOF_INT == 2
+ #define pgm_read_int(addr) ((int)pgm_read_uint16_t(addr))
+ #else
+ #error Missing support for CPU word size != 16bit
+ #endif
+
+ #ifndef PROGMEM
+ #define PROGMEM __attribute__((__progmem__))
+ #endif
+ #ifndef PSTR
+ #define PSTR(s) ({ static const char __c[] PROGMEM = (s); &__c[0]; })
+ #endif
+ #ifndef PFUNC
+ #define PFUNC(x) x ## _P
+ #endif
+
+#elif CPU_HARVARD
+ #error Missing CPU support
+#endif
+
+#ifndef PSTR
+#define PSTR /* nothing */
+#endif
+
+#ifndef PFUNC
+#define PFUNC(x) x
+#endif
+
+#ifndef PROGMEM
+#define PROGMEM /* nothing */
+#endif
+
+/**
+ * \name Types for variables stored in program memory (harvard processors).
+ * \{
+ */
+typedef PROGMEM char pgm_char;
+typedef PROGMEM int8_t pgm_int8_t;
+typedef PROGMEM uint8_t pgm_uint8_t;
+typedef PROGMEM int16_t pgm_int16_t;
+typedef PROGMEM uint16_t pgm_uint16_t;
+typedef PROGMEM int32_t pgm_int32_t;
+typedef PROGMEM uint32_t pgm_uint32_t;
+/*\}*/
+
+/**
+ * \name PGM support macros.
+ *
+ * These macros enable dual compilation of code for both program
+ * and data memory.
+ *
+ * Such a function may be defined like this:
+ *
+ * \code
+ * void PGM_FUNC(lcd_puts)(PGM_ATTR const char *str)
+ * {
+ * char c;
+ * while ((c = PGM_READ_CHAR(str++))
+ * lcd_putchar(c);
+ * }
+ * \endcode
+ *
+ * The above code can be compiled twice: once with the _PROGMEM preprocessor
+ * symbol defined, and once without. The two object modules can then be
+ * linked in the same application for use by client code:
+ *
+ * \code
+ * lcd_puts("Hello, world!");
+ * lcd_puts_P(PSTR("Hello, world!"));
+ *
+ * // To be used when invoking inside other PGM_FUNC functions:
+ * PGM_FUNC(lcd_puts)(some_string);
+ * \endcode
+ *
+ * \{
+ */
+#ifdef _PROGMEM
+ #define PGM_READ_CHAR(s) pgm_read_char(s)
+ #define PGM_FUNC(x) PFUNC(x)
+ #define PGM_STR(x) PSTR(x)
+ #define PGM_ATTR PROGMEM
+#else
+ #define PGM_READ_CHAR(s) (*(s))
+ #define PGM_FUNC(x) x
+ #define PGM_STR(x) x
+ #define PGM_ATTR /* nothing */
+#endif
+/* \} */
+
+
+#endif /* MWARE_PGM_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Pool macros.
+ *
+ * \version $Id$
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.6 2006/07/19 12:56:28 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.5 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.4 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.3 2004/12/08 08:09:01 bernie
+ *#* Add missing header.
+ *#*
+ *#*/
+#ifndef MWARE_POOL_H
+#define MWARE_POOL_H
+
+#include <cfg/macros.h>
+#include <mware/list.h>
+
+#define EXTERN_POOL(name) \
+ extern List name
+
+#define DECLARE_POOL_WITH_STORAGE(name, type, num, storage) \
+ static type name##_items[num]; \
+ storage name; \
+ INLINE void name##_init(void (*init_func)(type*)) \
+ { \
+ int i; \
+ LIST_INIT(&name); \
+ for (i=0;i<countof(name##_items);++i) \
+ { \
+ if (init_func) init_func(&name##_items[i]); \
+ ADDTAIL(&name, (Node*)&name##_items[i]); \
+ } \
+ } \
+ INLINE void name##_init(void (*init_func)(type*)) \
+ /**/
+
+#define DECLARE_POOL(name, type, num) \
+ DECLARE_POOL_WITH_STORAGE(name, type, num, List)
+
+#define DECLARE_POOL_STATIC(name, type, num) \
+ DECLARE_POOL_WITH_STORAGE(name, type, num, static List)
+
+#define pool_init(name, init_func) (*(name##_init))(init_func)
+#define pool_alloc(name) REMHEAD(name)
+#define pool_free(name, elem) ADDHEAD(name, (Node*)elem)
+#define pool_empty(name) ISLISTEMPTY(name)
+
+#endif /* MWARE_POOL_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief Very simple rand() algorithm.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/* This would really belong to libc */
+static int rand(void)
+{
+ static unsigned long seed;
+
+ /* Randomize seed */
+ seed = (seed ^ 0x4BAD5A39UL) + 6513973UL;
+
+ return (int)(seed>>16);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Line editing support with history
+ *
+ * Rationale for basic implementation choices:
+ *
+ * \li The history is implemented storing consecutive ASCIIZ strings within an array of memory. When
+ * the history is full, the first (oldest) line is cancelled and the whole buffer is memmoved to
+ * overwrite it and make room. while this is is obviously not the fastest algorithm (which would
+ * require the use of a circular buffer) it is surely good enough for this module, which does not
+ * aim at fast performances (line editing does not require to be blazingly fast).
+ *
+ * \li The first character in the history is always \c \\0, and it is used as a guard. By 'wasting' it
+ * in this way, the code actually gets much simpler in that we remove many checks when moving
+ * backward (\c i>0 and similar).
+ *
+ * \li While editing, the current index points to the position of the buffer which contains the
+ * last character typed in (exactly like a stack pointer). This also allows to simplify calculations
+ * and to make easier using the last byte of history.
+ *
+ * \li While editing, the current line is always kept null-terminated. This is important because
+ * if the user press ENTER, we must have room to add a \c \\0 to terminate the line. If the line
+ * is as long as the whole history buffer, there would not be space for it. By always keeping the
+ * \c \\0 at the end, we properly ensure this without making index checks harder.
+ *
+ * \li When removing a line from the history (see \c pop_history()), instead of updating all the
+ * indices we have around, we move backward the pointer to the history we use. This way, we don't
+ * have to update anything. This means that we keep two pointers to the history: \c real_history
+ * always points to the physical start, while \c history is the adjusted pointer (that is
+ * dereference to read/write to it).
+ *
+ * \todo Use up/down to move through history The history line will be copied to the current line,
+ * making sure there is room for it.
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+
+#include "readline.h"
+
+#include <cfg/compiler.h>
+#include <cfg/debug.h>
+
+#include <stdio.h>
+#include <drv/ser.h>
+
+
+/// Enable compilation of the unit test code
+#define DEBUG_UNIT_TEST 0
+
+/// Enable dump of the history after each line
+#define DEBUG_DUMP_HISTORY 0
+
+
+/** Special keys (escape sequences converted to a single code) */
+enum RL_KEYS {
+ SPECIAL_KEYS = 0x1000,
+
+ /*
+ * Three byte keys:
+ * #################
+ * UpArrow: 0x1B 0x5B 0X41
+ * DownArrow: 0x1B 0x5B 0X42
+ * RightArrow: 0x1B 0x5B 0x43
+ * LeftArrow: 0x1b 0x5B 0x44
+ * Beak(Pause): 0x1b 0x5B 0x50
+ */
+ KEY_UP_ARROW,
+ KEY_DOWN_ARROW,
+ KEY_LEFT_ARROW,
+ KEY_RIGHT_ARROW,
+ KEY_PAUSE,
+
+ /*
+ * Four byte keys:
+ * ################
+ * F1: 0x1b 0x5B 0x5B 0x41
+ * F2: 0x1b 0x5B 0x5B 0x42
+ * F3: 0x1b 0x5B 0x5B 0x43
+ * F4: 0x1b 0x5B 0x5B 0x44
+ * F5: 0x1b 0x5B 0x5B 0x45
+ * Ins: 0x1b 0x5B 0x32 0x7E
+ * Home: 0x1b 0x5B 0x31 0x7E
+ * PgUp: 0x1b 0x5B 0x35 0x7E
+ * Del: 0x1b 0x5B 0x33 0x7E
+ * End: 0x1b 0x5B 0x34 0x7E
+ * PgDn: 0x1b 0x5B 0x36 0x7E
+ */
+ KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
+ KEY_INS, KEY_HOME, KEY_PGUP, KEY_DEL, KEY_END, KEY_PGDN,
+
+ /*
+ * Five byte keys:
+ * ################
+ * F6: 0x1b 0x5B 0x31 0x37 0x7E
+ * F7: 0x1b 0x5B 0x31 0x38 0x7E
+ * F8: 0x1b 0x5B 0x31 0x39 0x7E
+ * F9: 0x1b 0x5B 0x32 0x30 0x7E
+ * F10: 0x1b 0x5B 0x32 0x31 0x7E
+ * F11: 0x1b 0x5B 0x32 0x33 0x7E
+ * F12: 0x1b 0x5B 0x32 0x34 0x7E
+ */
+ KEY_F6, KEY_F7, KEY_F8, KEY_F9,
+ KEY_F10, KEY_F11, KEY_F12,
+};
+
+/** Check if \a c is a separator between words.
+ * \note Parameter \a c is evaluated multiple times
+ */
+#define IS_WORD_SEPARATOR(c) ((c) == ' ' || (c) == '\0')
+
+/// Write the string \a txt to the IO output (without any kind of termination)
+INLINE void rl_puts(const struct RLContext* ctx, const char* txt)
+{
+ if (!ctx->put)
+ return;
+
+ while (*txt)
+ ctx->put(*txt++, ctx->put_param);
+}
+
+/// Write character \a ch to the IO output.
+INLINE void rl_putc(const struct RLContext* ctx, char ch)
+{
+ if (ctx->put)
+ ctx->put(ch, ctx->put_param);
+}
+
+/** Read a character from the IO into \a ch. This function also takes
+ * care of converting the ANSI escape sequences into one of the codes
+ * defined in \c RL_KEYS.
+ */
+static bool rl_getc(const struct RLContext* ctx, int* ch)
+{
+ int c = ctx->get(ctx->get_param);
+
+ if (c == EOF)
+ {
+ if (ctx->clear)
+ ctx->clear(ctx->clear_param);
+
+ return false;
+ }
+
+ if (c == 0x1B)
+ {
+ // Unknown ESC sequence. Ignore it and read
+ // return next character.
+ if (ctx->get(ctx->get_param) != 0x5B)
+ return rl_getc(ctx, ch);
+
+ /* To be added:
+ * Home: 0x1b 0x5B 0x31 0x7E
+ * F6: 0x1b 0x5B 0x31 0x37 0x7E
+ * F7: 0x1b 0x5B 0x31 0x38 0x7E
+ * F8: 0x1b 0x5B 0x31 0x39 0x7E
+ * Ins: 0x1b 0x5B 0x32 0x7E
+ * F9: 0x1b 0x5B 0x32 0x30 0x7E
+ * F10: 0x1b 0x5B 0x32 0x31 0x7E
+ * F11: 0x1b 0x5B 0x32 0x33 0x7E
+ * F12: 0x1b 0x5B 0x32 0x34 0x7E
+ * Del: 0x1b 0x5B 0x33 0x7E
+ * End: 0x1b 0x5B 0x34 0x7E
+ * PgUp: 0x1b 0x5B 0x35 0x7E
+ * PgDn: 0x1b 0x5B 0x36 0x7E
+ */
+
+ c = ctx->get(ctx->get_param);
+ switch (c)
+ {
+ case 0x41: c = KEY_UP_ARROW; break;
+ case 0x42: c = KEY_DOWN_ARROW; break;
+ case 0x43: c = KEY_RIGHT_ARROW; break;
+ case 0x44: c = KEY_LEFT_ARROW; break;
+ case 0x50: c = KEY_PAUSE; break;
+ case 0x5B:
+ c = ctx->get(ctx->get_param);
+ switch (c)
+ {
+ case 0x41: c = KEY_F1; break;
+ case 0x42: c = KEY_F2; break;
+ case 0x43: c = KEY_F3; break;
+ case 0x44: c = KEY_F4; break;
+ case 0x45: c = KEY_F5; break;
+ default: return rl_getc(ctx, ch);
+ }
+ break;
+ default: return rl_getc(ctx, ch);
+ }
+ }
+
+ *ch = c;
+ return true;
+}
+
+INLINE void beep(struct RLContext* ctx)
+{
+ rl_putc(ctx, '\a');
+}
+
+static bool pop_history(struct RLContext* ctx, int total_len)
+{
+ // Compute the length of the first command (including terminator).
+ int len = strlen(ctx->real_history+1)+1;
+
+ // (the first byte of the history should always be 0)
+ ASSERT(ctx->real_history[0] == '\0');
+
+ // If it is the only one in the history, do nothing
+ if (len == total_len)
+ return false;
+
+ // Overwrite the first command with the second one
+ memmove(ctx->real_history, ctx->real_history+len, HISTORY_SIZE-len);
+
+ // Move back the ctx->buffer pointer so that all the indices are still valid
+ ctx->history -= len;
+
+ return true;
+}
+
+/// Check if index \a i points to the begin of the history.
+INLINE bool is_history_begin(struct RLContext* ctx, int i)
+{ return ctx->history + i == ctx->real_history; }
+
+/// Check if index \a i points to the (exclusive) end of history
+INLINE bool is_history_end(struct RLContext* ctx, int i)
+{ return ctx->history + i == ctx->real_history + HISTORY_SIZE; }
+
+/// Check if index \a i points to the (exclusive) end of history, or somewhere past the end.
+INLINE bool is_history_past_end(struct RLContext* ctx, int i)
+{ return ctx->history + i >= ctx->real_history + HISTORY_SIZE; }
+
+/** Insert \a num_chars characters from \a ch into the history buffer at the
+ * position indicated by \a curpos. If needed, remove old history to make room.
+ * Returns true if everything was successful, false if there was no room to
+ * add the characters.
+ * \note \a num_chars can be 0, in which case we just make sure the line is
+ * correctly zero-terminated (ASCIIZ format).
+ */
+static bool insert_chars(struct RLContext* ctx, size_t *curpos, const char* ch, int num_chars)
+{
+ ASSERT(!is_history_past_end(ctx, *curpos));
+
+ while (is_history_past_end(ctx, *curpos+num_chars+1))
+ {
+ if (!pop_history(ctx, *curpos))
+ return false;
+ }
+
+ while (num_chars--)
+ ctx->history[++(*curpos)] = *ch++;
+
+ ASSERT(!is_history_past_end(ctx, *curpos + 1));
+ ctx->history[*curpos+1] = '\0';
+ return true;
+}
+
+/// Insert a single character \a ch into the buffer (with the same semantic of \c insert_chars())
+static bool insert_char(struct RLContext* ctx, size_t *curpos, char ch)
+{
+ return insert_chars(ctx, curpos, &ch, 1);
+}
+
+#if DEBUG_DUMP_HISTORY
+/// Dump the internal history of a context (used only for debug purposes)
+static void dump_history(struct RLContext* ctx)
+{
+ int k;
+ char buf[8];
+ ASSERT(ctx->real_history[0] == '\0');
+ rl_puts(ctx, "History dump:");
+ rl_puts(ctx, "\r\n");
+ for (k = 1;
+ ctx->real_history + k != ctx->history + ctx->history_pos + 1;
+ k += strlen(&ctx->real_history[k]) + 1)
+ {
+ rl_puts(ctx, &ctx->real_history[k]);
+ rl_puts(ctx, "\r\n");
+ }
+
+ sprintf(buf, "%d\r\n", ctx->history_pos + (ctx->history - ctx->real_history));
+ rl_puts(ctx, buf);
+}
+#endif /* DEBUG_DUMP_HISTORY */
+
+/// Complete the current word. Return false if no unambiguous completion was found
+static bool complete_word(struct RLContext *ctx, size_t *curpos)
+{
+ const char* completed_word;
+ size_t wstart;
+
+ // If the current character is a separator,
+ // there is nothing to complete
+ wstart = *curpos;
+ if (IS_WORD_SEPARATOR(ctx->history[wstart]))
+ {
+ beep(ctx);
+ return false;
+ }
+
+ // Find the separator before the current word
+ do
+ --wstart;
+ while (!IS_WORD_SEPARATOR(ctx->history[wstart]));
+
+ // Complete the word through the hook
+ completed_word = ctx->match(ctx->match_param, ctx->history + wstart + 1, *curpos - wstart);
+ if (!completed_word)
+ return false;
+
+ // Move back the terminal cursor to the separator
+ while (*curpos != wstart)
+ {
+ rl_putc(ctx, '\b');
+ --*curpos;
+ }
+
+ // Insert the completed command
+ insert_chars(ctx, curpos, completed_word, strlen(completed_word));
+ rl_puts(ctx, completed_word);
+ insert_char(ctx, curpos, ' ');
+ rl_putc(ctx, ' ');
+
+ return true;
+}
+
+void rl_refresh(struct RLContext* ctx)
+{
+ rl_puts(ctx, "\r\n");
+ if (ctx->prompt)
+ rl_puts(ctx, ctx->prompt);
+ rl_puts(ctx, ctx->history + ctx->history_pos + 1);
+}
+
+const char* rl_readline(struct RLContext* ctx)
+{
+ size_t i = ctx->history_pos;
+
+ if (ctx->prompt)
+ rl_puts(ctx, ctx->prompt);
+
+ insert_chars(ctx, &i, NULL, 0);
+
+ while (1)
+ {
+ char ch;
+ int c;
+
+ ASSERT(ctx->history - ctx->real_history + ctx->line_pos < HISTORY_SIZE);
+
+ if (!rl_getc(ctx, &c))
+ return NULL;
+
+ // Just ignore special keys for now
+ if (c > SPECIAL_KEYS)
+ continue;
+
+ if (c == '\t')
+ {
+ // Ask the match hook if available
+ if (!ctx->match)
+ return false;
+
+ complete_word(ctx, &ctx->line_pos);
+ continue;
+ }
+
+ if (c == '\r' || c == '\n')
+ {
+ if (ctx->prompt)
+ rl_puts(ctx, ctx->prompt);
+
+ // Terminate line
+ insert_chars(ctx, &ctx->line_pos, NULL, 0);
+ rl_puts(ctx, "\r\n");
+ break;
+ }
+
+ // Backspace cancels a character, or it is ignored if at
+ // the start of the line
+ if (c == '\b')
+ {
+ if (ctx->history[ctx->line_pos] != '\0')
+ {
+ --ctx->line_pos;
+ rl_puts(ctx, "\b \b");
+ }
+ continue;
+ }
+
+ // Add a character to the buffer, if possible
+ ch = (char)c;
+ ASSERT2(ch == c, "a special key was not properly handled");
+ if (insert_chars(ctx, &ctx->line_pos, &ch, 1))
+ {
+ rl_putc(ctx, ch);
+ }
+ else
+ {
+ beep(ctx);
+ }
+ }
+
+ ctx->history_pos = ctx->line_pos + 1;
+ while (ctx->history[ctx->line_pos] != '\0')
+ --ctx->line_pos;
+
+ // Do not store empty lines in the history
+ if (ctx->line_pos == ctx->history_pos - 1)
+ ctx->history_pos -= 1;
+
+#if DEBUG_DUMP_HISTORY
+ dump_history(ctx);
+#endif
+
+ // Since the current pointer now points to the separator, we need
+ // to return the first character
+ return &ctx->history[ctx->line_pos + 1];
+}
+
+
+#if DEBUG_UNIT_TEST
+
+/** Perform the unit test for the readline library */
+void rl_test(void);
+
+#if HISTORY_SIZE != 32
+ #error This test needs HISTORY_SIZE to be set at 32
+#endif
+
+static struct RLContext test_ctx;
+
+static char* test_getc_ptr;
+static int test_getc(void* data)
+{
+ return *test_getc_ptr++;
+}
+
+/** Perform a readline test. The function pipes the characters from \a input_buffer
+ * through the I/O to \c rl_readline(). After the whole string is sent, \c do_test()
+ * checks if the current history within the context match \a expected_history.
+ */
+static bool do_test(char* input_buffer, char* expected_history)
+{
+ rl_init_ctx(&test_ctx);
+ rl_sethook_get(&test_ctx, test_getc, NULL);
+
+ test_getc_ptr = input_buffer;
+ while (*test_getc_ptr)
+ rl_readline(&test_ctx);
+
+ if (memcmp(test_ctx.real_history, expected_history, HISTORY_SIZE) != 0)
+ {
+ ASSERT2(0, "history compare failed");
+ return false;
+ }
+
+ return true;
+}
+
+void rl_test(void)
+{
+ char* test1_in = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n";
+ char test1_hist[HISTORY_SIZE] = "\0l\0m\0n\0o\0p\0q\0r\0s\0t\0u\0v\0w\0x\0y\0z";
+
+ if (!do_test(test1_in, test1_hist))
+ return;
+
+ kprintf("rl_test successful\n");
+}
+
+#endif /* DEBUG_UNIT_TEST */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright (C) 2004 Giovanni Bajo
+ * Copyright (C) 2004 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief Line editing support with history
+ *
+ * This file implements a kernel for line editing through a terminal, with history of the typed lines.
+ * Basic feature of this module:
+ *
+ * \li Abstracted from I/O. The user must provide hooks for getc and putc functions.
+ * \li Basic support for ANSI escape sequences for input of special codes.
+ * \li Support for command name completion (through a hook).
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+
+#ifndef MWARE_READLINE_H
+#define MWARE_READLINE_H
+
+#include <cfg/compiler.h>
+
+#include <string.h>
+
+#define HISTORY_SIZE 1024
+
+typedef int (*getc_hook)(void* user_data);
+typedef void (*putc_hook)(char ch, void* user_data);
+typedef const char* (*match_hook)(void* user_data, const char* word, int word_len);
+typedef void (*clear_hook)(void* user_data);
+
+struct RLContext
+{
+ getc_hook get;
+ void* get_param;
+
+ putc_hook put;
+ void* put_param;
+
+ match_hook match;
+ void* match_param;
+
+ clear_hook clear;
+ void* clear_param;
+
+ const char* prompt;
+
+ char real_history[HISTORY_SIZE];
+ char* history;
+ size_t history_pos;
+ size_t line_pos;
+};
+
+INLINE void rl_init_ctx(struct RLContext *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->history = ctx->real_history;
+}
+
+INLINE void rl_clear_history(struct RLContext *ctx)
+{
+ memset(ctx->real_history, 0, sizeof(ctx->real_history));
+ ctx->history_pos = 0;
+ ctx->history = ctx->real_history;
+}
+
+INLINE void rl_sethook_get(struct RLContext* ctx, getc_hook get, void* get_param)
+{ ctx->get = get; ctx->get_param = get_param; }
+
+INLINE void rl_sethook_put(struct RLContext* ctx, putc_hook put, void* put_param)
+{ ctx->put = put; ctx->put_param = put_param; }
+
+INLINE void rl_sethook_match(struct RLContext* ctx, match_hook match, void* match_param)
+{ ctx->match = match; ctx->match_param = match_param; }
+
+INLINE void rl_sethook_clear(struct RLContext* ctx, clear_hook clear, void* clear_param)
+{ ctx->clear = clear; ctx->clear_param = clear_param; }
+
+INLINE void rl_setprompt(struct RLContext* ctx, const char* prompt)
+{ ctx->prompt = prompt; }
+
+const char* rl_readline(struct RLContext* ctx);
+
+void rl_refresh(struct RLContext* ctx);
+
+#endif /* MWARE_READLINE_H */
--- /dev/null
+
+#include "resource.h"
+#include <mware/observer.h>
+
+/**
+ * Internal structure for building a priority queue
+ * of processes waiting for the resource to become free.
+ */
+typedef struct ResourceWaiter
+{
+ PriNode link;
+ struct Observer *owner;
+
+} ResourceWaiter;
+
+
+bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest)
+{
+ bool success = false;
+
+ ASSERT(releaseRequest);
+
+ sem_obtain(&res->lock);
+
+ if (res->owner == releaseRequest)
+ {
+ // Already ours
+ res->pri = pri;
+ success = true;
+ }
+ else if (!res->owner)
+ {
+ // Trivial acquire: nobody was owning the resource
+ res->pri = pri;
+ res->owner = releaseRequest;
+ success = true;
+ }
+ else
+ {
+ ResourceWaiter waiter;
+
+ // Setup waiter structure and enqueue it to resource
+ waiter.owner = releaseRequest;
+ waiter.link.pri = pri;
+ LIST_ENQUEUE(&res->queue, &waiter.link);
+
+ // Resource busy: are we eligible for preemption?
+ if ((res->pri < pri) && res->owner->event)
+ res->owner->event(EVENT_RELEASE, res);
+
+ // Wait in the queue until the timeout occurs.
+ do
+ {
+ sem_release(&res->lock);
+ // TODO: use a semaphore here instead
+ ResMan_sleep();
+ sem_obtain(&res->lock);
+
+ // Check for ownership
+ if (res->owner == releaseRequest)
+ {
+ success = true;
+ break;
+ }
+ }
+ while (timeout--);
+
+ // Remove pending waiter
+ if (!success)
+ REMOVE(&waiter.link.link);
+ }
+
+ sem_release(&res->lock);
+ return success;
+}
+
+void ResMan_Free(Resource *res)
+{
+ ResourceWaiter *waiter;
+
+ sem_obtain(&res->lock);
+
+
+ ASSERT(res->owner);
+ //TODO: check for real owner calling free
+
+ // Check for new owner candidates.
+ if ((waiter = (ResourceWaiter *)list_remHead(&res->queue)))
+ {
+ // Transfer ownership of the resource
+ res->owner = waiter->owner;
+ res->pri = waiter->link.pri;
+ //ResMan_wakeup(waiter);
+ }
+ else
+ {
+ // Nobody waiting, free the resource
+ res->owner = NULL;
+ res->pri = -1;
+ }
+
+ sem_release(&res->lock);
+}
+
+void ResMan_Init(Resource *res)
+{
+ res->owner = NULL;
+ res->pri = -1;
+
+ sem_init(&res->lock);
+ LIST_INIT(&res->queue);
+}
+
--- /dev/null
+#ifndef MWARE_RESOURCE_H
+#define MWARE_RESOURCE_H
+
+#include <drv/timer.h> // time_t
+#include <kern/sem.h>
+
+/*
+ * Abstract locking primitives used by host OS.
+ */
+#if CONFIG_KERNEL
+
+ typedef Semaphore ResourceLock;
+ #define ResMan_sleep() timer_delay(1)
+ #define ResMan_time_t mtime_t
+
+#else /* FreeRTOS */
+
+ #include <freertos.h>
+ #include <semphr.h>
+ #include <task.h> // vTaskDelay()
+
+ #define ResMan_sleep() vTaskDelay((portTickType)1 * portTICK_RATE_MS)
+ #define ResMan_time_t portTickType
+#endif
+
+
+// Forward decl
+struct Observer;
+
+/**
+ * Hold context information for a resource such as an audio channel.
+ *
+ * Each driver registers one or more Resource instances with the
+ * ResMan using ResMan_Register().
+ *
+ * Clients can then allocate the resource through ResMan_Alloc()
+ * providing a desired priority and an Observer for asynchronous
+ * notification.
+ *
+ * Allocated resources can be stolen by other clients asking for a
+ * higher priority. ResMan notifies a preemption request by invoking
+ * the Observer of the current owner.
+ *
+ * The Observer callback must take whatever action is needed to
+ * release the resource as soon as possible to avoid blocking the
+ * new owner.
+ */
+typedef struct Resource
+{
+//Private
+ /// Control access to fields below.
+ Semaphore lock;
+
+ /// Pointer to current owner's observer. NULL if resource is free.
+ struct Observer *owner;
+
+ /// Priority of current owner (higher values mean higher priority).
+ int pri;
+
+ /// Queue of processes waiting to obtain the resource.
+ List queue;
+} Resource;
+
+/// Event sent by ResMan to owners when to request resource release.
+enum { EVENT_RELEASE = 1 };
+
+/// Try to allocate a resource \a res with priority \a pri for at most \a timeout ticks.
+bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest);
+
+/// Free resource \a res. Will eventually wake-up other queued owners.
+void ResMan_Free(Resource *res);
+
+void ResMan_Init(Resource *res);
+
+#endif /* MWARE_RESOURCE_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief General-purpose run-length {en,de}coding algorithm (implementation)
+ *
+ * Original source code from http://www.compuphase.com/compress.htm
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/07/19 12:56:28 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.3 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.2 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.1 2004/08/04 02:35:54 bernie
+ *#* Import simple RLE algorithm.
+ *#*
+ *#*/
+
+#include "rle.h"
+
+
+/**
+ * Run-length encode \a len bytes from the \a input buffer
+ * to the \a output buffer.
+ */
+int rle(unsigned char *output, const unsigned char *input, int len)
+{
+ int count, index, i;
+ unsigned char first;
+ unsigned char *out;
+
+
+ out = output;
+ count = 0;
+ while (count < len)
+ {
+ index = count;
+ first = input[index++];
+
+ /* Scan for bytes identical to the first one */
+ while ((index < len) && (index - count < 127) && (input[index] == first))
+ index++;
+
+ if (index - count == 1)
+ {
+ /* Failed to "replicate" the current byte. See how many to copy.
+ */
+ while ((index < len) && (index - count < 127))
+ {
+ /* Avoid a replicate run of only 2-bytes after a literal run.
+ * There is no gain in this, and there is a risc of loss if the
+ * run after the two identical bytes is another literal run.
+ * So search for 3 identical bytes.
+ */
+ if ((input[index] == input[index - 1]) &&
+ ((index > 1) && (input[index] == input[index - 2])))
+ {
+ /* Reset the index so we can back up these three identical
+ * bytes in the next run.
+ */
+ index -= 2;
+ break;
+ }
+
+ index++;
+ }
+
+ /* Output a run of uncompressed bytes: write length and values */
+ *out++ = (unsigned char)(count - index);
+ for (i = count; i < index; i++)
+ *out++ = input[i];
+ }
+ else
+ {
+ /* Output a compressed run: write length and value */
+ *out++ = (unsigned char)(index - count);
+ *out++ = first;
+ }
+
+ count = index;
+ }
+
+ /* Output EOF marker */
+ *out++ = 0;
+
+ return (out - output);
+}
+
+
+/**
+ * Run-length decode from the \a input buffer to the \a output
+ * buffer.
+ *
+ * \note The output buffer must be large enough to accomodate
+ * all decoded output.
+ */
+int unrle(unsigned char *output, const unsigned char *input)
+{
+ signed char count;
+ unsigned char *out;
+ unsigned char value;
+
+
+ out = output;
+
+ for (;;)
+ {
+ count = (signed char)*input++;
+ if (count > 0)
+ {
+ /* replicate run */
+ value = *input++;
+ while (count--)
+ *out++ = value;
+ }
+ else if (count < 0)
+ {
+ /* literal run */
+ while (count++)
+ *out++ = *input++;
+ }
+ else
+ /* EOF */
+ break;
+ }
+
+ return (out - output);
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ *
+ * \brief General-purpose run-length {en,de}coding algorithm (interface)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.4 2006/07/19 12:56:28 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.3 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.2 2004/08/25 14:12:09 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.1 2004/08/04 02:35:54 bernie
+ *#* Import simple RLE algorithm.
+ *#*
+ *#*/
+#ifndef RLE_H
+#define RLE_H
+
+int rle(unsigned char *output, const unsigned char *input, int length);
+int unrle(unsigned char *output, const unsigned char *input);
+
+#endif /* RLE_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2002, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief sprintf() implementation based on _formatted_write()
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include <mware/formatwr.h>
+#include <mware/pgm.h>
+#include <cfg/compiler.h>
+
+#include <stdio.h>
+
+
+static void __str_put_char(char c, void *ptr)
+{
+ /*
+ * This Does not work on Code Warrior. Hmm...
+ * *(*((char **)ptr))++ = c;
+ */
+
+ **((char **)ptr) = c;
+ (*((char **)ptr))++;
+}
+
+static void __null_put_char(UNUSED_ARG(char, c), UNUSED_ARG(void *, ptr))
+{
+ /* nop */
+}
+
+
+int PGM_FUNC(vsprintf)(char *str, const char * PGM_ATTR fmt, va_list ap)
+{
+ int result;
+
+ if (str)
+ {
+ result = PGM_FUNC(_formatted_write)(fmt, __str_put_char, &str, ap);
+
+ /* Terminate string */
+ *str = '\0';
+ }
+ else
+ result = PGM_FUNC(_formatted_write)(fmt, __null_put_char, 0, ap);
+
+
+ return result;
+}
+
+
+int PGM_FUNC(sprintf)(char *str, const char * fmt, ...)
+{
+ int result;
+ va_list ap;
+
+ va_start(ap, fmt);
+ result = PGM_FUNC(vsprintf)(str, fmt, ap);
+ va_end(ap);
+
+ return result;
+}
+
+/**
+ * State information for __sn_put_char()
+ */
+struct __sn_state
+{
+ char *str;
+ size_t len;
+};
+
+/**
+ * formatted_write() callback used [v]snprintf().
+ */
+static void __sn_put_char(char c, void *ptr)
+{
+ struct __sn_state *state = (struct __sn_state *)ptr;
+
+ if (state->len)
+ {
+ --state->len;
+ *state->str++ = c;
+ }
+}
+
+
+int PGM_FUNC(vsnprintf)(char *str, size_t size, const char * PGM_ATTR fmt, va_list ap)
+{
+ int result = 0;
+
+ /* Make room for traling '\0'. */
+ if (size--)
+ {
+ if (str)
+ {
+ struct __sn_state state;
+ state.str = str;
+ state.len = size;
+
+ result = PGM_FUNC(_formatted_write)(fmt, __sn_put_char, &state, ap);
+
+ /* Terminate string. */
+ *state.str = '\0';
+ }
+ else
+ result = PGM_FUNC(_formatted_write)(fmt, __null_put_char, 0, ap);
+ }
+
+ return result;
+}
+
+
+int PGM_FUNC(snprintf)(char *str, size_t size, const char * fmt, ...)
+{
+ int result;
+ va_list ap;
+
+ va_start(ap, fmt);
+ result = PGM_FUNC(vsnprintf)(str, size, fmt, ap);
+ va_end(ap);
+
+ return result;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief sprintf() implementation based on _formatted_write()
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "sprintf.c"
+#include "formatwr.c"
+#include "hex.c"
+#include <cfg/compiler.h>
+#include <mware/pgm.h>
+#include <stdio.h>
+
+#include <assert.h> /* assert() */
+#include <string.h> /* strcmp() */
+
+
+int main(UNUSED_ARG(int, argc), UNUSED_ARG(char **,argv))
+{
+ char buf[256];
+ static const char test_string[] = "Hello, world!\n";
+ static const pgm_char test_string_pgm[] = "Hello, world!\n";
+
+ snprintf(buf, sizeof buf, "%s", test_string);
+ assert(strcmp(buf, test_string) == 0);
+
+ snprintf(buf, sizeof buf, "%S", test_string_pgm);
+ assert(strcmp(buf, test_string_pgm) == 0);
+
+#define TEST(FMT, VALUE, EXPECT) do { \
+ snprintf(buf, sizeof buf, FMT, VALUE); \
+ assert(strcmp(buf, EXPECT) == 0); \
+ } while (0)
+
+ TEST("%d", 12345, "12345");
+ TEST("%ld", 123456789L, "123456789");
+ TEST("%ld", -12345678L, "-12345678");
+ TEST("%lu", 4294967295UL, "4294967295");
+ TEST("%hd", -12345, "-12345");
+ TEST("%hu", 65535U, "65535");
+
+ TEST("%8d", 123, " 123");
+ TEST("%8d", -123, " -123");
+ TEST("%-8d", -123, "-123 ");
+ TEST("%08d", -123, "-0000123");
+
+ TEST("%8.2f", -123.456, " -123.46");
+ TEST("%-8.2f", -123.456, "-123.46 ");
+ TEST("%8.0f", -123.456, " -123");
+
+#undef TEST
+
+ /*
+ * Stress tests.
+ */
+ snprintf(buf, sizeof buf, "%s", NULL);
+ assert(strcmp(buf, "<NULL>") == 0);
+ snprintf(buf, sizeof buf, "%k");
+ assert(strcmp(buf, "???") == 0);
+ sprintf(NULL, test_string); /* must not crash */
+
+ return 0;
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Poor man's hex arrays (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "strtol10.h"
+
+/**
+ * Convert a formatted base-10 ASCII number to unsigned long binary representation.
+ *
+ * Unlike the standard strtoul(), this function has an interface
+ * that makes it better suited for protocol parsers. It's also
+ * much simpler and smaller than a full featured strtoul().
+ *
+ * \param first Pointer to first byte of input range (STL-style).
+ * \param last Pointer to end of input range (STL-style).
+ * Pass NULL to parse up to the first \\0.
+ * \param val Pointer to converted value.
+ *
+ * \return true for success, false for failure.
+ *
+ * \see strtol10()
+ */
+bool strtoul10(const char *first, const char *last, unsigned long *val)
+{
+ // Check for no input
+ if (*first == '\0')
+ return false;
+
+ *val = 0;
+ for(/*nop*/; first != last && *first != '\0'; ++first)
+ {
+ if ((*first < '0') || (*first > '9'))
+ return false;
+
+ *val = (*val * 10L) + (*first - '0');
+ }
+
+ return true;
+}
+
+
+/**
+ * Convert a formatted base-10 ASCII number to signed long binary representation.
+ *
+ * \see strtoul10()
+ */
+bool strtol10(const char *first, const char *last, long *val)
+{
+ bool negative = false;
+
+ if (*first == '+')
+ ++first; /* skip unary plus sign */
+ else if (*first == '-')
+ {
+ negative = true;
+ ++first;
+ }
+
+ bool result = strtoul10(first, last, (unsigned long *)val);
+
+ if (negative)
+ *val = - *val;
+
+ return result;
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Poor man's hex arrays (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+
+#ifndef MWARE_STRTOL10_H
+#define MWARE_STRTOL10_H
+
+#include <cfg/compiler.h> /* bool */
+
+bool strtoul10(const char *first, const char *last, unsigned long *val);
+bool strtol10(const char *first, const char *last, long *val);
+
+/**
+ * Replacement for standard library function atol().
+ */
+INLINE long atol(const char *str)
+{
+ long val;
+ strtol10(str, NULL, &val);
+ return val;
+}
+
+/**
+ * Replacement for standard library function atoi().
+ */
+INLINE int atoi(const char *str)
+{
+ return (int)atol(str);
+}
+
+#endif /* MWARE_STRTOL10_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ * \brief X-Modem serial transmission protocol (implementation)
+ *
+ * Supports the CRC-16 and 1K-blocks variants of the standard.
+ * \see ymodem.txt for the protocol description.
+ *
+ * \todo Break xmodem_send() and xmodem_recv() in smaller functions.
+ *
+ * \todo Maybe convert drv/ser.c to the KFile interface for symmetry and
+ * flexibility.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+
+#include "xmodem.h"
+
+#include <appconfig.h>
+#include <string.h> /* for memset() */
+#include <drv/ser.h>
+#include <algo/crc.h>
+#include <cfg/debug.h>
+
+
+
+
+/**
+ * \name Protocol control codes
+ * \{
+ */
+#define XM_SOH 0x01 /**< Start Of Header (128-byte block) */
+#define XM_STX 0x02 /**< Start Of Header (1024-byte block) */
+#define XM_EOT 0x04 /**< End Of Transmission */
+#define XM_ACK 0x06 /**< Acknowledge block */
+#define XM_NAK 0x15 /**< Negative Acknowledge */
+#define XM_C 0x43 /**< Request CRC-16 transmission */
+#define XM_CAN 0x18 /**< CANcel transmission */
+/*\}*/
+
+#define XM_MAXRETRIES 15 /**< Max retries before giving up */
+#define XM_MAXCRCRETRIES 7 /**< Max retries before switching to BCC */
+
+#if CONFIG_XMODEM_1KCRC == 1
+ #define XM_BUFSIZE 1024 /**< 1024 bytes of block buffer */
+#else
+ #define XM_BUFSIZE 128 /**< 128 bytes of block buffer */
+#endif
+
+
+#if CONFIG_XMODEM_RECV
+/**
+ * \brief Receive a file using the XModem protocol.
+ *
+ * \param port Serial port to use for transfer
+ * \param fd Destination file
+ *
+ * \note This function allocates a large amount of stack (\see XM_BUFSIZE).
+ */
+bool xmodem_recv(struct Serial *port, KFile *fd)
+{
+ char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
+ int c, i, blocksize;
+ int blocknr = 0, last_block_done = 0, retries = 0;
+ char *buf;
+ uint8_t checksum;
+ uint16_t crc;
+ bool purge = false;
+ bool usecrc = true;
+
+
+ XMODEM_PROGRESS("Starting Transfer...\n");
+ purge = true;
+ ser_setstatus(port, 0);
+
+ /* Send initial NAK to start transmission */
+ for(;;)
+ {
+ if (XMODEM_CHECK_ABORT)
+ {
+ ser_putchar(XM_CAN, port);
+ ser_putchar(XM_CAN, port);
+ XMODEM_PROGRESS("Transfer aborted\n");
+ return false;
+ }
+
+ /*
+ * Discard incoming input until a timeout occurs, then send
+ * a NAK to the transmitter.
+ */
+ if (purge)
+ {
+ purge = false;
+
+ if (ser_getstatus(port))
+ XMODEM_PROGRESS("Retries %d\n", retries);
+
+ ser_resync(port, 200);
+ retries++;
+
+ if (retries >= XM_MAXRETRIES)
+ {
+ ser_putchar(XM_CAN, port);
+ ser_putchar(XM_CAN, port);
+ XMODEM_PROGRESS("Transfer aborted\n");
+ return false;
+ }
+
+ /* Transmission start? */
+ if (blocknr == 0)
+ {
+ if (retries < XM_MAXCRCRETRIES)
+ {
+ XMODEM_PROGRESS("Request Tx (CRC)\n");
+ ser_putchar(XM_C, port);
+ }
+ else
+ {
+ /* Give up with CRC and fall back to checksum */
+ usecrc = false;
+ XMODEM_PROGRESS("Request Tx (BCC)\n");
+ ser_putchar(XM_NAK, port);
+ }
+ }
+ else
+ ser_putchar(XM_NAK, port);
+ }
+
+ switch (ser_getchar(port))
+ {
+ #if XM_BUFSIZE >= 1024
+ case XM_STX: /* Start of header (1024-byte block) */
+ blocksize = 1024;
+ goto getblock;
+ #endif
+
+ case XM_SOH: /* Start of header (128-byte block) */
+ blocksize = 128;
+ /* Needed to avoid warning if XM_BUFSIZE < 1024 */
+ goto getblock;
+ getblock:
+ /* Get block number */
+ c = ser_getchar(port);
+
+ /* Check complemented block number */
+ if ((~c & 0xff) != ser_getchar(port))
+ {
+ XMODEM_PROGRESS("Bad blk (%d)\n", c);
+ purge = true;
+ break;
+ }
+
+ /* Determine which block is being sent */
+ if (c == (blocknr & 0xff))
+ /* Last block repeated */
+ XMODEM_PROGRESS("Repeat blk %d\n", blocknr);
+ else if (c == ((blocknr + 1) & 0xff))
+ /* Next block */
+ XMODEM_PROGRESS("Recv blk %d\n", ++blocknr);
+ else
+ {
+ /* Sync lost */
+ XMODEM_PROGRESS("Sync lost (%d/%d)\n", c, blocknr);
+ purge = true;
+ break;
+ }
+
+ buf = block_buffer; /* Reset pointer to start of buffer */
+ checksum = 0;
+ crc = 0;
+ for (i = 0; i < blocksize; i++)
+ {
+ if ((c = ser_getchar(port)) == EOF)
+ {
+ purge = true;
+ break;
+ }
+
+ /* Store in buffer */
+ *buf++ = (char)c;
+
+ /* Calculate block checksum or CRC */
+ if (usecrc)
+ crc = UPDCRC16(c, crc);
+ else
+ checksum += (char)c;
+ }
+
+ if (purge)
+ break;
+
+ /* Get the checksum byte or the CRC-16 MSB */
+ if ((c = ser_getchar(port)) == EOF)
+ {
+ purge = true;
+ break;
+ }
+
+ if (usecrc)
+ {
+ crc = UPDCRC16(c, crc);
+
+ /* Get CRC-16 LSB */
+ if ((c = ser_getchar(port)) == EOF)
+ {
+ purge = true;
+ break;
+ }
+
+ crc = UPDCRC16(c, crc);
+
+ if (crc)
+ {
+ XMODEM_PROGRESS("Bad CRC: %04x\n", crc);
+ purge = true;
+ break;
+ }
+ }
+ /* Compare the checksum */
+ else if (c != checksum)
+ {
+ XMODEM_PROGRESS("Bad sum: %04x/%04x\n", checksum, c);
+ purge = true;
+ break;
+ }
+
+ /*
+ * Avoid flushing the same block twice.
+ * This could happen when the sender does not receive our
+ * acknowledge and resends the same block.
+ */
+ if (last_block_done < blocknr)
+ {
+ /* Call user function to flush the buffer */
+ if (fd->write(fd, block_buffer, blocksize))
+ {
+ /* Acknowledge block and clear error counter */
+ ser_putchar(XM_ACK, port);
+ retries = 0;
+ last_block_done = blocknr;
+ }
+ else
+ {
+ /* User callback failed: abort transfer immediately */
+ retries = XM_MAXRETRIES;
+ purge = true;
+ }
+ }
+ break;
+
+ case XM_EOT: /* End of transmission */
+ ser_putchar(XM_ACK, port);
+ XMODEM_PROGRESS("Transfer completed\n");
+ return true;
+
+ case EOF: /* Timeout or serial error */
+ purge = true;
+ break;
+
+ default:
+ XMODEM_PROGRESS("Skipping garbage\n");
+ purge = true;
+ break;
+ }
+ } /* End forever */
+}
+#endif
+
+
+#if CONFIG_XMODEM_SEND
+/**
+ * \brief Transmit some data using the XModem protocol.
+ *
+ * \param port Serial port to use for transfer
+ * \param fd Source file
+ *
+ * \note This function allocates a large amount of stack for
+ * the XModem transfer buffer (\see XM_BUFSIZE).
+ */
+bool xmodem_send(struct Serial *port, KFile *fd)
+{
+ char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
+ size_t size = -1;
+ int blocknr = 1, retries = 0, c, i;
+ bool proceed, usecrc = false;
+ uint16_t crc;
+ uint8_t sum;
+
+ /*
+ * Reading a block can be very slow, so we read the first block early
+ * to avoid receiving double XM_C char.
+ * This could happen if we check for XM_C and then read the block, giving
+ * the receiving device time to send another XM_C char misinterpretating
+ * the blocks sent.
+ */
+ size = fd->read(fd, block_buffer, XM_BUFSIZE);
+
+ ser_setstatus(port, 0);
+ ser_purge(port);
+ XMODEM_PROGRESS("Wait remote host\n");
+
+ for(;;)
+ {
+ proceed = false;
+ do
+ {
+ if (XMODEM_CHECK_ABORT)
+ return false;
+
+ switch (c = ser_getchar(port))
+ {
+ case XM_NAK:
+ XMODEM_PROGRESS("Resend blk %d\n", blocknr);
+ proceed = true;
+ break;
+
+ case XM_C:
+ if (c == XM_C)
+ {
+ XMODEM_PROGRESS("Tx start (CRC)\n");
+ usecrc = true;
+ }
+ else
+ XMODEM_PROGRESS("Tx start (BCC)\n");
+
+ proceed = true;
+ break;
+
+ case XM_ACK:
+ /* End of transfer? */
+ if (!size)
+ return true;
+
+ /* Call user function to read in one block */
+ size = fd->read(fd, block_buffer, XM_BUFSIZE);
+ XMODEM_PROGRESS("Send blk %d\n", blocknr);
+ blocknr++;
+ retries = 0;
+ proceed = true;
+ break;
+
+ case EOF:
+ ser_setstatus(port, 0);
+ retries++;
+ XMODEM_PROGRESS("Retries %d\n", retries);
+ if (retries <= XM_MAXRETRIES)
+ break;
+ /* falling through! */
+
+ case XM_CAN:
+ XMODEM_PROGRESS("Transfer aborted\n");
+ return false;
+
+ default:
+ XMODEM_PROGRESS("Skipping garbage\n");
+ break;
+ }
+ }
+ while (!proceed);
+
+ if (!size)
+ {
+ ser_putchar(XM_EOT, port);
+ continue;
+ }
+
+ /* Pad block with 0xFF if it's partially full */
+ memset(block_buffer + size, 0xFF, XM_BUFSIZE - size);
+
+ /* Send block header (STX, blocknr, ~blocknr) */
+ #if XM_BUFSIZE == 128
+ ser_putchar(XM_SOH, port);
+ #else
+ ser_putchar(XM_STX, port);
+ #endif
+ ser_putchar(blocknr & 0xFF, port);
+ ser_putchar(~blocknr & 0xFF, port);
+
+ /* Send block and compute its CRC/checksum */
+ sum = 0;
+ crc = 0;
+ for (i = 0; i < XM_BUFSIZE; i++)
+ {
+ ser_putchar(block_buffer[i], port);
+ crc = UPDCRC16(block_buffer[i], crc);
+ sum += block_buffer[i];
+ }
+
+ /* Send CRC/Checksum */
+ if (usecrc)
+ {
+ crc = UPDCRC16(0, crc);
+ crc = UPDCRC16(0, crc);
+ ser_putchar(crc >> 8, port);
+ ser_putchar(crc & 0xFF, port);
+ }
+ else
+ ser_putchar(sum, port);
+ }
+}
+#endif
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 1999, 2001 Bernardo Innocenti <bernie@develer.com>
+ *
+ * -->
+ * \brief X-Modem serial transmission protocol (interface)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+
+#ifndef MWARE_XMODEM_H
+#define MWARE_XMODEM_H
+#include <cfg/compiler.h>
+#include <kern/kfile.h>
+
+/**
+ * Called to know if we want to abort data tranfer.
+ * Redefine to whatever you need.
+ * \{
+ */
+#ifndef XMODEM_CHECK_ABORT
+#define XMODEM_CHECK_ABORT (false)
+#endif
+/*\}*/
+
+
+/**
+ * Called to printf progress messages.
+ * Default to kprintf debug, redefine to whatever you need.
+ * \{
+ */
+#ifndef XMODEM_PROGRESS
+#define XMODEM_PROGRESS(msg, ...) kprintf(msg, ## __VA_ARGS__)
+#endif
+
+
+/* fwd decl */
+struct Serial;
+
+bool xmodem_recv(struct Serial *port, KFile *fd);
+bool xmodem_send(struct Serial *port, KFile *fd);
+
+#endif /* MWARE_XMODEM_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \author Andrea Grandi <andrea@develer.com>
+ *
+ * \brief Tag protocol (protocol).
+ *
+ * TAG protocol is decribed in this way:
+ * <pre>
+ * ---------------------------------------------------
+ * |STX (0x02)|data...(10 HEX chars)|CR|LF|ETX (0x03)|
+ * ---------------------------------------------------
+ * </pre>
+ */
+
+#include "keytag.h"
+
+#include <kern/kfile.h>
+
+#include <drv/timer.h>
+#include <drv/ser.h>
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+static void keytag_clearPkt(struct TagPacket *pkt)
+{
+ pkt->sync = false;
+ pkt->len = 0;
+}
+
+ void keytag_init(struct TagPacket *pkt)
+ {
+ keytag_clearPkt(pkt);
+ }
+
+ void keytag_poll(struct TagPacket *pkt)
+{
+ int c;
+
+ /* Get all chars from buffer */
+ while ((c = kfile_getc(&pkt->tag_ser->fd)) != EOF)
+ {
+ /* Search for STX char in received chars */
+ if (c == TAG_STX)
+ {
+ /* When STX is found a new packet begins */
+ if (pkt->sync)
+ kprintf("TAG double sync!\n");
+ keytag_clearPkt(pkt);
+ pkt->sync = true;
+ }
+ else if (pkt->sync)
+ {
+ /* Check for end of packet */
+ if (c == TAG_ETX)
+ {
+ pkt->buf[TAG_MAX_PRINT_CHARS] = '\x0';
+ /* Write read TAG on communication serial */
+ kfile_printf(&pkt->comm_ser->fd, "tag %s", pkt->buf);
+ pkt->sync = false;
+ }
+ else
+ {
+ /* Check for buffer overflow */
+ if (pkt->len >= TAG_MAX_LEN)
+ {
+ kprintf("TAG buffer overflow\n");
+ pkt->sync = false;
+ }
+ else
+ {
+ /* Add every char after STX to tag reading buffer */
+ if (pkt->sync)
+ {
+ pkt->buf[pkt->len] = c;
+ pkt->len++;
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \author Andrea Grandi <andrea@develer.com>
+ *
+ * \brief Tag protocol. (interface).
+ */
+
+#ifndef NET_KEYTAG_H
+#define NET_KEYTAG_H
+
+#include <kern/kfile.h>
+#include <drv/ser.h>
+
+/**
+ * Starting communication char (STX).
+ */
+#define TAG_STX 0x02
+
+/**
+ * Ending communication char (ETX).
+ */
+#define TAG_ETX 0x03
+
+/**
+ * Max buffer lenght
+ */
+#define TAG_MAX_LEN 14
+
+#define TAG_SER_PORT 0
+#define TAG_SER_BAUDRATE 9600
+
+/**
+ * Max number of chars to print in the communication serial
+ */
+#define TAG_MAX_PRINT_CHARS 12
+
+/**
+ * Structure of a Tag packet
+ */
+typedef struct TagPacket
+{
+ KFileSerial *tag_ser; // Tag serial
+ KFileSerial *comm_ser; // Communication serial
+ bool sync; // Status flag: true if we find an STX
+ uint16_t len; // Packet lenght
+ uint8_t buf[TAG_MAX_LEN]; // Reception buffer
+} TagPacket;
+
+void keytag_init(struct TagPacket *pkt);
+void keytag_poll(struct TagPacket *pkt);
+
+#endif /* NET_TAG_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id: pocketbus.c 20131 2007-12-13 17:39:55Z batt $
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief pocketBus protocol implementation.
+ *
+ * pocketBus protocol is a simple strictly master-slave protocol, usable
+ * in embedded systems.
+ * pocketBus frame is as follows:
+ * <pre>
+ * +----------------------------------------+
+ * | STX | VER | ADDR | PAYLOAD | CKS | ETX |
+ * +----------------------------------------+
+ * | | | | | | |
+ * + 1B + 1B + 2B + N Byte + 2B + 1B +
+ * </pre>
+ *
+ * - STX, 1 byte (0x02), packet start
+ * - VER, 1 byte, packet version
+ * - ADDR, 2 byte, slave address
+ * - PAYLOAD, N byte, data field
+ * - CKS, 2 byte, checksum
+ * - ETX, 1 byte, (0x03) packet end
+ *
+ * Protocol parsing start on STX reception. When the receiving routine
+ * finds an STX char, it starts to read characters from the bus
+ * until an ETX is received. Once a packet is received,
+ * the parser checks packet correctness and checksum. If all is OK
+ * the payload is returned.
+ *
+ * STX (0x02), ETX(0x03) and ESC(0x1B) are special characters and cannot be
+ * transmitted inside payload without escaping them.
+ * To escape a character you must precede it by the ESC char.
+ * E.G. STX -> ESC + STX
+ * ETX -> ESC + ETX
+ * ESC -> ESC + ESC
+ *
+ * In the ADDR field is always specified the slave address.
+ * In the case of master trasmitting, ADDR contains the slave destination
+ * address.
+ * In case of slave replying, ADDR contains the slave address itself.
+ * Thus, the master device does not have an address. Packet must be routed to
+ * master by hardware bus design.
+ *
+ * The checksum algorithm used is rotating hash algortihm, quite simple but more
+ * reliable than simple checksum.
+ * The checksum in computed on all fields excluding STX, ETX and CHK fields itself.
+ * Checksum is computed on the packet *before* escaping.
+ * Escape sequence counts for 1 character only (the escaped one).
+ */
+
+#include "pocketbus.h"
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+
+#include <kern/kfile.h>
+
+#include <mware/byteorder.h>
+
+#include <string.h>
+
+/**
+ * Send a character over pocketBus channel stream, handling escape mode.
+ */
+void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c)
+{
+ /* Update checksum */
+ rotating_update1(c, &ctx->out_cks);
+
+ /* Escape characters with special meaning */
+ if (c == POCKETBUS_ESC || c == POCKETBUS_STX || c == POCKETBUS_ETX)
+ kfile_putc(POCKETBUS_ESC, ctx->fd);
+
+ kfile_putc(c, ctx->fd);
+}
+
+/**
+ * Send pocketBus packet header.
+ */
+void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr)
+{
+ PocketBusHdr hdr;
+
+ hdr.ver = POCKETBUS_VER;
+ hdr.addr = cpu_to_be16(addr);
+ rotating_init(&ctx->out_cks);
+
+ /* Send STX */
+ kfile_putc(POCKETBUS_STX, ctx->fd);
+
+ /* Send header */
+ pocketbus_write(ctx, &hdr, sizeof(hdr));
+}
+
+/**
+ * Send buffer \a _data over bus, handling escape.
+ */
+void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len)
+{
+ const uint8_t *data = (const uint8_t *)_data;
+
+ while (len--)
+ pocketbus_putchar(ctx, *data++);
+}
+
+/**
+ * Send pocketBus packet tail.
+ */
+void pocketbus_end(struct PocketBusCtx *ctx)
+{
+ /* Send checksum */
+ rotating_t cks = cpu_to_be16(ctx->out_cks);
+ pocketbus_write(ctx, &cks, sizeof(cks));
+
+ /* Send ETX */
+ kfile_putc(POCKETBUS_ETX, ctx->fd);
+}
+
+/**
+ * Send buffer of \a data to address \a addr with a pocketBus packet over channel stream.
+ */
+void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len)
+{
+ pocketbus_begin(ctx, addr);
+
+ /* Send data */
+ pocketbus_write(ctx, data, len);
+
+ pocketbus_end(ctx);
+}
+
+
+/**
+ * Try to read a packet from the pocketBus.
+ * \return true if a packet is received, false otherwise.
+ */
+bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg)
+{
+ int c;
+
+ /* Process incoming characters until buffer is not empty */
+ while ((c = kfile_getc(ctx->fd)) != EOF)
+ {
+ /* Look for STX char */
+ if (c == POCKETBUS_STX && !ctx->escape)
+ {
+ /* When an STX is found, inconditionally start a new packet */
+ if (ctx->sync)
+ kprintf("pocketBus double sync!\n");
+
+ ctx->sync = true;
+ ctx->len = 0;
+ rotating_init(&ctx->in_cks);
+ continue;
+ }
+
+ if (ctx->sync)
+ {
+ /* Handle escape mode */
+ if (c == POCKETBUS_ESC && !ctx->escape)
+ {
+ ctx->escape = true;
+ continue;
+ }
+
+ /* Handle message end */
+ if (c == POCKETBUS_ETX && !ctx->escape)
+ {
+ ctx->sync = false;
+
+ /* Check minimum size */
+ if (ctx->len < sizeof(PocketBusHdr) + sizeof(rotating_t))
+ {
+ kprintf("pocketBus short pkt!\n");
+ continue;
+ }
+
+ /* Remove checksum bytes from packet len */
+ ctx->len -= sizeof(rotating_t);
+
+ /* Compute checksum */
+ rotating_update(ctx->buf, ctx->len, &ctx->in_cks);
+ rotating_t recv_cks = be16_to_cpu(*((rotating_t *)(ctx->buf + ctx->len)));
+
+ /* Checksum check */
+ if (recv_cks == ctx->in_cks)
+ {
+ PocketBusHdr *hdr = (PocketBusHdr *)(ctx->buf);
+ /* Check packet version */
+ if (hdr->ver == POCKETBUS_VER)
+ {
+ /* Packet received, set msg fields */
+ msg->payload = ctx->buf + sizeof(PocketBusHdr);
+ msg->addr = be16_to_cpu(hdr->addr);
+ msg->len = ctx->len - sizeof(PocketBusHdr);
+ msg->ctx = ctx;
+ return true;
+ }
+ else
+ {
+ kprintf("pocketBus version mismatch, here[%d], there[%d]\n", POCKETBUS_VER, hdr->ver);
+ continue;
+ }
+ }
+ else
+ {
+ kprintf("pocketBus cks error, here[%04X], there[%04X]\n", ctx->in_cks, recv_cks);
+ continue;
+ }
+
+ }
+
+ ctx->escape = false;
+
+ /* Check buffer overflow: simply ignore
+ received data and go to unsynced state. */
+ if (ctx->len >= CONFIG_POCKETBUS_BUFLEN)
+ {
+ kprintf("pocketBus buffer overflow\n");
+ ctx->sync = false;
+ continue;
+ }
+
+ /* Put received data in the buffer */
+ ctx->buf[ctx->len] = c;
+ ctx->len++;
+ }
+ }
+
+ /*
+ * Check stream status.
+ */
+ if (kfile_error(ctx->fd))
+ {
+ TRACEMSG("fd status[%04X]", kfile_error(ctx->fd));
+ kfile_clearerr(ctx->fd);
+ }
+
+ return false;
+}
+
+
+/**
+ * Initialize pocketBus protocol handler.
+ */
+void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd)
+{
+ ASSERT(ctx);
+ ASSERT(fd);
+
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->fd = fd;
+}
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id: pocketbus.h 20131 2007-12-13 17:39:55Z batt $
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief pocketBus protocol interface.
+ */
+
+#ifndef NET_POCKETBUS_H
+#define NET_POCKETBUS_H
+
+#include <algos/rotating_hash.h>
+#include <drv/ser.h>
+#include <kern/kfile.h>
+#include <cfg/compiler.h>
+#include "appconfig.h" //for CONFIG_POCKETBUS_BUFLEN
+
+/**
+ * pocketBus special characters definitions.
+ * \{
+ */
+#define POCKETBUS_STX 0x02 //ASCII STX
+#define POCKETBUS_ETX 0x03 //ASCII ETX
+#define POCKETBUS_ESC 0x1B //ASCII ESC
+#define POCKETBUS_ACK 0x06 //ASCII ACK
+#define POCKETBUS_NAK 0x15 //ASCII NAK
+/*\}*/
+
+#define POCKETBUS_BROADCAST_ADDR 0xFFFF ///< pocketBus broadcast address
+
+/**
+ * Type for pocketBus length.
+ */
+typedef uint16_t pocketbus_len_t;
+
+/**
+ * Type for pocketBus addresses.
+ */
+typedef uint16_t pocketbus_addr_t;
+
+/**
+ * Header of pocketBus messages.
+ */
+typedef struct PocketBusHdr
+{
+ #define POCKETBUS_VER 1
+ uint8_t ver; ///< packet version
+ pocketbus_addr_t addr; ///< slave address
+} PocketBusHdr;
+
+/**
+ * pocketBus context structure.
+ */
+typedef struct PocketBusCtx
+{
+ struct KFile *fd; ///< File descriptor
+ bool sync; ///< Status flag: true if we have received an STX, false otherwise
+ bool escape; ///< Status flag: true if we are in escape mode, false otherwise
+ rotating_t in_cks; ///< Checksum computation for received data.
+ rotating_t out_cks; ///< Checksum computation for transmitted data.
+ pocketbus_len_t len; ///< Received length
+ uint8_t buf[CONFIG_POCKETBUS_BUFLEN]; ///< receiving Buffer
+} PocketBusCtx;
+
+/**
+ * Structure holding pocketBus message parameters.
+ */
+typedef struct PocketMsg
+{
+ struct PocketBusCtx *ctx; ///< pocketBus message context
+ pocketbus_addr_t addr; ///< address for received packet
+ pocketbus_len_t len; ///< payload length
+ const uint8_t *payload; ///< payload data
+} PocketMsg;
+
+/**
+ * This ensure that endianess convertion functions work on
+ * the right data size.
+ * \{
+ */
+STATIC_ASSERT(sizeof(pocketbus_addr_t) == sizeof(uint16_t));
+STATIC_ASSERT(sizeof(rotating_t) == sizeof(uint16_t));
+/*\}*/
+
+void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c);
+void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr);
+void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len);
+void pocketbus_end(struct PocketBusCtx *ctx);
+
+void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len);
+bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg);
+void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd);
+
+#endif /* NET_POCKETBUS_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id: pocketcmd.c 16587 2007-10-02 14:31:02Z batt $
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief pocketBus protocol Command layer implementation.
+ *
+ * This module implements command layer over pocketBus
+ * protocol.
+ * Payload packets received by pocketBus are first checked for
+ * address matching.
+ * If a packet is addressed to us we look for a suitable
+ * callback function to call.
+ *
+ * The received payload format is as follows:
+ * <pre>
+ * +----------------------------------------+
+ * | CMD | DATA |
+ * +----------------------------------------+
+ * | | |
+ * + 2B + 0..N Byte +
+ * </pre>
+ *
+ * The CMD ID used is the same supplied by the master when
+ * the command was sent.
+ */
+
+#include "pocketcmd.h"
+#include "pocketbus.h"
+
+#include <cfg/macros.h>
+#include <cfg/debug.h>
+#include <cfg/module.h>
+
+#include <drv/timer.h>
+
+#include <mware/byteorder.h>
+
+#include <string.h>
+
+/**
+ * pocketBus Command poll function.
+ * Call it to read and process pocketBus commands.
+ */
+void pocketcmd_poll(struct PocketCmdCtx *ctx)
+{
+ PocketMsg msg;
+
+ /* Try to read a packet from pocketBus */
+ while (pocketbus_recv(ctx->bus_ctx, &msg))
+ {
+ /* Check address */
+ if (msg.addr == ctx->addr ||
+ msg.addr == POCKETBUS_BROADCAST_ADDR)
+ {
+ const PocketCmdHdr *hdr = (const PocketCmdHdr *)msg.payload;
+ pocketcmd_t cmd = be16_to_cpu(hdr->cmd);
+
+ /* We're no longer waiting for a reply (in case we were) */
+ if (cmd == ctx->waiting)
+ ctx->waiting = PKTCMD_NULL;
+
+ /* Check for command callback */
+ pocketcmd_hook_t callback = ctx->search(cmd);
+
+ /* Call it if exists */
+ if (callback)
+ {
+ PocketCmdMsg cmd_msg;
+
+ cmd_msg.cmd_ctx = ctx;
+ cmd_msg.cmd = cmd;
+ cmd_msg.len = msg.len - sizeof(PocketCmdHdr);
+ cmd_msg.buf = msg.payload + sizeof(PocketCmdHdr);
+
+ callback(&cmd_msg);
+ }
+ }
+ }
+}
+
+/**
+ * Send command \a cmd to/from slave adding \a len arguments in \a buf.
+ * Address used is contained in \a ctx->addr .
+ * If we are master and the message has a reply, you must set \a wait_reply to true.
+ * \return true if all is ok, false if we are already waiting a replay from another slave.
+ */
+bool pocketcmd_send(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len, bool wait_reply)
+{
+ /* Check if we are waiting a reply from someone */
+ if (ctx->waiting != PKTCMD_NULL)
+ {
+ /* Check is reply timeout is elapsed */
+ if (timer_clock() - ctx->reply_timer < ms_to_ticks(PKTCMD_REPLY_TIMEOUT))
+ {
+ TRACEMSG("Pkt discard! waiting cmd[%04X]\n", ctx->waiting);
+ return false;
+ }
+ else
+ {
+ TRACEMSG("Timeout waiting cmd[%04X]\n", ctx->waiting);
+ ctx->waiting = PKTCMD_NULL;
+ }
+ }
+
+ /* Endianess! */
+ cmd = cpu_to_be16(cmd);
+
+ /* Send packet */
+ pocketbus_begin(ctx->bus_ctx, ctx->addr);
+ pocketbus_write(ctx->bus_ctx, &cmd, sizeof(cmd));
+ pocketbus_write(ctx->bus_ctx, buf, len);
+ pocketbus_end(ctx->bus_ctx);
+
+ if (wait_reply)
+ {
+ ctx->waiting = cmd;
+ ctx->reply_timer = timer_clock();
+ }
+ return true;
+}
+
+/**
+ * Init pocketBus command layer.
+ * \a ctx is pocketBus command layer context.
+ * \a bus_ctx is pocketBus context.
+ * \a addr is slave address (see pocketcmd_setAddr for details.)
+ * \a search is the lookup function used to search command ID callbacks.
+ */
+void pocketcmd_init(struct PocketCmdCtx *ctx, struct PocketBusCtx *bus_ctx, pocketbus_addr_t addr, pocketcmd_lookup_t search)
+{
+ ASSERT(ctx);
+ ASSERT(bus_ctx);
+ ASSERT(search);
+ MOD_CHECK(timer);
+
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->bus_ctx = bus_ctx;
+ ctx->search = search;
+ pocketcmd_setAddr(ctx, addr);
+}
+
+/**
+ * Helper function used to reply to master with an ACK.
+ */
+void pocketcmd_replyAck(struct PocketCmdMsg *msg)
+{
+ uint8_t ack[] = { POCKETBUS_ACK };
+
+ pocketcmd_slaveReply(msg->cmd_ctx, msg->cmd, ack, sizeof(ack));
+}
+
+/**
+ * Helper function used to reply to master with a NAK.
+ */
+void pocketcmd_replyNak(struct PocketCmdMsg *msg)
+{
+ uint8_t nak[] = { POCKETBUS_NAK };
+
+ pocketcmd_slaveReply(msg->cmd_ctx, msg->cmd, nak, sizeof(nak));
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id: pocketcmd.h 20030 2007-12-04 16:16:09Z batt $
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * \brief pocketBus protocol command layer interface.
+ */
+
+#ifndef NET_POCKETCMD_H
+#define NET_POCKETCMD_H
+
+#include "pocketbus.h"
+#include <cfg/compiler.h>
+
+#define PKTCMD_NULL 0 ///< pocketBus Null command
+
+#define PKTCMD_REPLY_TIMEOUT 50 ///< Command replay timeout in milliseconds
+
+typedef uint16_t pocketcmd_t; ///< Type for Command IDs
+
+/**
+ * Header for transmitted pocketBus Commands.
+ */
+typedef struct PocketCmdHdr
+{
+ pocketcmd_t cmd; ///< command ID
+} PocketCmdHdr;
+
+/**
+ * This ensure that endianess convertion functions work on
+ * the right data size.
+ * \{
+ */
+STATIC_ASSERT(sizeof(pocketcmd_t) == sizeof(uint16_t));
+/*\}*/
+
+/* fwd declaration */
+struct PocketCmdCtx;
+
+/**
+ * pocketBus command message structure.
+ */
+typedef struct PocketCmdMsg
+{
+ struct PocketCmdCtx *cmd_ctx; ///< command context
+ pocketcmd_t cmd; ///< command id
+ pocketbus_len_t len; ///< optional arg length
+ const uint8_t *buf; ///< optional arguments
+} PocketCmdMsg;
+
+/**
+ * Type for command hooks.
+ */
+typedef void (*pocketcmd_hook_t)(struct PocketCmdMsg *cmd_msg);
+
+/**
+ * Type for lookup function hooks.
+ */
+typedef pocketcmd_hook_t (*pocketcmd_lookup_t)(pocketcmd_t cmd);
+
+/**
+ * pocketBus context for command layer communications.
+ */
+typedef struct PocketCmdCtx
+{
+ struct PocketBusCtx *bus_ctx; ///< pocketBus context
+ pocketbus_addr_t addr; ///< Our address
+ pocketcmd_lookup_t search; ///< Lookup function used to search for command callbacks
+ pocketcmd_t waiting; ///< The command ID we are waiting for or PKTCMD_NULL.
+ ticks_t reply_timer; ///< For waiting_reply
+} PocketCmdCtx;
+
+/**
+ * Set slave address \a addr for pocketBus command layer.
+ * If we are a slave this is *our* address.
+ * If we are the master this is the slave address to send messages to.
+ */
+INLINE void pocketcmd_setAddr(struct PocketCmdCtx *ctx, pocketbus_addr_t addr)
+{
+ ctx->addr = addr;
+}
+
+void pocketcmd_init(struct PocketCmdCtx *ctx, struct PocketBusCtx *bus_ctx, pocketbus_addr_t addr, pocketcmd_lookup_t search);
+void pocketcmd_poll(struct PocketCmdCtx *ctx);
+bool pocketcmd_send(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len, bool has_replay);
+void pocketcmd_replyNak(struct PocketCmdMsg *msg);
+void pocketcmd_replyAck(struct PocketCmdMsg *msg);
+
+/**
+ * Helper function used by master to send a command to slave \a addr.
+ */
+INLINE bool pocketcmd_masterSend(struct PocketCmdCtx *ctx, pocketbus_addr_t addr, pocketcmd_t cmd, const void *buf, size_t len)
+{
+ pocketcmd_setAddr(ctx, addr);
+ return pocketcmd_send(ctx, cmd, buf, len, true);
+}
+
+/**
+ * Helper function used by slave to reply to a master command.
+ */
+INLINE bool pocketcmd_slaveReply(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len)
+{
+ return pocketcmd_send(ctx, cmd, buf, len, false);
+}
+
+
+#endif /* NET_POCKETCMD_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Portable abstraction for high-resolution time handling (implementation)
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+
+#include "hptime.h"
+
+#if defined(_WIN32)
+
+#include <windows.h>
+
+hptime_t hptime_get(void)
+{
+ FILETIME ft;
+
+ /*
+ * La precisione dei FileTime sarebbe 100ns, ma il
+ * valore viene ottenuto convertendo una struttura
+ * SYSTEMTIME, che ha precisione di 1ms. Il numero
+ * che otteniamo e' quindi sempre un multiplo di
+ * 100000.
+ */
+ GetSystemTimeAsFileTime(&ft);
+
+ /* Copy the upper/lower into a quadword. */
+ return (((hptime_t)ft.dwHighDateTime) << 32) + (hptime_t)ft.dwLowDateTime;
+}
+
+#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+
+#include <sys/time.h> /* for gettimeofday() */
+#include <stddef.h> /* for NULL */
+
+hptime_t hptime_get(void)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return (hptime_t)tv.tv_sec * HPTIME_TICKS_PER_SECOND
+ + (hptime_t)tv.tv_usec;
+}
+
+#else /* !__unix__ */
+ #error OS dependent support code missing for this OS
+#endif /* !__unix__ */
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Portable abstraction for high-resolution time handling (interface)
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ */
+#ifndef HPTIME_H
+#define HPTIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef _WIN32
+
+ /** our type for "high precision absolute time" */
+ typedef __int64 hptime_t;
+
+ #define HPTIME_TICKS_PER_SECOND (10000000I64)
+ #define HPTIME_TICKS_PER_MILLISEC (10000I64)
+ #define HPTIME_TICKS_PER_MICRO (10I64)
+
+#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+
+ #include <stdint.h> /* int64_t */
+
+ #ifndef DEVLIB_MTIME_DEFINED
+ #define DEVLIB_MTIME_DEFINED 1 /* Resolve conflict with <cfg/compiler.h> */
+ typedef int32_t mtime_t;
+ #define SIZEOF_MTIME_T (32 / CPU_BITS_PER_CHAR)
+ #define MTIME_INFINITE 0x7FFFFFFFL
+ #endif
+
+ /** Type for "high precision absolute time". */
+ typedef int64_t hptime_t;
+
+ #define HPTIME_TICKS_PER_SECOND (1000000LL)
+ #define HPTIME_TICKS_PER_MILLISEC (1000LL)
+ #define HPTIME_TICKS_PER_MICRO (1LL)
+
+#else /* !__unix__ */
+ #error OS dependent support code missing for this OS
+#endif /* !__unix__ */
+
+/**
+ * Return the current time with the maximum precision made available from the hosting OS
+ */
+extern hptime_t hptime_get(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HPTIME_H */
--- /dev/null
+#
+# $Id$
+# Copyright 2002,2003,2004,2005,2006 Develer S.r.l. (http://www.develer.com/)
+# All rights reserved.
+#
+# Based on:
+# GCC-AVR standard Makefile part 2
+# Volker Oth 1/2000
+#
+# Author: Bernardo Innocenti <bernie@develer.com>
+#
+
+# Remove all default pattern rules
+.SUFFIXES:
+
+# Verbosity
+ifeq ($(V),1)
+# Verbose build
+Q :=
+L := @echo >/dev/null
+else
+# Quiet build
+Q := @
+L := @echo
+endif
+
+# Select Bourne Again SHell as default make shell
+SHELL := bash
+
+# Checker build
+ifeq ($(C),1)
+CC = $(CHECKER)
+CFLAGS += -Wundef -D__x86_64__=1 -D__unix__=1 -D__linux__=1 -D__STDC_VERSION__=199901L
+endif
+
+# Initialize $(top_srcdir) with current directory, unless it was already initialized
+top_srcdir ?= $(shell pwd)
+
+# Products
+TRG_ELF = $(TRG:%=$(OUTDIR)/%.elf)
+TRG_S19 = $(TRG:%=$(OUTDIR)/%.s19)
+TRG_HEX = $(TRG:%=$(OUTDIR)/%.hex)
+TRG_BIN = $(TRG:%=$(OUTDIR)/%.bin)
+TRG_ROM = $(TRG:%=$(OUTDIR)/%.rom)
+TRG_COF = $(TRG:%=$(OUTDIR)/%.cof)
+TRG_EXE = $(TRG:%=$(OUTDIR)/%)
+
+
+RECURSIVE_TARGETS = all-recursive install-recursive clean-recursive
+
+# The default target
+.PHONY: all
+ifeq ($(EMBEDDED_TARGET),1)
+all:: all-recursive $(TRG_S19) $(TRG_HEX) $(TRG_BIN)
+else
+all:: all-recursive $(TRG_EXE)
+endif
+
+# Generate project documentation
+.PHONY: docs
+docs:
+ $L "Building documentation"
+ $Q $(DOXYGEN)
+
+# Generate ctags
+.PHONY: tags
+tags:
+ $L "Rebuilding C tags database"
+ $Q ctags -R --exclude=doc
+
+# Run testsuite
+.PHONY: check
+check:
+ $L "Running testsuite"
+ $Q ./run_tests.sh
+
+define build_target
+
+ifneq ($$(strip $$($(1)_MCU)),)
+# Define all project specific object files
+$(1)_CFLAGS += -mmcu=$$($(1)_MCU)
+$(1)_CXXFLAGS += -mmcu=$$($(1)_MCU)
+$(1)_ASFLAGS += -mmcu=$$($(1)_MCU)
+$(1)_CPPAFLAGS += -mmcu=$$($(1)_MCU)
+$(1)_LDFLAGS += -mmcu=$$($(1)_MCU)
+endif
+ifneq ($$(strip $$($(1)_CPU)),)
+# Define all project specific object files
+$(1)_CFLAGS += -mcpu=$$($(1)_CPU)
+$(1)_CXXFLAGS += -mcpu=$$($(1)_CPU)
+$(1)_ASFLAGS += -mcpu=$$($(1)_CPU)
+$(1)_CPPAFLAGS += -mcpu=$$($(1)_CPU)
+$(1)_LDFLAGS += -mcpu=$$($(1)_CPU)
+endif
+ifneq ($$(strip $$($(1)_LDSCRIPT)),)
+$(1)_LDFLAGS += -Wl,-T$$($(1)_LDSCRIPT)
+endif
+
+$(1)_CC = $$($(1)_CROSS)$$(CC)
+$(1)_CXX = $$($(1)_CROSS)$$(CXX)
+$(1)_AS = $$($(1)_CROSS)$$(AS)
+$(1)_OBJCOPY = $$($(1)_CROSS)$$(OBJCOPY)
+
+$(1)_COBJ = $$(foreach file,$$($(1)_CSRC:%.c=%.o),$$(OBJDIR)/$(1)/$$(file))
+$(1)_CXXOBJ = $$(foreach file,$$($(1)_CXXSRC:%.cpp=%.o),$$(OBJDIR)/$(1)/$$(file))
+$(1)_PCOBJ = $$(foreach file,$$($(1)_PCSRC:%.c=%_P.o),$$(OBJDIR)/$(1)/$$(file))
+$(1)_AOBJ = $$(foreach file,$$($(1)_ASRC:%.s=%.o),$$(OBJDIR)/$(1)/$$(file))
+$(1)_CPPAOBJ = $$(foreach file,$$($(1)_CPPASRC:%.S=%.o),$$(OBJDIR)/$(1)/$$(file))
+$(1)_OBJ := $$($(1)_COBJ) $$($(1)_CXXOBJ) $$($(1)_PCOBJ) $$($(1)_AOBJ) $$($(1)_CPPAOBJ)
+$(1)_SRC := $$($(1)_CSRC) $$($(1)_CXXSRC) $$($(1)_PCSRC) $$($(1)_ASRC) $$($(1)_CPPASRC)
+OBJ += $$($(1)_OBJ)
+
+ifneq ($$(strip $$($(1)_CXXSRC)),)
+$(1)_LD = $$($(1)_CROSS)$$(LDXX)
+else
+$(1)_LD = $$($(1)_CROSS)$$(LD)
+endif
+
+# Compile: instructions to create assembler and/or object files from C source
+$$($(1)_COBJ) : $$(OBJDIR)/$(1)/%.o : %.c
+ $L "$(1): Compiling $$< (C)"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_CC) -c $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+
+# Compile: instructions to create assembler and/or object files from C++ source
+$$($(1)_CXXOBJ) : $$(OBJDIR)/$(1)/%.o : %.cpp
+ $L "$(1): Compiling $$< (C++)"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_CXX) -c $$(CXXFLAGS) $$($(1)_CXXFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+
+# Generate assembly sources from C files (debug)
+$$(OBJDIR)/$(1)/%.s : %.c
+ $L "$(1): Generating asm source $$<"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_CC) -S $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$< -o $$@
+
+# Generate special progmem variant of a source file
+$$($(1)_PCOBJ) : $$(OBJDIR)/$(1)/%_P.o : %.c
+ $L "$(1): Compiling $$< (PROGMEM)"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_CC) -c -D_PROGMEM $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+
+# Assemble: instructions to create object file from assembler files
+$$($(1)_AOBJ): $$(OBJDIR)/$(1)/%.o : %.s
+ $L "$(1): Assembling $$<"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_AS) -c $$(ASFLAGS) $$($(1)_ASFLAGS) $$< -o $$@
+
+$$($(1)_CPPAOBJ): $$(OBJDIR)/$(1)/%.o : %.S
+ $L "$(1): Assembling with CPP $$<"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_CC) -c $$(CPPAFLAGS) $$($(1)_CPPAFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+
+
+# Link: instructions to create elf output file from object files
+$$(OUTDIR)/$(1).elf $$(OUTDIR)/$(1)_nostrip: bumprev $$($(1)_OBJ) $$($(1)_LDSCRIPT)
+ $L "$(1): Linking $$@"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_LD) $$($(1)_OBJ) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
+
+# Strip debug info
+$$(OUTDIR)/$(1): $$(OUTDIR)/$(1)_nostrip
+ $L "$(1): Generating stripped executable $$@"
+ $Q $$($(1)_STRIP) -o $$@ $$^
+
+# Compile and link (program-at-a-time)
+$$(OUTDIR)/$(1)_whole.elf: bumprev $$($(1)_SRC) $$($(1)_LDSCRIPT)
+ $L "$(1): Compiling and Linking whole program $$@"
+ @$$(MKDIR_P) $$(dir $$@)
+ $Q $$($(1)_CC) $$($(1)_SRC) $$(CFLAGS) $$($(1)_CFLAGS) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
+
+# Flash target
+# NOTE: we retry in case of failure because the STK500 programmer is crappy
+.PHONY: flash_$(1)
+flash_$(1): $(OUTDIR)/$(1).s19 flash_$(1)_local
+ if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U flash:w:$$< ; then \
+ $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U flash:w:$$< ; \
+ fi
+ #avarice --mkII -j usb --erase --program --verify --file images/triface.elf
+
+.PHONY: flash_$(1)_local
+flash_$(1)_local:
+
+.PHONY: fuses_$(!)
+fuses_$(1):
+ if [ ! -z "$$($(1)_efuse)" ] ; then \
+ if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U efuse:w:$$($(1)_efuse):m ; then \
+ $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U efuse:w:$$($(1)_efuse):m ; \
+ fi \
+ fi
+ if [ ! -z "$$($(1)_hfuse)" ] ; then \
+ if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U hfuse:w:$$($(1)_hfuse):m ; then \
+ $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U hfuse:w:$$($(1)_hfuse):m ; \
+ fi \
+ fi
+ if [ ! -z "$$($(1)_lfuse)" ] ; then \
+ if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lfuse:w:$$($(1)_lfuse):m ; then \
+ $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lfuse:w:$$($(1)_lfuse):m ; \
+ fi \
+ fi
+ if [ ! -z "$$($(1)_lock)" ] ; then \
+ if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lock:w:$$($(1)_lock):m ; then \
+ $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lock:w:$$($(1)_lock):m ; \
+ fi \
+ fi
+
+$$(OUTDIR)/$(1).hex: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O ihex $$< $$@
+
+$$(OUTDIR)/$(1).s19: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O srec $$< $$@
+
+$$(OUTDIR)/$(1).bin: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O binary $$< $$@
+
+$$(OUTDIR)/$(1).obj: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O avrobj $$< $$@
+
+$$(OUTDIR)/$(1).rom: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O $$(FORMAT) $$< $$@
+# $$($(1)_OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" -O $$(FORMAT) $$< $$(@:.rom=.eep)
+
+endef
+
+# Generate build rules for all targets
+$(foreach t,$(TRG),$(eval $(call build_target,$(t))))
+
+# Generate Qt's moc files from headers
+# NOTE: moc totally sucks and can generate empty files for some error conditions,
+# leading to puzzling linker errors. Kill 'em and abort build.
+%_moc.cpp: %.h
+ $(MOC) -o $@ $<
+ if [ ! -s $< ]; then \
+ rm -f $@; \
+ exit 1; \
+ fi
+
+
+%.cof: %.elf
+ $(COFFCONVERT) -O coff-ext-avr $< $@
+# $(COFFCONVERT) -O coff-avr $< $@ # For use with AVRstudio 3
+
+#make instruction to delete created files
+clean: clean-recursive
+ -$(RM_R) $(OBJDIR)
+ -$(RM_R) $(OUTDIR)
+
+$(RECURSIVE_TARGETS):
+ @target=`echo $@ | sed s/-recursive//`; \
+ for dir in $(SUBDIRS); do \
+ if [ -e $$dir/configure.in ] || [ -e $$dir/configure.ac ] && [ ! -x $$dir/configure ]; then \
+ echo "Running autogen.sh in $$dir..."; \
+ ( cd $$dir && chmod a+x autogen.sh && ./autogen.sh && rm -f Makefile || exit 1 ); \
+ fi; \
+ if [ ! -e $$dir/Makefile ]; then \
+ if [ -e "$$dir/build-$(ARCH)" ]; then \
+ echo "Running build script in $$dir..."; \
+ ( cd $$dir && chmod a+x build && ./build || exit 1 ); \
+ else \
+ echo "Running configure in $$dir..."; \
+ ( cd $$dir && ./configure --prefix=$(PREFIX) || exit 1 ); \
+ fi; \
+ fi; \
+ $(MAKE) -C $$dir $$target || exit 1; \
+ done
+
+BUILDREV_H = buildrev.h
+
+ifeq ($(shell [ -e bertos/verstag.c ] && echo yes),yes)
+.PHONY: bumprev
+bumprev:
+ @buildnr=0; \
+ if [ -f $(BUILDREV_H) ]; then \
+ buildnr=`sed <"$(BUILDREV_H)" -n -e 's/#define VERS_BUILD \([0-9][0-9]*\)/\1/p'`; \
+ fi; \
+ buildnr=`expr $$buildnr + 1`; \
+ buildhost=`hostname`; \
+ echo "#define VERS_BUILD $$buildnr" >"$(BUILDREV_H)"; \
+ echo "#define VERS_HOST \"$$buildhost\"" >>"$(BUILDREV_H)"; \
+ echo "Building revision $$buildnr"
+else
+.PHONY: bumprev
+bumprev:
+
+endif
+
+# Include dependencies
+ifneq ($(strip $(OBJ)),)
+-include $(OBJ:%.o=%.d)
+endif
--- /dev/null
+#!/bin/bash
+#
+# Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+# All rights reserved.
+#
+# Author: Bernardo Innocenti <bernie@develer.com>
+#
+# $Id$
+#
+
+
+VERBOSE=1
+
+CC=gcc
+CFLAGS="-W -Wall -Wextra -I. -fno-builtin -D_DEBUG"
+
+CXX=g++
+CXXFLAGS="$CFLAGS"
+
+
+for test in `find . -name "*_test.*"`; do
+ [ $VERBOSE -gt 0 ] && echo "Running $test..."
+ case "$test" in
+ *.cpp)
+ $CXX $CXXFLAGS $test -o test || exit 1
+ ./test || exit 1
+ rm -f test
+ ;;
+ *.c)
+ $CC $CFLAGS $test -o test || exit 1
+ ./test || exit 1
+ rm -f test
+ ;;
+ esac
+done
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Define application version strings
+ */
+#include <verstag.h>
+
+/*
+ * "buildrev.h" is auto-generated by the build infrastructure,
+ * incrementing VERS_BUILD each time the project is rebuilt.
+ */
+#include "buildrev.h"
+
+const char vers_tag[] = VERS_TAG;
+const char vers_build_str[] = _STRINGIZE(VERS_BUILD);
+const char vers_host[] = VERS_HOST;
+const int vers_build_nr = VERS_BUILD;
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001, 2002, 2003 by Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Declare application version strings
+ */
+#ifndef DEVLIB_VERSTAG_H
+#define DEVLIB_VERSTAG_H
+
+#ifndef ARCH_CONFIG_H
+ #include <cfg/arch_config.h>
+#endif
+
+#define APP_NAME "Appname"
+#define APP_DESCRIPTION "Long application name description"
+#define APP_AUTHOR "Develer"
+#define APP_COPYRIGHT "Copyright 2006 Develer (http://www.develer.com/)"
+
+#if (ARCH & ARCH_FOO)
+ #define VERS_MAJOR 0
+ #define VERS_MINOR 1
+ #define VERS_REV 0
+ #define VERS_LETTER ""
+#elif (ARCH & ARCH_BAR)
+ #define VERS_MAJOR 0
+ #define VERS_MINOR 1
+ #define VERS_REV 0
+ #define VERS_LETTER ""
+#else
+ #error unknown architecture
+#endif
+
+/**
+ * If _SNAPSHOT is defined, \c VERS_TAG contains the build date
+ * date instead of a numeric version string.
+ */
+#define _SNAPSHOT
+
+#ifdef _DEBUG
+ #define VERS_DBG "D"
+#else
+ #define VERS_DBG ""
+#endif
+
+#define __STRINGIZE(x) #x
+#define _STRINGIZE(x) __STRINGIZE(x)
+
+/** Build application version string (i.e.: "1.7.0") */
+#define MAKE_VERS(maj,min,rev) _STRINGIZE(maj) "." _STRINGIZE(min) "." _STRINGIZE(rev) VERS_LETTER VERS_DBG
+#ifdef _SNAPSHOT
+ #define VERS_TAG "snapshot" " " __DATE__ " " __TIME__ " " VERS_LETTER " " VERS_DBG
+#else
+ #define VERS_TAG MAKE_VERS(VERS_MAJOR,VERS_MINOR,VERS_REV)
+#endif
+
+/** Build application version string suitable for MS windows resource files (i.e.: "1, 7, 0, 1") */
+#define MAKE_RCVERS(maj,min,rev,bld) _STRINGIZE(maj) ", " _STRINGIZE(min) ", " _STRINGIZE(rev) ", " _STRINGIZE(bld)
+#define RCVERSION_TAG MAKE_VERS(VERS_MAJOR,VERS_MINOR,VERS_REV)
+
+/** The revision string (contains VERS_TAG) */
+extern const char vers_tag[];
+
+/** Sequential build number (contains VERS_BUILD) */
+extern const int vers_build_nr;
+//extern const char vers_build_str[];
+
+/** Hostname of the machine used to build this binary (contains VERS_HOST) */
+extern const char vers_host[];
+
+#endif /* DEVLIB_VERSTAG_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001,2002,2003 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Set system configuration
- */
-
-
-#ifndef ARCH_CONFIG_H
-#define ARCH_CONFIG_H
-
-/**
- * \name Architectures
- * \{
- */
-#define ARCH_FOO (1<<0)
-#define ARCH_BAR (1<<1)
-#define ARCH_EMUL (1<<8)
-/*\}*/
-
-#endif /* ARCH_CONFIG_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001, 2002, 2003 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \brief Additional support macros for compiler independance
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef BERTOS_COMPILER_H
-#define BERTOS_COMPILER_H
-
-#include <cpu/detect.h>
-
-
-#if defined __GNUC__ && defined __GNUC_MINOR__
- #define GNUC_PREREQ(maj, min) \
- ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-#else
- #define GNUC_PREREQ(maj, min) 0
-#endif
-
-/* Some CW versions do not allow enabling C99 from the settings panel. */
-#if defined(__MWERKS__)
- #pragma c99 on
-#endif
-
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
- #define COMPILER_C99 1
-#else
- #define COMPILER_C99 0
-#endif
-
-
-/** Concatenate two different preprocessor tokens (allowing macros to expand) */
-#define PP_CAT(x,y) PP_CAT__(x,y)
-#define PP_CAT__(x,y) x ## y
-#define PP_CAT3(x,y,z) PP_CAT(PP_CAT(x,y),z)
-#define PP_CAT4(x,y,z,w) PP_CAT(PP_CAT3(x,y,z),w)
-#define PP_CAT5(x,y,z,w,j) PP_CAT(PP_CAT4(x,y,z,w),j)
-
-/** String-ize a token (allowing macros to expand) */
-#define PP_STRINGIZE(x) PP_STRINGIZE__(x)
-#define PP_STRINGIZE__(x) #x
-
-
-#if defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)
-
- #pragma language=extended
-
- #if CPU_ARM
-
- #define COMPILER_VARIADIC_MACROS 1
-
- #define INTERRUPT(x) __irq __arm void x (void)
- #define INLINE static inline
-
- /* Include some standard C89/C99 stuff */
- #include <stddef.h>
- #include <stdint.h>
- #include <stdbool.h>
-
- #elif CPU_I196
-
- // IAR has size_t as built-in type, but does not define this symbol.
- #define _SIZE_T_DEFINED
-
- #define INTERRUPT(x) interrupt [x]
- #define REGISTER shortad
- #define INLINE /* unsupported */
-
- /*
- * Imported from <longjmp.h>. Unfortunately, we can't just include
- * this header because it typedefs jmp_buf to be an array of chars.
- * This would allow the compiler to place the buffer on an odd address.
- * The CPU _should_ be able to perform word accesses to
- * unaligned data, but there are *BUGS* in the 80196KC with
- * some combinations of opcodes and addressing modes. One of
- * these, "ST SP,[?GR]+" is used in the longjmp() implementation
- * provided by the IAR compiler ANSI C library. When ?GR contains
- * an odd address, surprisingly the CPU will copy the high order
- * byte of the source operand (SP) in the low order byte of the
- * destination operand (the memory location pointed to by ?GR).
- *
- * We also need to replace the library setjmp()/longjmp() with
- * our own versions because the IAR implementation "forgets" to
- * save the contents of local registers (?LR).
- */
- struct _JMP_BUF
- {
- void *sp; /* Stack pointer */
- void *return_addr; /* Return address */
- int lr[6]; /* 6 local registers */
- };
-
- typedef struct _JMP_BUF jmp_buf[1];
-
- int setjmp(jmp_buf env);
- void longjmp(jmp_buf env, int val);
-
- /* Fake bool support */
- #define true (1==1)
- #define false (1!=1)
- typedef unsigned char bool;
-
- #else
- #error Unsupported CPU
- #endif
-
-#elif defined(_MSC_VER) /* Win32 emulation support */
-
- /* MSVC doesn't provide <stdbool.h>. */
- #ifndef __cplusplus
- #define true (1==1)
- #define false (1!=1)
- typedef int bool;
- #endif /* !__cplusplus */
-
- /* These C99 functions are oddly named in MSVCRT32.lib */
- #define snprintf _snprintf
- #define vsnprintf _vsnprintf
-
- /* MSVC doesn't support C99's __func__, but has a similar extension. */
- #define __func__ __FUNCTION__
-
- /* MSVC doesn't support C99's inline keyword */
- #ifndef __cplusplus
- #define INLINE __inline
- #endif
-
-#elif defined(__GNUC__)
-
- /* Compiler features */
- #define COMPILER_VARIADIC_MACROS 1 /* Even in C++ */
- #define COMPILER_TYPEOF 1
- #define COMPILER_STATEMENT_EXPRESSIONS 1
-
- /* GCC attributes */
- #define FORMAT(type,fmt,first) __attribute__((__format__(type, fmt, first)))
- #define NORETURN __attribute__((__noreturn__))
- #define UNUSED_ARG(type,arg) __attribute__((__unused__)) type arg
- #define UNUSED_VAR(type,name) __attribute__((__unused__)) type name
- #define USED_VAR(type,name) __attribute__((__used__)) type name
- #define INLINE static inline __attribute__((__always_inline__))
- #define LIKELY(x) __builtin_expect(!!(x), 1)
- #define UNLIKELY(x) __builtin_expect(!!(x), 0)
- #define PURE_FUNC __attribute__((pure))
- #define CONST_FUNC __attribute__((const))
- #define UNUSED_FUNC __attribute__((unused))
- #define USED_FUNC __attribute__((__used__))
- #define RESTRICT __restrict__
- #define MUST_CHECK __attribute__((warn_unused_result))
- #define PACKED __attribute__((packed))
- /**
- * Force compiler to realod context variable.
- */
- #define MEMORY_BARRIER asm volatile ("" : : : "memory")
-
- #if GNUC_PREREQ(3,1)
- #define DEPRECATED __attribute__((__deprecated__))
- #endif
-
- #ifndef __cplusplus
- #define ASSERT_TYPE_EQUAL(var1, var2) \
- STATIC_ASSERT(__builtin_types_compatible_p(typeof(var1), typeof(var2)))
- #define ASSERT_TYPE_IS(var, type) \
- STATIC_ASSERT(__builtin_types_compatible_p(typeof(var), type))
- #endif
-
- /* Include some standard C89/C99 stuff */
- #include <stddef.h>
- #include <stdint.h>
- #include <stdbool.h>
- #if !CPU_AVR
- #include <sys/types.h> /* for ssize_t */
- #endif
-
- #ifndef __cplusplus
- /*
- * Disallow some C++ keywords as identifiers in C programs,
- * for improved portability.
- */
- #pragma GCC poison new delete class template typename
- #pragma GCC poison private protected public operator
- #pragma GCC poison friend mutable using namespace
- #pragma GCC poison cin cout cerr clog
- #endif
-
-
-
-#elif defined(__MWERKS__)
-
- /* Compiler features */
- #define COMPILER_VARIADIC_MACROS 1
- #define COMPILER_TYPEOF 1
- #define COMPILER_STATEMENT_EXPRESSIONS 1
-
- #define typeof __typeof__
-
- #define UNUSED_ARG(type,arg) type
-
- #include <stddef.h>
- #include <stdint.h>
- #include <stdbool.h>
-
- // CodeWarrior has size_t as built-in type, but does not define this symbol.
- #define _SIZE_T_DEFINED
-
-#else
- #error unknown compiler
-#endif
-
-
-/* Defaults for compiler extensions. */
-
-/**
- * \def COMPILER_VARIADIC_MACROS
- * Support for macros with variable arguments.
- */
-#ifndef COMPILER_VARIADIC_MACROS
-#define COMPILER_VARIADIC_MACROS (COMPILER_C99 != 0)
-#endif
-
-/**
- * \def COMPILER_TYPEOF
- * Support for dynamic type identification.
- */
-#ifndef COMPILER_TYPEOF
-#define COMPILER_TYPEOF 0
-#endif
-
-/**
- * \def COMPILER_STATEMENT_EXPRESSIONS
- * Support for statement expressions.
- */
-#ifndef COMPILER_STATEMENT_EXPRESSIONS
-#define COMPILER_STATEMENT_EXPRESSIONS 0
-#endif
-
-/* A few defaults for missing compiler features. */
-#ifndef INLINE
-#define INLINE static inline
-#endif
-#ifndef NORETURN
-#define NORETURN /* nothing */
-#endif
-#ifndef FORMAT
-#define FORMAT(type,fmt,first) /* nothing */
-#endif
-#ifndef DEPRECATED
-#define DEPRECATED /* nothing */
-#endif
-#ifndef UNUSED_ARG
-#define UNUSED_ARG(type,arg) type arg
-#endif
-#define UNUSED UNUSED_ARG /* OBSOLETE */
-#ifndef UNUSED_VAR
-#define UNUSED_VAR(type,name) type name
-#endif
-#ifndef USED_VAR
-#define USED_VAR(type,name) type name
-#endif
-#ifndef REGISTER
-#define REGISTER /* nothing */
-#endif
-#ifndef LIKELY
-#define LIKELY(x) x
-#endif
-#ifndef UNLIKELY
-#define UNLIKELY(x) x
-#endif
-#ifndef PURE_FUNC
-#define PURE_FUNC /* nothing */
-#endif
-#ifndef CONST_FUNC
-#define CONST_FUNC /* nothing */
-#endif
-#ifndef UNUSED_FUNC
-#define UNUSED_FUNC /* nothing */
-#endif
-#ifndef USED_FUNC
-#define USED_FUNC /* nothing */
-#endif
-#ifndef RESTRICT
-#define RESTRICT /* nothing */
-#endif
-#ifndef MUST_CHECK
-#define MUST_CHECK /* nothing */
-#endif
-#ifndef PACKED
-#define PACKED /* nothing */
-#endif
-#ifndef MEMORY_BARRIER
-#define MEMORY_BARRIER /* nothing */
-#warning No memory barrier defined for select compiler. If you use the kernel check it.
-#endif
-
-
-/* Misc definitions */
-#ifndef NULL
-#define NULL (void *)0
-#endif
-#ifndef EOF
-#define EOF (-1)
-#endif
-
-/* Support for hybrid C/C++ applications. */
-#ifdef __cplusplus
- #define EXTERN_C extern "C"
- #define EXTERN_C_BEGIN extern "C" {
- #define EXTERN_C_END }
- #define EXTERN_CONST extern const
- #define CONST_CAST(TYPE,EXPR) (const_cast<TYPE>(EXPR))
-#else
- #define EXTERN_C extern
- #define EXTERN_C_BEGIN /* nothing */
- #define EXTERN_C_END /* nothing */
- #define EXTERN_CONST const
- #define CONST_CAST(TYPE,EXPR) ((TYPE)(EXPR)) /* FIXME: How can we suppress the warning in C? */
-#endif
-
-
-#if defined(_MSC_VER) \
- || ((defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)) && CPU_I196)
- /**
- * \name ISO C99 fixed-size types
- *
- * These should be in <stdint.h>, but a few compilers lack them.
- * \{
- */
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- typedef short int int16_t;
- typedef unsigned short int uint16_t;
- typedef long int int32_t; /* _WIN64 safe */
- typedef unsigned long int uint32_t; /* _WIN64 safe */
-
- #ifdef _MSC_VER
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
- #else
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
- #endif
- /* \} */
-#else
- /* This is the standard location. */
- #include <stdint.h>
-#endif
-
-#if CPU_AVR_ATMEGA8
- /*
- * The ATmega8 has a very small Flash, so we can't afford
- * to link in support routines for 32bit integer arithmetic.
- */
- typedef int16_t ticks_t; /**< Type for time expressed in ticks. */
- typedef int16_t mtime_t; /**< Type for time expressed in milliseconds. */
- typedef int16_t utime_t; /**< Type for time expressed in microseconds. */
- #define SIZEOF_MTIME_T (16 / CPU_BITS_PER_CHAR)
- #define SIZEOF_UTIME_T (16 / CPU_BITS_PER_CHAR)
- #define MTIME_INFINITE 0x7FFFL
-#else
- typedef int32_t ticks_t; /**< Type for time expressed in ticks. */
-
- typedef int32_t utime_t; /**< Type for time expressed in microseconds. */
- #define SIZEOF_UTIME_T (32 / CPU_BITS_PER_CHAR)
-
- #ifndef DEVLIB_MTIME_DEFINED
- #define DEVLIB_MTIME_DEFINED 1 /* Resolve conflict with <os/hptime.h> */
- typedef int32_t mtime_t; /**< Type for time expressed in milliseconds. */
- #define SIZEOF_MTIME_T (32 / CPU_BITS_PER_CHAR)
- #define MTIME_INFINITE 0x7FFFFFFFL
- #endif
-#endif
-
-/** Bulk storage large enough for both pointers or integers. */
-typedef void * iptr_t;
-
-/** Bulk storage large enough for both pointers to constants or integers. */
-typedef const void * const_iptr_t;
-
-typedef unsigned char sigbit_t; /**< Type for signal bits. */
-typedef unsigned char sigmask_t; /**< Type for signal masks. */
-typedef unsigned char page_t; /**< Type for banked memory pages. */
-
-
-/**
- * \name Standard type definitions.
- *
- * These should be in <sys/types.h> or <stddef.h>, but many compilers
- * and C libraries lack them.
- *
- * We check for some common definitions to avoid redefinitions:
- *
- * glibc, avr-libc: _SIZE_T_DEFINED, __ssize_t_defined
- * Darwin libc: _BSD_SIZE_T_DEFINED_, _SIZE_T
- * IAR ARM: _SIZE_T
- *
- * \{
- */
-#if !(defined(size_t) || defined(_SIZE_T_DEFINED) || defined(_BSD_SIZE_T_DEFINED_) \
- || defined(_SIZE_T))
- #if CPU_X86
- /* 32bit or 64bit (32bit for _WIN64). */
- typedef unsigned long size_t;
- #else
- #error Unknown CPU
- #endif
-#endif
-
-#if !(defined(ssize_t) || defined(_SSIZE_T) || defined(__ssize_t_defined))
- #if CPU_X86
- /* 32bit or 64bit (32bit for _WIN64). */
- typedef long ssize_t;
- #elif CPU_ARM
- typedef int ssize_t;
- #elif CPU_AVR
- /* 16bit (missing in avr-libc's sys/types.h). */
- typedef int ssize_t;
- #else
- #error Unknown CPU
- #endif
-#endif
-/*\}*/
-
-
-/**
- * \name Types for hardware registers.
- *
- * Only use these types for registers whose contents can
- * be changed asynchronously by external hardware.
- *
- * \{
- */
-#if CPU_DSP56K
- /* Registers can be accessed only through 16-bit pointers */
- typedef volatile uint16_t reg16_t;
-#else
- typedef volatile uint8_t reg8_t;
- typedef volatile uint16_t reg16_t;
- typedef volatile uint32_t reg32_t;
-#endif
-/*\}*/
-
-
-/* Quasi-ANSI macros */
-#ifndef offsetof
- /**
- * Return the byte offset of the member \a m in struct \a s.
- *
- * \note This macro should be defined in "stddef.h" and is sometimes
- * compiler-specific (g++ has a builtin for it).
- */
- #define offsetof(s,m) (size_t)&(((s *)0)->m)
-#endif
-#ifndef countof
- /**
- * Count the number of elements in the static array \a a.
- *
- * \note This macro is non-standard, but implements a very common idiom
- */
- #define countof(a) (sizeof(a) / sizeof(*(a)))
-#endif
-
-/**
- * Cast a member of a structure out to the containing structure.
- *
- * \param ptr the pointer to the member.
- * \param type the type of the container struct this is embedded in.
- * \param member the name of the member within the struct.
- */
-#if COMPILER_TYPEOF && COMPILER_STATEMENT_EXPRESSIONS
- #define containerof(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *_mptr = (ptr); /* type check */ \
- (type *)((char *)_mptr - offsetof(type, member)); \
- })
-#else
- #define containerof(ptr, type, member) \
- ( (type *)((char *)(ptr) - offsetof(type, member)) )
-#endif
-
-/** Issue a compilation error if the \a condition is false */
-#define STATIC_ASSERT(condition) \
- UNUSED_VAR(extern char, STATIC_ASSERTION_FAILED__[(condition) ? 1 : -1])
-
-#ifndef ASSERT_TYPE_EQUAL
- /** Ensure two variables have the same type. */
- #define ASSERT_TYPE_EQUAL(var1, var2) \
- do { (void)(&(var1) == &(var2)); } while(0)
-#endif
-
-#ifndef ASSERT_TYPE_IS
- /** Ensure variable is of specified type. */
- #define ASSERT_TYPE_IS(var, type) \
- do { (void)(&(var) == (type *)0); } while(0)
-#endif
-
-#endif /* BERTOS_COMPILER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Simple debug facilities for hosted and embedded C/C++ applications.
- *
- * Debug output goes to stderr in hosted applications.
- * Freestanding (AKA embedded) applications use \c drv/kdebug.c to output
- * diagnostic messages to a serial terminal or a JTAG debugger.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef DEVLIB_DEBUG_H
-#define DEVLIB_DEBUG_H
-
-#include <cfg/os.h>
-#include <cfg/compiler.h>
-
-
-/*
- * Defaults for rarely used config stuff.
- */
-#ifndef CONFIG_KDEBUG_DISABLE_TRACE
-#define CONFIG_KDEBUG_DISABLE_TRACE 0
-#endif
-
-#ifndef CONFIG_KDEBUG_ASSERT_NO_TEXT
-#define CONFIG_KDEBUG_ASSERT_NO_TEXT 0
-#endif
-
-#if defined(__doxygen__)
- /**
- * Preprocessor symbol defined only for debug builds.
- *
- * The build infrastructure must arrange for _DEBUG to
- * be predefined for all the source files being compiled.
- *
- * This is compatible with the MSVC convention for the
- * default Debug and Release project targets.
- */
- #define _DEBUG 1
-#endif
-
-#ifdef _DEBUG
-
- // STLport specific: enable extra checks
- #define __STL_DEBUG 1
-
- // MSVC specific: Enable memory allocation debug
- #if defined(_MSC_VER)
- #include <crtdbg.h>
- #endif
-
- /*
- * On UNIX systems the extabilished practice is to define
- * NDEBUG for release builds and nothing for debug builds.
- */
- #ifdef NDEBUG
- #undef NDEBUG
- #endif
-
- /**
- * This macro duplicates the old MSVC trick of redefining
- * THIS_FILE locally to avoid the overhead of many duplicate
- * strings in ASSERT().
- */
- #ifndef THIS_FILE
- #define THIS_FILE __FILE__
- #endif
-
- /**
- * This macro can be used to conditionally exclude one or more
- * statements conditioned on \c _DEBUG, avoiding the clutter
- * of ifdef/endif pairs.
- *
- * \code
- * struct FooBar
- * {
- * int foo;
- * bool bar;
- * DB(int ref_count;) // Track number of users
- *
- * void release()
- * {
- * DB(--ref_count;)
- * }
- * };
- * \endcode
- */
- #define DB(x) x
-
- #include <appconfig.h> /* CONFIG_KDEBUG_ASSERT_NO_TEXT */
- #include <cpu/attr.h> /* CPU_HARVARD */
-
- /* These are implemented in drv/kdebug.c */
- void kdbg_init(void);
- void kputchar(char c);
- int kputnum(int num);
- void kdump(const void *buf, size_t len);
- void __init_wall(long *wall, int size);
-
- #if CPU_HARVARD
- #include <mware/pgm.h>
- void kputs_P(const char *PROGMEM str);
- void kprintf_P(const char *PROGMEM fmt, ...) FORMAT(__printf__, 1, 2);
- int __assert_P(const char *PROGMEM cond, const char *PROGMEM file, int line);
- void __trace_P(const char *func);
- void __tracemsg_P(const char *func, const char *PROGMEM fmt, ...);
- int __invalid_ptr_P(void *p, const char *PROGMEM name, const char *PROGMEM file, int line);
- int __check_wall_P(long *wall, int size, const char * PGM_ATTR name, const char * PGM_ATTR file, int line);
- #define kputs(str) kputs_P(PSTR(str))
- #define kprintf(fmt, ...) kprintf_P(PSTR(fmt) ,## __VA_ARGS__)
- #define __assert(cond, file, line) __assert_P(PSTR(cond), PSTR(file), (line))
- #define __trace(func) __trace_P(func)
- #define __tracemsg(func, fmt, ...) __tracemsg_P(func, PSTR(fmt), ## __VA_ARGS__)
- #define __invalid_ptr(p, name, file, line) __invalid_ptr_P((p), PSTR(name), PSTR(file), (line))
- #define __check_wall(wall, size, name, file, line) __check_wall_P(wall, size, PSTR(name), PSTR(file), (line))
- #else /* !CPU_HARVARD */
- void kputs(const char *str);
- void kprintf(const char *fmt, ...) FORMAT(__printf__, 1, 2);
- int __assert(const char *cond, const char *file, int line);
- void __trace(const char *func);
- void __tracemsg(const char *func, const char *fmt, ...) FORMAT(__printf__, 2, 3);
- int __invalid_ptr(void *p, const char *name, const char *file, int line);
- int __check_wall(long *wall, int size, const char *name, const char *file, int line);
- #endif /* !CPU_HARVARD */
-
- #if !CONFIG_KDEBUG_ASSERT_NO_TEXT
- #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __assert(#x, THIS_FILE, __LINE__)))
- #define ASSERT2(x, help) ((void)(LIKELY(x) ? 0 : __assert(help " (" #x ")", THIS_FILE, __LINE__)))
- #else
- #define ASSERT(x) ((void)(LIKELY(x) ? 0 : __assert("", THIS_FILE, __LINE__)))
- #define ASSERT2(x, help) ((void)ASSERT(x))
- #endif
-
- /**
- * Check that the given pointer is either NULL or pointing to valid memory.
- *
- * The assumption here is that valid pointers never point to low
- * memory regions. This helps catching pointers taken from
- * struct/class memebers when the struct pointer was NULL.
- */
- #define ASSERT_VALID_PTR(p) ((void)(LIKELY((p) >= 0x200) ? 0 : __invalid_ptr(p, #p, THIS_FILE, __LINE__)))
-
- /**
- * Check that the given pointer is not pointing to invalid memory.
- *
- * \see ASSERT_VALID_PTR()
- */
- #define ASSERT_VALID_PTR_OR_NULL(p) ((void)(LIKELY((p == NULL) || ((p) >= 0x200)) ? 0 : __invalid_ptr((p), #p, THIS_FILE, __LINE__)))
-
- #if !CONFIG_KDEBUG_DISABLE_TRACE
- #define TRACE __trace(__func__)
- #define TRACEMSG(msg,...) __tracemsg(__func__, msg, ## __VA_ARGS__)
- #else
- #define TRACE do {} while(0)
- #define TRACEMSG(...) do {} while(0)
- #endif
-
- /**
- * \name Walls to detect data corruption
- * \{
- */
- #define WALL_SIZE 8
- #define WALL_VALUE (long)0xABADCAFEL
- #define DECLARE_WALL(name,size) long name[(size) / sizeof(long)];
- #define FWD_DECLARE_WALL(name,size) extern long name[(size) / sizeof(long)];
- #define INIT_WALL(name) __init_wall((name), countof(name))
- #define CHECK_WALL(name) __check_wall((name), countof(name), #name, THIS_FILE, __LINE__)
- /*\}*/
-
- /**
- * Check that the given pointer actually points to an object
- * of the specified type.
- */
- #define ASSERT_VALID_OBJ(_t, _o) do { \
- ASSERT_VALID_PTR((_o)); \
- ASSERT(dynamic_cast<_t>((_o)) != NULL); \
- }
-
- /**
- * \name Debug object creation and destruction.
- *
- * These macros help track some kinds of leaks in C++ programs.
- * Usage is as follows:
- *
- * \code
- * class Foo
- * {
- * DECLARE_INSTANCE_TRACKING(Foo)
- *
- * Foo()
- * {
- * NEW_INSTANCE(Foo);
- * // ...
- * }
- *
- * ~Foo()
- * {
- * DELETE_INSTANCE(Foo);
- * // ...
- * }
- * };
- *
- * // Put this in the implementation file of the class
- * IMPLEMENT_INSTANCE_TRACKING(Foo)
- *
- * // Client code
- * int main(void)
- * {
- * Foo *foo = new Foo;
- * cout << GET_INSTANCE_COUNT(Foo) << endl; // prints "1"
- * delete foo;
- * ASSERT_ZERO_INSTANCES(Foo); // OK
- * }
- * \endcode
- * \{
- */
- #define NEW_INSTANCE(CLASS) do { ++CLASS::__instances } while (0)
- #define DELETE_INSTANCE(CLASS) do { --CLASS::__instances } while (0)
- #define ASSERT_ZERO_INSTANCES(CLASS) ASSERT(CLASS::__instances == 0)
- #define GET_INSTANCE_COUNT(CLASS) (CLASS::__instances)
- #define DECLARE_INSTANCE_TRACKING(CLASS) static int __instances
- #define IMPLEMENT_INSTANCE_TRACKING(CLASS) int CLASS::__instances = 0
- /*\}*/
-
-#else /* !_DEBUG */
-
- /*
- * On UNIX systems the extabilished practice is to define
- * NDEBUG for release builds and nothing for debug builds.
- */
- #ifndef NDEBUG
- #define NDEBUG 1
- #endif
-
- #define DB(x) /* nothing */
- #ifndef ASSERT
- #define ASSERT(x) ((void)0)
- #endif /* ASSERT */
- #define ASSERT2(x, help) ((void)0)
- #define ASSERT_VALID_PTR(p) ((void)0)
- #define ASSERT_VALID_PTR_OR_NULL(p) ((void)0)
- #define ASSERT_VALID_OBJ(_t, _o) ((void)0)
- #define TRACE do {} while (0)
- #if COMPILER_VARIADIC_MACROS
- #define TRACEMSG(x, ...) do {} while (0)
- #else
- INLINE void TRACEMSG(UNUSED_ARG(const char *, msg), ...)
- {
- /* NOP */
- }
- #endif
-
- #define DECLARE_WALL(name, size) /* nothing */
- #define FWD_DECLARE_WALL(name, size) /* nothing */
- #define INIT_WALL(name) do {} while (0)
- #define CHECK_WALL(name) do {} while (0)
-
- #define NEW_INSTANCE(CLASS) do {} while (0)
- #define DELETE_INSTANCE(CLASS) do {} while (0)
- #define ASSERT_ZERO_INSTANCES(CLASS) do {} while (0)
- #define GET_INSTANCE_COUNT(CLASS) ERROR_ONLY_FOR_DEBUG
- #define DECLARE_INSTANCE_TRACKING(CLASS)
- #define IMPLEMENT_INSTANCE_TRACKING(CLASS)
-
- INLINE void kdbg_init(void) { /* nop */ }
- INLINE void kputchar(UNUSED_ARG(char, c)) { /* nop */ }
- INLINE int kputnum(UNUSED_ARG(int, num)) { return 0; }
- INLINE void kputs(UNUSED_ARG(const char *, str)) { /* nop */ }
- INLINE void kdump(UNUSED_ARG(const void *, buf), UNUSED_ARG(size_t, len)) { /* nop */ }
-
- #if defined(__cplusplus) && COMPILER_VARIADIC_MACROS
- /* G++ can't inline functions with variable arguments... */
- #define kprintf(fmt,...) do { (void)(fmt); } while(0)
- #else
- /* ...but GCC can. */
- INLINE void kprintf(UNUSED_ARG(const char *, fmt), ...) { /* nop */ }
- #endif
-
-#endif /* _DEBUG */
-
-#endif /* DEVLIB_DEBUG_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Common and handy function macros
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- */
-#ifndef CFG_MACROS_H
-#define CFG_MACROS_H
-
-#include <cfg/compiler.h>
-
-/* avr-gcc does not seem to support libstdc++ */
-#if defined(__cplusplus) && !CPU_AVR
- /* Type-generic macros implemented with template functions. */
- #include <algorithm>
-
- template<class T> inline T ABS(T n) { return n >= 0 ? n : -n; }
- #define MIN(a,b) std::min(a, b)
- #define MAX(a,b) std::max(a, b)
- #define SWAP(a,b) std::swap(a, b)
-#elif (COMPILER_STATEMENT_EXPRESSIONS && COMPILER_TYPEOF)
- /* Type-generic macros implemented with statement expressions. */
- #define ABS(n) ({ \
- typeof(n) _n = (n); \
- (_n < 0) ? -_n : _n; \
- })
- #define MIN(a,b) ({ \
- typeof(a) _a = (a); \
- typeof(b) _b = (b); \
- ASSERT_TYPE_EQUAL(_a, _b); \
- /** \
- * The (typeof(_a)) cast in necessary: \
- * result type of conditional expressions is \
- * *NOT* the type of the value returned but \
- * the type that would be produced if _a and _b \
- * were mixed in an expression. \
- * Even in _a and _b are of the same type, \
- * if mixed in an expression the type will be \
- * promoted to int! \
- */ \
- ((typeof(_a))((_a < _b) ? _a : _b)); \
- })
- #define MAX(a,b) ({ \
- typeof(a) _a = (a); \
- typeof(b) _b = (b); \
- ASSERT_TYPE_EQUAL(_a, _b); \
- /** \
- * The (typeof(_a)) cast in necessary: \
- * result type of conditional expressions is \
- * *NOT* the type of the value returned but \
- * the type that would be produced if _a and _b \
- * were mixed in an expression. \
- * Even in _a and _b are of the same type, \
- * if mixed in an expression the type will be \
- * promoted to int! \
- */ \
- ((typeof(_a))((_a > _b) ? _a : _b)); \
- })
-#else /* !(COMPILER_STATEMENT_EXPRESSIONS && COMPILER_TYPEOF) */
- /* Buggy macros for inferior compilers. */
- #define ABS(a) (((a) < 0) ? -(a) : (a))
- #define MIN(a,b) (((a) < (b)) ? (a) : (b))
- #define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif /* !(COMPILER_STATEMENT_EXPRESSIONS && COMPILER_TYPEOF) */
-
-/** Bound \a x between \a min and \a max. */
-#define MINMAX(min,x,max) (MIN(MAX(min, x), max))
-
-#ifdef __cplusplus
- /* Use standard implementation from <algorithm> */
- #define SWAP(a,b) std::swap(a, b)
-#elif COMPILER_TYPEOF
- /**
- * Type-generic macro to swap \a a with \a b.
- *
- * \note Arguments are evaluated multiple times.
- */
- #define SWAP(a, b) \
- do { \
- typeof(a) tmp; \
- ASSERT_TYPE_EQUAL(a, b); \
- tmp = (a); \
- (a) = (b); \
- (b) = tmp; \
- } while (0)
-#else /* !COMPILER_TYPEOF */
- /* Sub-optimal implementation that only works with integral types. */
- #define SWAP(a, b) \
- do { \
- (a) ^= (b); \
- (b) ^= (a); \
- (a) ^= (b); \
- } while (0)
-
-#endif /* COMPILER_TYPEOF */
-
-/**
- * Macro to swap \a a with \a b, with explicit type \a T for dumb C89 compilers.
- *
- * \note Arguments are evaluated multiple times.
- */
-#define SWAP_T(a, b, T) \
- do { \
- T tmp; \
- ASSERT_TYPE_IS(a, T); \
- ASSERT_TYPE_IS(b, T); \
- tmp = (a); \
- (a) = (b); \
- (b) = tmp; \
- } while (0)
-
-
-#ifndef BV
- /** Convert a bit value to a binary flag. */
- #define BV(x) (1<<(x))
-#endif
-
-/** Same as BV() but with 32 bit result */
-#define BV32(x) ((uint32_t)1<<(x))
-
-/** Same as BV() but with 16 bit result */
-#define BV16(x) ((uint16_t)1<<(x))
-
-/** Same as BV() but with 8 bit result */
-#define BV8(x) ((uint8_t)1<<(x))
-
-/**
- * Perform an integer division rounding the result to the nearest int value.
- * \note \a divisor should preferibly be a costant, otherwise this macro generates
- * 2 division. Also divisor is evaluated twice.
- */
-#define DIV_ROUND(dividend, divisor) (((dividend) + (divisor) / 2) / (divisor))
-
-/** Round up \a x to an even multiple of the 2's power \a pad. */
-#define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
-
-/* OBSOLETE */
-#define ROUND2 ROUND_UP2
-
-/**
- * \name Integer round macros.
- *
- * Round \a x to a multiple of \a base.
- * \note If \a x is signed these macros generate a lot of code.
- * \{
- */
-#define ROUND_DOWN(x, base) ( (x) - ((x) % (base)) )
-#define ROUND_UP(x, base) ( ((x) + (base) - 1) - (((x) + (base) - 1) % (base)) )
-#define ROUND_NEAREST(x, base) ( ((x) + (base) / 2) - (((x) + (base) / 2) % (base)) )
-/* \} */
-
-/** Check if \a x is an integer power of 2. */
-#define IS_POW2(x) (!(bool)((x) & ((x)-1)))
-
-/** Calculate a compile-time log2 for a uint8_t */
-#define UINT8_LOG2(x) \
- ((x) < 2 ? 0 : \
- ((x) < 4 ? 1 : \
- ((x) < 8 ? 2 : \
- ((x) < 16 ? 3 : \
- ((x) < 32 ? 4 : \
- ((x) < 64 ? 5 : \
- ((x) < 128 ? 6 : 7)))))))
-
-/** Calculate a compile-time log2 for a uint16_t */
-#define UINT16_LOG2(x) \
- ((x < 256) ? UINT8_LOG2(x) : UINT8_LOG2((x) >> 8) + 8)
-
-/** Calculate a compile-time log2 for a uint32_t */
-#define UINT32_LOG2(x) \
- ((x < 65536UL) ? UINT16_LOG2(x) : UINT16_LOG2((x) >> 16) + 16)
-
-#if COMPILER_VARIADIC_MACROS
- /** Count the number of arguments (up to 16). */
- #define PP_COUNT(...) \
- PP_COUNT__(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
- #define PP_COUNT__(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,count,...) \
- count
-#endif
-
-#if COMPILER_VARIADIC_MACROS
- /**
- * \def BIT_CHANGE(reg, (mask, value), ...)
- *
- * This macro allows for efficient and compact bit toggling in a hardware
- * register. It is meant to replace hand-coded cruft which toggles bits
- * in sequence.
- *
- * It is possible to specify an unlimited pair of (mask, value) parameters.
- * For instance:
- *
- * \code
- * void set_timer(bool start)
- * {
- * BIT_CHANGE(REG_CTRL_TIMER,
- * (TIMER_MODE, MODE_COUNT),
- * (OVL_IRQ, 1),
- * (CMP_IRQ, 1),
- * (START, start)
- * );
- * }
- * \endcode
- *
- * The macro expansion will be roughly the following:
- *
- * \code
- * REG_CTRL_TIMER = (REG_CTRL_TIMER & ~(TIMER_MODE|OVL_IRQ|CMP_IRQ|START)
- * | (MODE_COUNT|OVL_IRQ|CMP_IRQ|(start ? START : 0));
- * \endcode
- *
- * It is up to the compiler to produce the optimal code. We checked that GCC produces
- * the best code in most cases. We preferred this expansion over the use of a block
- * with a local variable because CodeWarrior 6.1 was not able to remove completely the
- * allocation of the local from the stack.
- *
- * \note This macro is available only in C99 because it makes use of variadic macros.
- * It would be possible to make up an implementation with a slightly different syntax
- * for use with C90 compilers, through Boost Preprocessor.
- */
-
- /**
- * \def BIT_CHANGE_BV(reg, (bit, value), ...)
- *
- * Similar to BIT_CHANGE(), but get bits instead of masks (and applies BV() to convert
- * them to masks).
- */
-
- #define BIT_EXTRACT_FLAG_0(bit, value) bit
- #define BIT_EXTRACT_FLAG_1(bit, value) BV(bit)
- #define BIT_EXTRACT_VALUE__(bit, value) value
-
- #define BIT_MASK_SINGLE__(use_bv, index, max, arg) \
- ((index < max) ? (PP_CAT(BIT_EXTRACT_FLAG_, use_bv) arg) : 0) \
- /**/
-
- #define BIT_MASK_IF_SINGLE__(use_bv, index, max, arg) \
- (((index < max) && (BIT_EXTRACT_VALUE__ arg)) ? (PP_CAT(BIT_EXTRACT_FLAG_, use_bv) arg) : 0) \
- /**/
-
- #define BIT_ITER__2(macro, use_bv, max, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15, ...) \
- (macro(use_bv, 0, max, a0) | \
- macro(use_bv, 1, max, a1) | \
- macro(use_bv, 2, max, a2) | \
- macro(use_bv, 3, max, a3) | \
- macro(use_bv, 4, max, a4) | \
- macro(use_bv, 5, max, a5) | \
- macro(use_bv, 6, max, a6) | \
- macro(use_bv, 7, max, a7) | \
- macro(use_bv, 8, max, a8) | \
- macro(use_bv, 9, max, a9) | \
- macro(use_bv, 10, max, a10) | \
- macro(use_bv, 11, max, a11) | \
- macro(use_bv, 12, max, a12) | \
- macro(use_bv, 13, max, a13) | \
- macro(use_bv, 14, max, a14) | \
- macro(use_bv, 15, max, a15)) \
- /**/
-
- #define BIT_ITER__(macro, use_bv, ...) \
- BIT_ITER__2(macro, use_bv, PP_COUNT(__VA_ARGS__), __VA_ARGS__, (0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1)) \
- /**/
-
- #define BIT_MASKS__(use_bv, ...) \
- BIT_ITER__(BIT_MASK_SINGLE__, use_bv, __VA_ARGS__)
- /**/
-
- #define BIT_MASKS_CONDITIONAL__(use_bv, ...) \
- BIT_ITER__(BIT_MASK_IF_SINGLE__, use_bv, __VA_ARGS__)
- /**/
-
- #define BIT_CHANGE__(reg, use_bv, ...) \
- ((reg) = ((reg) & ~BIT_MASKS__(use_bv, __VA_ARGS__)) | BIT_MASKS_CONDITIONAL__(use_bv, __VA_ARGS__)) \
- /**/
-
- #define BIT_CHANGE(reg, ...) BIT_CHANGE__(reg, 0, __VA_ARGS__)
- #define BIT_CHANGE_BV(reg, ...) BIT_CHANGE__(reg, 1, __VA_ARGS__)
-
-#endif /* COMPILER_VARIADIC_MACROS */
-
-/**
- * Macro for rotating bit left or right.
- * \{
- */
-#define ROTR(var, rot) (((var) >> (rot)) | ((var) << ((sizeof(var) * 8) - (rot))))
-#define ROTL(var, rot) (((var) << (rot)) | ((var) >> ((sizeof(var) * 8) - (rot))))
-/*\}*/
-
-/**
- * Make an id from 4 letters, useful for
- * file formats and kfile ids.
- */
-#define MAKE_ID(a,b,c,d) \
- ( ((uint32_t)(a) << 24) \
- | ((uint32_t)(b) << 16) \
- | ((uint32_t)(c) << 8) \
- | ((uint32_t)(d) << 0) )
-
-/**
- * Type for id generated by MAKE_ID().
- */
-typedef uint32_t id_t;
-
-#endif /* MACROS_H */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Debug macros for inter-module dependency checking.
- *
- * These macros expand to nothing in release builds. In debug
- * builds, they perform run-time dependency checks for modules.
- *
- * The usage pattern looks like this:
- *
- * \code
- * MOD_DEFINE(phaser)
- *
- * void phaser_init(void)
- * {
- * MOD_CHECK(computer);
- * MOD_CHECK(warp_core);
- *
- * [...charge weapons...]
- *
- * MOD_INIT(phaser);
- * }
- *
- * void phaser_cleanup(void)
- * {
- * MOD_CLEANUP(phaser);
- *
- * [...disarm phaser...]
- * }
- * \endcode
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-#ifndef CFG_MODULE_H
-#define CFG_MODULE_H
-
-#include <cfg/debug.h>
-
-/**
- * Declare a global variable for module dependency check.
- *
- * \see MOD_INIT(), MOD_CHECK()
- */
-#define MOD_DEFINE(module) DB(extern bool module ## _initialized; bool module ## _initialized;)
-
-/**
- * Check that \a module was already initialized.
- *
- * Put this check just before accessing any facility
- * provided by a module that requires prior initialization.
- *
- * \see MOD_INIT()
- */
-
-#define MOD_CHECK(module) \
-do { \
- DB(extern bool module ## _initialized;) \
- ASSERT(module ## _initialized); \
-} while (0)
-
-/**
- * Mark module as initialized.
- *
- * Marking initialization requires the global data
- * previously defined by MOD_DEFINE().
- *
- * To prevent double initialization bugs, an initialized
- * module must first be cleaned up with MOD_CLEANUP() before
- * calling MOD_INIT() another time.
- *
- * \see MOD_CLEANUP(), MOD_CHECK(), MOD_DEFINE()
- */
-#define MOD_INIT(module) \
-do { \
- ASSERT(!module ## _initialized); \
- DB(module ## _initialized = true;) \
-} while (0)
-
-/**
- * Mark module as being no longer initialized.
- *
- * Marking initialization requires the global data
- * previously defined by MOD_DEFINE().
- *
- * \see MOD_INIT(), MOD_CHECK(), MOD_DEFINE()
- */
-#define MOD_CLEANUP(module) \
-do { \
- ASSERT(module ## _initialized); \
- DB(module ## _initialized = false;) \
-} while (0)
-
-#endif /* CFG_MODULE_H */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief OS-specific definitions
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef DEVLIB_OS_H
-#define DEVLIB_OS_H
-
-/** Macro to include OS-specific versions of the headers. */
-#define OS_HEADER(module) PP_STRINGIZE(PP_CAT3(module, _, OS_ID).h)
-#define OS_CSOURCE(module) PP_STRINGIZE(PP_CAT3(module, _, OS_ID).c)
-
-/*
- * OS autodetection (Some systems trigger multiple OS definitions)
- */
-#ifdef _WIN32
- #define OS_WIN32 1
- #define OS_ID win32
-
- // FIXME: Maybe disable Win32 exceptions?
- typedef int cpuflags_t;
- #define IRQ_DISABLE /* FIXME */
- #define IRQ_ENABLE /* FIXME */
- #define IRQ_SAVE_DISABLE(old_sigs) /* FIXME */
- #define IRQ_RESTORE(old_sigs) /* FIXME */
-
-#else
- #define OS_WIN32 0
-#endif
-
-#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
- #define OS_UNIX 1
- #define OS_POSIX 1 /* Not strictly UNIX, but no way to autodetect it. */
- #define OS_ID posix
-
- /*
- * The POSIX moral equivalent of disabling IRQs is disabling signals.
- */
- #include <signal.h>
- typedef sigset_t cpuflags_t;
-
- #define SET_ALL_SIGNALS(sigs) \
- do { \
- sigfillset(&sigs); \
- sigdelset(&sigs, SIGINT); \
- sigdelset(&sigs, SIGSTOP); \
- sigdelset(&sigs, SIGCONT); \
- } while(0)
-
- #define IRQ_DISABLE \
- do { \
- sigset_t sigs; \
- SET_ALL_SIGNALS(sigs); \
- sigprocmask(SIG_BLOCK, &sigs, NULL); \
- } while (0)
-
- #define IRQ_ENABLE \
- do { \
- sigset_t sigs; \
- SET_ALL_SIGNALS(sigs); \
- sigprocmask(SIG_UNBLOCK, &sigs, NULL); \
- } while (0)
-
- #define IRQ_SAVE_DISABLE(old_sigs) \
- do { \
- sigset_t sigs; \
- SET_ALL_SIGNALS(sigs); \
- sigprocmask(SIG_BLOCK, &sigs, &old_sigs); \
- } while (0)
-
- #define IRQ_RESTORE(old_sigs) \
- do { \
- sigprocmask(SIG_SETMASK, &old_sigs, NULL); \
- } while (0)
-
- #define IRQ_ENABLED() \
- ({ \
- sigset_t sigs; \
- sigprocmask(SIG_SETMASK, NULL, &sigs); \
- sigismember(&sigs, SIGALRM) ? false : true; \
- })
-
-#else
- #define OS_UNIX 0
- #define OS_POSIX 0
-#endif
-
-#ifdef __linux__
- #define OS_LINUX 1
-#else
- #define OS_LINUX 0
-#endif
-
-#if defined(__APPLE__) && defined(__MACH__)
- #define OS_DARWIN 1
-#else
- #define OS_DARWIN 0
-#endif
-
-/*
- * We want Qt and other frameworks to look like OSes because you would
- * tipically want their portable abstractions if you're using one of these.
- */
-#if defined(_QT)
- #define OS_QT 1
- #undef OS_ID
- #define OS_ID qt
-#else
- #define OS_QT 0
-#endif
-
-/*
- * Summarize hosted environments as OS_HOSTED and embedded
- * environment with OS_EMBEDDED.
- */
-#if OS_WIN32 || OS_UNIX || OS_DARWIN || OS_QT
- #define OS_HOSTED 1
- #define OS_EMBEDDED 0
-#else
- #define OS_HOSTED 0
- #define OS_EMBEDDED 1
-
- /* Embedded environments fall back to CPU-specific code. */
- #define OS_ID CPU_ID
-#endif
-
-/* Self-check for the detection */
-#if !defined(OS_ID)
- #error OS_ID not defined
-#endif
-#if OS_HOSTED && OS_EMBEDDED
- #error Both hosted and embedded OS environment
-#endif
-#if !OS_HOSTED && !OS_EMBEDDED
- #error Neither hosted nor embedded OS environment
-#endif
-
-#endif /* DEVLIB_OS_H */
+++ /dev/null
-#
-# $Id$
-# Copyright 2002,2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
-# All rights reserved.
-#
-# Author: Bernardo Innocenti <bernie@develer.com>
-# Based on: GCC-AVR standard Makefile part 1, Volker Oth 1/2000
-#
-
-#
-# Programmer type
-# see local pgm_config.mk for programmer customization.
--include pgm_config.mk
-DPROG ?= -V -c stk500 -P /dev/ttyS0
-
-# Set to 1 to build for embedded devices.
-# e.g. produce target.elf instead of target and target_nostrip
-EMBEDDED_TARGET = 1
-#EMBEDDED_TARGET = 0
-
-OPTCFLAGS = -ffunction-sections -fdata-sections
-#OPTCFLAGS = -funsafe-loop-optimizations
-
-# For AVRStudio
-#DEBUGCFLAGS = -gdwarf-2
-
-# For GDB
-DEBUGCFLAGS = -ggdb
-
-#
-# define some variables based on the AVR base path in $(AVR)
-#
-#CROSS = avr-
-CC = gcc
-CXX = g++
-AS = $(CC) -x assembler-with-cpp
-LD = $(CC)
-LDXX = $(CXX)
-OBJCOPY = objcopy
-STRIP = strip
-INSTALL = cp -a
-RM = rm -f
-RM_R = rm -rf
-RN = mv
-MKDIR_P = mkdir -p
-SHELL = /bin/sh
-CHECKER = sparse
-DOXYGEN = doxygen
-AVRDUDE = avrdude
-MOC = moc-qt4
-FLEXCAT = $(top_srcdir)/tools/flexcat/flexcat
-
-# For conversion from ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
-COFFCONVERT=$(OBJCOPY) \
- --debugging \
- --change-section-address .data-0x800000 \
- --change-section-address .bss-0x800000 \
- --change-section-address .noinit-0x800000 \
- --change-section-address .eeprom-0x810000
-
-INCDIR = -I. -Ihw
-LIBDIR = lib
-OBJDIR = obj
-OUTDIR = images
-
-# output format can be srec, ihex (avrobj is always created)
-FORMAT = srec
-#FORMAT = ihex
-
-# Compiler flags for generating dependencies
-DEP_FLAGS = -MMD -MP
-
-# Compiler flags for generating source listings
-LIST_FLAGS = -Wa,-anhlmsd=$(@:.o=.lst)
-
-# Linker flags for generating map files
-ifeq ($(EMBEDDED_TARGET), 1)
-MAP_FLAGS = -Wl,-Map=$(@:%.elf=%.map),--cref
-else
-MAP_FLAGS =
-endif
-
-# Compiler warning flags for both C and C++
-WARNFLAGS = \
- -W -Wformat -Wall -Wundef -Wpointer-arith -Wcast-qual \
- -Wcast-align -Wwrite-strings -Wsign-compare \
- -Wmissing-noreturn \
- -Wextra -Wstrict-aliasing=2 \
-# -Wunsafe-loop-optimizations
-
-# Compiler warning flags for C only
-C_WARNFLAGS = \
- -Wmissing-prototypes -Wstrict-prototypes
-
-# Default C preprocessor flags (for C, C++ and cpp+as)
-CPPFLAGS = $(INCDIR)
-
-# Default C compiler flags
-CFLAGS = $(OPTCFLAGS) $(DEBUGCFLAGS) $(WARNFLAGS) $(C_WARNFLAGS) \
- $(DEP_FLAGS) $(LIST_FLAGS) -std=gnu99
-
-# Default C++ compiler flags
-CXXFLAGS = $(OPTCFLAGS) $(DEBUGCFLAGS) $(WARNFLAGS) \
- $(DEP_FLAGS) $(LIST_FLAGS)
-
-# Default compiler assembly flags
-CPPAFLAGS = $(DEBUGCFLAGS) -MMD
-
-# Default assembler flags
-ASFLAGS = $(DEBUGCFLAGS)
-
-# Default linker flags
-#LDFLAGS = $(MAP_FLAGS)
-
-#bernie: does not complain for missing symbols!
-LDFLAGS = $(MAP_FLAGS) -Wl,--gc-sections
-
-# Flags for avrdude
-AVRDUDEFLAGS = $(DPROG)
-
-# additional libs
-LIB = -lm
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Kernel configuration parameters
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.8 2006/07/19 12:56:24 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.7 2006/02/21 16:05:53 bernie
- *#* Move from cfg/ to top-level.
- *#*
- *#* Revision 1.3 2005/11/04 16:20:01 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.2 2005/04/11 19:10:27 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.1 2005/04/11 19:04:13 bernie
- *#* Move top-level headers to cfg/ subdir.
- *#*
- *#* Revision 1.5 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.4 2004/08/24 16:19:38 bernie
- *#* Add missing header.
- *#*
- *#* Revision 1.3 2004/07/30 14:24:16 rasky
- *#* Task switching con salvataggio perfetto stato di interrupt (SR)
- *#* Kernel monitor per dump informazioni su stack dei processi
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 17:48:35 bernie
- *#* Add top-level files.
- *#*
- *#*/
-#ifndef CONFIG_KERN_H
-#define CONFIG_KERN_H
-
-#include <cfg/arch_config.h> /* ARCH_EMUL */
-
-/**
- * \name Modules activation
- *
- * \{
- */
-/* Module/option Active Dependencies */
-#define CONFIG_KERN_SCHED (1)
-#define CONFIG_KERN_SIGNALS (1 && CONFIG_KERN_SCHED)
-#define CONFIG_KERN_TIMER (1)
-#define CONFIG_KERN_HEAP (0)
-#define CONFIG_KERN_SEMAPHORES (0 && CONFIG_KERN_SIGNALS)
-#define CONFIG_KERN_MONITOR (1 && CONFIG_KERN_SCHED)
-/*\}*/
-
-/* EXPERIMENTAL */
-#define CONFIG_KERN_PREEMPTIVE (0 && CONFIG_KERN_SCHED && CONFIG_KERN_TIMER)
-
-#define CONFIG_KERN_QUANTUM 50 /**< Time sharing quantum in timer ticks. */
-
-#if (ARCH & ARCH_EMUL)
- /* We need a large stack because system libraries are bloated */
- #define CONFIG_PROC_DEFSTACKSIZE 65536
-#else
- /**
- * Default stack size for each thread, in bytes.
- *
- * The goal here is to allow a minimal task to save all of its
- * registers twice, plus push a maximum of 32 variables on the
- * stack.
- *
- * The actual size computed by the default formula is:
- * AVR: 102
- * i386: 156
- * ARM: 164
- * x86_64: 184
- *
- * Note that on most 16bit architectures, interrupts will also
- * run on the stack of the currently running process. Nested
- * interrupts will greatly increases the amount of stack space
- * required per process. Use irqmanager to minimize stack
- * usage.
- */
- #define CONFIG_PROC_DEFSTACKSIZE \
- (CPU_SAVED_REGS_CNT * 2 * sizeof(cpustack_t) \
- + 32 * sizeof(int))
-#endif
-
-/* OBSOLETE */
-#define CONFIG_KERN_DEFSTACKSIZE CONFIG_PROC_DEFSTACKSIZE
-
-/* Memory fill codes to help debugging */
-#if CONFIG_KERN_MONITOR
- #include <cpu/types.h>
- #if (SIZEOF_CPUSTACK_T == 1)
- /* 8bit cpustack_t */
- #define CONFIG_KERN_STACKFILLCODE 0xA5
- #define CONFIG_KERN_MEMFILLCODE 0xDB
- #elif (SIZEOF_CPUSTACK_T == 2)
- /* 16bit cpustack_t */
- #define CONFIG_KERN_STACKFILLCODE 0xA5A5
- #define CONFIG_KERN_MEMFILLCODE 0xDBDB
- #elif (SIZEOF_CPUSTACK_T == 4)
- /* 16bit cpustack_t */
- #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5UL
- #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBUL
- #elif (SIZEOF_CPUSTACK_T == 8)
- /* 16bit cpustack_t */
- #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5A5A5A5A5UL
- #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBDBDBDBDBUL
- #else
- #error No cpustack_t size supported!
- #endif
-#endif
-
-
-#endif /* CONFIG_KERN_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \brief ADC driver (implementation)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-
-#include <drv/adc.h>
-#include <drv/timer.h>
-
-#include CPU_CSOURCE(adc)
-
-#include <cfg/debug.h> // ASSERT()
-#include <cfg/macros.h> // MIN()
-#include <cfg/compiler.h>
-#include <cfg/module.h>
-
-/**
- * Read the ADC channel \a ch.
- */
-adcread_t adc_read(adc_ch_t ch)
-{
- ASSERT(ch <= (adc_ch_t)ADC_MUX_MAXCH);
- ch = MIN(ch, (adc_ch_t)ADC_MUX_MAXCH);
-
- adc_hw_select_ch(ch);
-
- return(adc_hw_read());
-}
-
-MOD_DEFINE(adc);
-
-/**
- * Initialize the ADC hardware.
- */
-void adc_init(void)
-{
- adc_hw_init();
-
- MOD_INIT(adc);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \brief ADC driver (interface)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-
-#ifndef DRV_ADC_H
-#define DRV_ADC_H
-
-#include <cfg/compiler.h>
-#include <cfg/debug.h>
-#include <cpu/attr.h>
-#include CPU_HEADER(adc)
-
-/** Type for ADC return value. */
-typedef uint16_t adcread_t;
-
-/** Type for channel */
-typedef uint8_t adc_ch_t;
-
-#define adc_bits() ADC_BITS
-
-adcread_t adc_read(adc_ch_t ch);
-void adc_init(void);
-
-/**
- * Macro used to convert data from adc range (0...(2 ^ADC_BITS - 1)) to
- * \a y1 ... \a y2 range.
- * \note \a y1, \a y2 can be negative, and put in ascending or descending order as well.
- * \note \a data and \a y2 are evaluated only once, \a y1 twice.
- */
-#define ADC_RANGECONV(data, y1, y2) ((((data) * ((y2) - (y1))) / ((1 << ADC_BITS) - 1)) + (y1))
-
-#endif /* DRV_ADC_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2003 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \brief Buzzer driver (implementation)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.19 2006/07/19 12:56:25 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.18 2006/02/17 21:15:25 bernie
- *#* Add MOD_CHECK() checks.
- *#*
- *#* Revision 1.17 2006/02/10 12:30:18 bernie
- *#* Push interrupt protection inside hw module.
- *#*
- *#* Revision 1.16 2005/11/04 16:19:33 bernie
- *#* buz_init(): Restore IRQ protection as in project_bko.
- *#*
- *#* Revision 1.15 2005/06/27 21:25:50 bernie
- *#* Modularize hardware access; Port to new timer interface.
- *#*
- *#* Revision 1.14 2005/04/11 19:10:27 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.13 2005/02/18 11:20:15 bernie
- *#* Use mware/event.h; Update copyright info.
- *#*
- *#* Revision 1.12 2004/12/13 12:07:06 bernie
- *#* DISABLE_IRQSAVE/ENABLE_IRQRESTORE: Convert to IRQ_SAVE_DISABLE/IRQ_RESTORE.
- *#*
- *#* Revision 1.11 2004/12/08 09:11:53 bernie
- *#* Rename time_t to mtime_t.
- *#*
- *#* Revision 1.10 2004/10/03 18:38:51 bernie
- *#* Add missing AVR header; Fix header.
- *#*
- *#* Revision 1.9 2004/09/14 21:01:25 bernie
- *#* Use new AVR port pin names.
- *#*/
-
-#include "buzzer.h"
-
-#include <hw_buzzer.h>
-#include <drv/timer.h>
-
-#include <mware/event.h>
-
-#include <cfg/debug.h>
-#include <cfg/module.h>
-
-
-/* Local vars */
-static Timer buz_timer;
-static bool buz_timer_running;
-static mtime_t buz_repeat_interval;
-static mtime_t buz_repeat_duration;
-
-
-/**
- * Turn off buzzer, called by software timer
- */
-static void buz_softint(void)
-{
- if (IS_BUZZER_ON)
- {
- BUZZER_OFF;
- if (buz_repeat_interval)
- {
- /* Wait for interval time */
- timer_setDelay(&buz_timer, ms_to_ticks(buz_repeat_interval));
- timer_add(&buz_timer);
- }
- else
- buz_timer_running = false;
- }
- else if (buz_repeat_interval)
- {
- /* Wait for beep time */
- BUZZER_ON;
- timer_setDelay(&buz_timer, ms_to_ticks(buz_repeat_duration));
- timer_add(&buz_timer);
- }
- else
- buz_timer_running = false;
-}
-
-
-/**
- * Beep for the specified ms time
- */
-void buz_beep(mtime_t time)
-{
- cpuflags_t flags;
- IRQ_SAVE_DISABLE(flags);
-
- /* Remove the software interrupt if it was already queued */
- if (buz_timer_running)
- timer_abort(&buz_timer);
-
- /* Turn on buzzer */
- BUZZER_ON;
-
- /* Add software interrupt to turn the buzzer off later */
- buz_timer_running = true;
- timer_setDelay(&buz_timer, ms_to_ticks(time));
- timer_add(&buz_timer);
-
- IRQ_RESTORE(flags);
-}
-
-
-/**
- * Start buzzer repetition
- */
-void buz_repeat_start(mtime_t duration, mtime_t interval)
-{
- buz_repeat_interval = interval;
- buz_repeat_duration = duration;
- buz_beep(duration);
-}
-
-
-/**
- * Stop buzzer repetition
- */
-void buz_repeat_stop(void)
-{
- cpuflags_t flags;
- IRQ_SAVE_DISABLE(flags);
-
- /* Remove the software interrupt if it was already queued */
- if (buz_timer_running)
- {
- timer_abort(&buz_timer);
- buz_timer_running = false;
- }
-
- buz_repeat_interval = 0;
- BUZZER_OFF;
-
- IRQ_RESTORE(flags);
-}
-
-MOD_DEFINE(buzzer)
-
-/**
- * Initialize buzzer.
- */
-void buz_init(void)
-{
- MOD_CHECK(timer);
-
- BUZZER_HW_INIT;
-
- /* Init software interrupt. */
- timer_set_event_softint(&buz_timer, (Hook)buz_softint, 0);
-
- MOD_INIT(buzzer);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003,2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2003 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Buzzer driver
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.10 2006/07/19 12:56:25 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.9 2005/11/27 23:32:15 bernie
- *#* Update copyright information.
- *#*
- *#* Revision 1.8 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.7 2005/04/11 19:10:27 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.6 2004/12/08 09:11:53 bernie
- *#* Rename time_t to mtime_t.
- *#*
- *#* Revision 1.5 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.4 2004/08/24 16:53:43 bernie
- *#* Add missing headers.
- *#*
- *#* Revision 1.3 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.2 2004/05/23 18:21:53 bernie
- *#* Trim CVS logs and cleanup header info.
- *#*
- *#*/
-#ifndef DRV_BUZZER_H
-#define DRV_BUZZER_H
-
-#include <cfg/compiler.h>
-
-extern void buz_init(void);
-extern void buz_beep(mtime_t time);
-extern void buz_repeat_start(mtime_t duration, mtime_t interval);
-extern void buz_repeat_stop(void);
-
-#endif /* DRV_BUZZER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- *
- * -->
- *
- * \brief Generic library to handle buzzers and leds
- *
- * This library is divided into three different layers:
- *
- * - The topmost portable layer is buzzerled.[ch] which exposes a common API
- * enable/disable the devices. Basically, it handles the asynchronism to
- * implement bld_beep and bld_repeat.
- * - The middle layer is CPU-specific and exposes a single main function which
- * turns on/off each device.
- * - The lower layer is board-specific and communicates with the middle layer
- * with any required API. The idea is that devices can be tied to the CPU in
- * many different ways (many different pins), so this part should describe
- * which devices are present, and how they are connected.
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:25 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.5 2004/12/08 09:43:41 bernie
- *#* Add a todo item.
- *#*
- *#* Revision 1.4 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.3 2004/07/14 14:04:29 rasky
- *#* Merge da SC: spostata bld_set inline perché si ottimizza parecchio tramite propagazione di costanti
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 18:36:05 bernie
- *#* Import buzzerled driver.
- *#*
- *#*/
-
-#include "buzzerled.h"
-#include "timer.h"
-
-static struct Timer timers[NUM_BLDS];
-static bool timer_go[NUM_BLDS];
-
-INLINE enum BLD_DEVICE hook_parm_to_device(void* parm)
-{
- struct Timer* t = (struct Timer*)parm;
- int num_bld = t - &timers[0];
-
- ASSERT(num_bld >= 0);
- ASSERT(num_bld < NUM_BLDS);
-
- return (enum BLD_DEVICE)num_bld;
-}
-
-static void hook_turn_off(void* parm)
-{
- enum BLD_DEVICE num_bld = hook_parm_to_device(parm);
- bld_set(num_bld, false);
-}
-
-void bld_init(void)
-{
- bld_hw_init();
-}
-
-void bld_beep(enum BLD_DEVICE device, uint16_t duration)
-{
- // \todo This is not reentrant for the same device. FIXME!
- struct Timer *t = &timers[device];
- timer_set_delay(t, duration);
- timer_set_event_softint(t, hook_turn_off, t);
- timer_add(t);
-
- bld_set(device, true);
-}
-
-void bld_beep_and_wait(enum BLD_DEVICE device, uint16_t duration)
-{
- bld_set(device, true);
- timer_delay(duration);
- bld_set(device, false);
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- *
- * -->
- *
- * \brief Generic library to handle buzzers and leds
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-#ifndef DRV_BUZZERLED_H
-#define DRV_BUZZERLED_H
-
-#include <cpu/attr.h>
-
-/** Include hw.h. We expect hw.h to define enum BLD_DEVICE, which must contain
- * an enumarator for each device, plus a special symbol NUM_BLDS containing the
- * number of devices.
- */
-#include <hw.h>
-
-
-/* Include hw-level implementation. This allows inlining of bld_set, which in turns
- * should allow fast constant propagation for the common case (where the parameter
- * device is a constant).
- */
-#include CPU_HEADER(buzzerled)
-
-
-/** Initialize the buzzerled library.
- *
- * \note This function must be called before any other function in the library.
- */
-void bld_init(void);
-
-
-/** Set or reset a device.
- *
- * \param device Device to be set
- * \param enable Enable/disable status
- */
-#define bld_set(device, enable) bld_hw_set(device, enable)
-
-
-/** Enable a device for a certain interval of time
- *
- * \param device Device to be enabled
- * \param duration Number of milliseconds the device must be enabled
- *
- * \note This function is non-blocking, so it will return immediately.
- */
-void bld_beep(enum BLD_DEVICE device, uint16_t duration);
-
-
-/** Enable a device for a certain interval of time and wait.
- *
- * \param device Device to be enabled
- * \param duration Number of milliseconds the device must be enabled
- *
- * \note This function is blocking, so it will return after the specified period of time.
- */
-void bld_beep_and_wait(enum BLD_DEVICE device, uint16_t duration);
-
-#endif /* DRV_BUZZERLED_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Function library for AT45DBXX Data Flash memory.
- *
- *
- * \version $Id: dataflash.c 20677 2008-02-19 14:29:52Z batt $
- * \author Daniele Basile <asterix@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#include "dataflash.h"
-#include <appconfig.h>
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-#include <cfg/module.h>
-#include <drv/timer.h>
-#include <kern/kfile.h>
-
-#if CONFIG_KERNEL
-#include <kern/proc.h>
-#endif
-
-#include <string.h>
-
-/**
- * Array used to describe dataflash memory devices currently supported.
- */
-static const DataflashInfo mem_info[] =
-{
- {
- /* AT45DB041B */
- .density_id = 0x07,
- .page_size = 264,
- .page_bits = 9,
- .page_cnt = 2048,
- .read_cmd = DFO_READ_FLASH_MEM_BYTE_B,
- },
- {
- /* AT45DB081D */
- .density_id = 0x09,
- .page_size = 264,
- .page_bits = 9,
- .page_cnt = 4096,
- .read_cmd = DFO_READ_FLASH_MEM_BYTE_D,
- },
- {
- /* AT45DB161D */
- .density_id = 0x0B,
- .page_size = 528,
- .page_bits = 10,
- .page_cnt = 4096,
- .read_cmd = DFO_READ_FLASH_MEM_BYTE_D,
- },
- /* Add other memories here */
-};
-
-STATIC_ASSERT(countof(mem_info) == DFT_CNT);
-
-/**
- * Macro that toggle CS of dataflash.
- * \note This is equivalent to fd->setCS(false) immediately followed by fd->setCS(true).
- */
-INLINE void CS_TOGGLE(KFileDataflash *fd)
-{
- fd->setCS(false);
- fd->setCS(true);
-}
-
-/**
- * Send a generic command to dataflash memory.
- * This function send only 4 byte: opcode, page address and
- * byte address.
- */
-static void send_cmd(KFileDataflash *fd, dataflash_page_t page_addr, dataflash_offset_t byte_addr, DataFlashOpcode opcode)
-{
-
- /*
- * Make sure to toggle CS signal in order,
- * and reset dataflash command decoder.
- */
- CS_TOGGLE(fd);
-
-
- /*
- * To send one command to data flash memory, we send 4 byte.
- * First byte is opcode command, second and third byte are
- * page address, in last byte we write a byte page address.
- * (see datasheet for more detail).
- *
- * \note Generaly a defaul memory page size is more than 256 byte.
- * In this case we need for addressing a byte in one page more than
- * 8 bit, so we put in fourth byte low part of address byte, and
- * hight part of address byte in third byte togheter low par of page
- * address.
- *
- */
-
- /*
- * Send opcode.
- */
- kfile_putc(opcode, fd->channel);
-
- /*
- * Send page address.
- */
- kfile_putc((uint8_t)(page_addr >> (16 - mem_info[fd->dev].page_bits)), fd->channel);
- kfile_putc((uint8_t)((page_addr << (mem_info[fd->dev].page_bits - 8)) + (byte_addr >> 8)), fd->channel);
-
- /*
- * Send byte page address.
- */
- kfile_putc((uint8_t)byte_addr, fd->channel);
-}
-
-/**
- * Reset dataflash memory function.
- *
- * If \a fd->setReset function is not NULL,
- * this function resets data flash memory
- * with one pulse reset long about 10usec.
- *
- */
-static void dataflash_reset(KFileDataflash *fd)
-{
- fd->setCS(false);
-
- if (fd->setReset)
- {
- fd->setReset(true);
- timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH));
- fd->setReset(false);
- timer_delayHp(us_to_hptime(RESET_PULSE_WIDTH));
- }
-}
-
-
-/**
- * Read status register of dataflah memory.
- */
-static uint8_t dataflash_stat(KFileDataflash *fd)
-{
- /*
- * Make sure to toggle CS signal
- * and reset dataflash command decoder.
- */
- CS_TOGGLE(fd);
-
- kfile_putc(DFO_READ_STATUS, fd->channel);
-
- return kfile_getc(fd->channel);
-}
-
-
-/**
- * Send one command to data flash memory, and
- * return status register value.
- *
- */
-static uint8_t dataflash_cmd(KFileDataflash *fd, dataflash_page_t page_addr, dataflash_offset_t byte_addr, DataFlashOpcode opcode)
-{
- uint8_t stat;
-
- send_cmd(fd, page_addr, byte_addr, opcode);
-
- CS_TOGGLE(fd);
-
- /*
- * We chech data flash memory state, and wait until busy-flag
- * is high.
- */
- while (!(dataflash_stat(fd) & BUSY_BIT))
- {
- #if CONFIG_KERNEL
- proc_switch();
- #endif
- }
-
- stat = dataflash_stat(fd);
-
- kfile_flush(fd->channel); // Flush channel
- /*
- * Data flash has completed a bus cycle, so disable CS.
- */
- fd->setCS(false);
-
- return stat;
-}
-
-/**
- * Read \a len bytes from main data flash memory or buffer data
- * flash memory, and put it in \a *block.
- */
-static void dataflash_readBlock(KFileDataflash *fd, dataflash_page_t page_addr, dataflash_offset_t byte_addr, DataFlashOpcode opcode, uint8_t *block, dataflash_size_t len)
-{
- send_cmd(fd, page_addr, byte_addr, opcode);
-
- if (opcode == DFO_READ_FLASH_MEM_BYTE_B)
- {
- /*
- * Send 24 don't care bits.
- */
- uint8_t dummy[] = { 0, 0, 0 };
- kfile_write(fd->channel, dummy, sizeof(dummy));
- }
-
- kfile_putc(0, fd->channel); //Send 8 don't care bit.
- kfile_read(fd->channel, block, len); //Read len bytes ad put in block buffer.
- kfile_flush(fd->channel); // Flush channel
- fd->setCS(false);
-}
-
-
-/**
- * Write \a len bytes in dataflash memory buffer.
- *
- * \note Is not possible to write directly in dataflash main memory.
- * To perform a write in main memory you must first write in dataflash buffer
- * memory and then send a command to write the page in main memory.
- */
-static void dataflash_writeBlock(KFileDataflash *fd, dataflash_offset_t offset, DataFlashOpcode opcode, const uint8_t *block, dataflash_size_t len)
-{
- ASSERT(offset + len <= mem_info[fd->dev].page_size);
-
- send_cmd(fd, 0x00, offset, opcode);
-
- kfile_write(fd->channel, block, len); //Write len bytes.
- kfile_flush(fd->channel); // Flush channel
-
- fd->setCS(false);
-}
-
-
-/**
- * Load selct page from dataflash memory to buffer.
- */
-static void dataflash_loadPage(KFileDataflash *fd, dataflash_page_t page_addr)
-{
- dataflash_cmd(fd, page_addr, 0x00, DFO_MOV_MEM_TO_BUFF1);
-}
-
-/**
- * Flush select page (stored in buffer) in data flash main memory page.
- */
-static int dataflash_flush(KFile *_fd)
-{
- KFileDataflash *fd = KFILEDATAFLASH(_fd);
- if (fd->page_dirty)
- {
- dataflash_cmd(fd, fd->current_page, 0x00, DFO_WRITE_BUFF1_TO_MEM_E);
-
- fd->page_dirty = false;
-
- kprintf("Flushing page <%ld>\n", fd->current_page);
- }
- return 0;
-}
-
-/* Kfile interface section */
-
-/**
- * Close file \a fd.
- */
-static int dataflash_close(struct KFile *_fd)
-{
- dataflash_flush(_fd);
- TRACE;
- return 0;
-}
-
-/**
- * Reopen dataflash file \a fd.
- */
-static KFile *dataflash_reopen(KFile *_fd)
-{
- KFileDataflash *fd = KFILEDATAFLASH(_fd);
- dataflash_close(_fd);
-
- fd->current_page = 0;
- fd->fd.seek_pos = 0;
-
- /* Load selected page from dataflash memory */
- dataflash_loadPage(fd, fd->current_page);
-
- TRACE;
- return &fd->fd;
-}
-
-
-/**
- * Read in \a buf \a size bytes from dataflash memmory.
- *
- * \note For reading data flash memory, we
- * check flag page_dirty, if is true (that mean
- * we have written a byte in buffer memory) we
- * flush current page in main memory and
- * then read from memory, else we read byte
- * directly from data flash main memory.
- *
- * \return the number of bytes read.
- */
-static size_t dataflash_read(struct KFile *_fd, void *buf, size_t size)
-{
- KFileDataflash *fd = KFILEDATAFLASH(_fd);
-
- dataflash_offset_t byte_addr;
- dataflash_page_t page_addr;
- uint8_t *data = (uint8_t *)buf;
-
-
- ASSERT(fd->fd.seek_pos + size <= fd->fd.size);
- size = MIN((uint32_t)size, fd->fd.size - fd->fd.seek_pos);
-
- kprintf("Reading at pos[%lu]\n", fd->fd.seek_pos);
-
- /*
- * We select page and offest from absolute address.
- */
- page_addr = fd->fd.seek_pos / mem_info[fd->dev].page_size;
- byte_addr = fd->fd.seek_pos % mem_info[fd->dev].page_size;
-
- kprintf("[page-<%ld>, byte-<%ld>]", page_addr, byte_addr);
-
- /*
- * Flush current page in main memory if
- * we had been written a byte in memory
- */
- dataflash_flush(&fd->fd);
-
- /*
- * Read byte in main page data flash memory.
- */
- dataflash_readBlock(fd, page_addr, byte_addr, mem_info[fd->dev].read_cmd, data, size);
-
- fd->fd.seek_pos += size;
- kprintf("Read %ld bytes\n", size);
-
- return size;
-}
-
-/**
- * Write \a _buf in dataflash memory
- *
- * \note For writing \a _buf in dataflash memory, we must
- * first write in buffer data flash memory. At the end of write,
- * we can put page in dataflash main memory.
- * If we write in two contiguous pages, we put in main memory current
- * page and then reload the page which we want to write.
- *
- * \return the number of bytes write.
- */
-static size_t dataflash_write(struct KFile *_fd, const void *_buf, size_t size)
-{
- KFileDataflash *fd = KFILEDATAFLASH(_fd);
-
- dataflash_offset_t offset;
- dataflash_page_t new_page;
- size_t total_write = 0;
-
- const uint8_t *data = (const uint8_t *) _buf;
-
- ASSERT(fd->fd.seek_pos + size <= fd->fd.size);
- size = MIN((uint32_t)size, fd->fd.size - fd->fd.seek_pos);
-
- kprintf("Writing at pos[%lu]\n", fd->fd.seek_pos);
-
- while (size)
- {
- /*
- * We select page and offest from absolute address.
- */
- new_page = fd->fd.seek_pos / mem_info[fd->dev].page_size;
- offset = fd->fd.seek_pos % mem_info[fd->dev].page_size;
-
-
- size_t wr_len = MIN(size, mem_info[fd->dev].page_size - offset);
-
- kprintf(" [page-<%ld>, byte-<%ld>]",new_page, offset);
-
- if (new_page != fd->current_page)
- {
- /* Flush current page in main memory*/
- dataflash_flush(&fd->fd);
- /* Load select page memory from data flash memory*/
- dataflash_loadPage(fd, new_page);
-
- fd->current_page = new_page;
- kprintf(" >> Load page: <%ld> ", new_page);
- }
- /*
- * Write byte in current page, and set true
- * page_dirty flag.
- */
- dataflash_writeBlock(fd, offset, DFO_WRITE_BUFF1, data, wr_len);
- fd->page_dirty = true;
-
- data += wr_len;
- fd->fd.seek_pos += wr_len;
- size -= wr_len;
- total_write += wr_len;
- }
-
- kprintf("written %lu bytes\n", total_write);
- return total_write;
-}
-
-MOD_DEFINE(dataflash);
-
-/**
- * Dataflash init function.
- * This function initialize \a fd with SPI channel \a ch and test if data flash memory
- * density is the same specified by device \a dev.
- * \a setCS is a callback used to set/reset CS line.
- * \a setReset is a callback used to set/reset the dataflash (can be NULL if reset is unconnected)
- * \return true if ok, false if memory density read from dataflash is not compliant with the
- * configured one.
- */
-bool dataflash_init(KFileDataflash *fd, KFile *ch, DataflashType dev, dataflash_setCS_t *setCS, dataflash_setReset_t *setReset)
-{
- uint8_t stat;
-
- MOD_CHECK(dataflash_hw);
-
- ASSERT(fd);
- ASSERT(ch);
- ASSERT(setCS);
- ASSERT(dev < DFT_CNT);
-
- memset(fd, 0, sizeof(*fd));
- DB(fd->fd._type = KFT_DATAFLASH);
- fd->dev = dev;
- fd->channel = ch;
- fd->setReset = setReset;
- fd->setCS = setCS;
-
- // Setup data flash programming functions.
- fd->fd.reopen = dataflash_reopen;
- fd->fd.close = dataflash_close;
- fd->fd.read = dataflash_read;
- fd->fd.write = dataflash_write;
- fd->fd.seek = kfile_genericSeek;
- fd->fd.flush = dataflash_flush;
-
- dataflash_reset(fd);
-
- stat = dataflash_stat(fd);
-
- /*
- * 2,3,4,5 bits of 1 byte status register
- * indicate a device density of dataflash memory
- * (see datasheet for more detail.)
- */
- if (GET_ID_DESITY_DEVICE(stat) != mem_info[fd->dev].density_id)
- return false;
-
- fd->current_page = 0;
- fd->fd.seek_pos = 0;
- fd->fd.size = mem_info[fd->dev].page_size * mem_info[fd->dev].page_cnt;
-
- /* Load selected page from dataflash memory */
- dataflash_loadPage(fd, fd->current_page);
- MOD_INIT(dataflash);
- return true;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Function library for AT45DB081D Flash memory.
- *
- *
- * \version $Id: dataflash.h 20677 2008-02-19 14:29:52Z batt $
- * \author Daniele Basile <asterix@develer.com>
- */
-
-
-#ifndef DRV_DATAFLASH_H
-#define DRV_DATAFLASH_H
-
-#include <kern/kfile.h>
-#include <cfg/compiler.h>
-
-#include <appconfig.h>
-
-
-/**
- * Type definitions for dflash memory.
- * \{
- */
-typedef uint32_t dataflash_page_t;
-typedef uint32_t dataflash_offset_t;
-typedef uint32_t dataflash_size_t;
-/*\}*/
-
-/**
- *
- */
-typedef void (dataflash_setReset_t)(bool);
-typedef void (dataflash_setCS_t)(bool);
-
-/**
- * Memory definitions.
- *
- * List of supported memory devices by this drive.
- * Every time we call dataflash_init() we check device id to
- * ensure we choose the right memory configuration.
- * (see dataflash.c for more details).
- */
-typedef enum DataflashType
-{
- DFT_AT45DB041B,
- DFT_AT45DB081D,
- DFT_AT45DB161D,
- DFT_CNT
-} DataflashType;
-
-
-/**
- * Dataflash KFile context structure.
- */
-typedef struct KFileDataflash
-{
- KFile fd; ///< File descriptor.
- KFile *channel; ///< Dataflash comm channel (usually SPI).
- DataflashType dev; ///< Memory device type;
- dataflash_page_t current_page; ///< Current loaded dataflash page.
- bool page_dirty; ///< True if current_page is dirty (needs to be flushed).
- dataflash_setReset_t *setReset; ///< Callback used to set reset pin of dataflash.
- dataflash_setCS_t *setCS; ///< Callback used to set CS pin of dataflash.
-} KFileDataflash;
-
-/**
- * ID for dataflash.
- */
-#define KFT_DATAFLASH MAKE_ID('D', 'F', 'L', 'H')
-
-/**
- * Convert + ASSERT from generic KFile to KFileDataflash.
- */
-INLINE KFileDataflash * KFILEDATAFLASH(KFile *fd)
-{
- ASSERT(fd->_type == KFT_DATAFLASH);
- return (KFileDataflash *)fd;
-}
-
-#define RESET_PULSE_WIDTH 10 ///< Width of reset pulse in usec.
-#define BUSY_BIT 0x80 ///< Select a busy bit in status register.
-#define CMP_BIT 0x40 ///< Select a compare bit in status register.
-
-/**
- * Select bits 2-5 of status register. These
- * bits indicate device density (see datasheet for
- * more details).
- */
-#define GET_ID_DESITY_DEVICE(reg_stat) (((reg_stat) & 0x3C) >> 2)
-
-/**
- * Data flash opcode commands.
- */
-typedef enum DataFlashOpcode {
- /**
- * Dataflash read commands.
- * \{
- */
- DFO_READ_FLASH_MEM_BYTE_D = 0x0B, ///< Continuos array read for D type memories.
- DFO_READ_FLASH_MEM_BYTE_B = 0xE8, ///< Continuos array read for B type memories.
-
- DFO_READ_FLASH_MEM = 0xD2, ///< Main memory page read.
- DFO_READ_BUFF1 = 0xD4, ///< SRAM buffer 1 read.
- DFO_READ_BUFF2 = 0xD6, ///< SRAM buffer 2 read.
- /* \}*/
-
- /**
- * Program and erase commands data flash.
- * \{
- */
- DFO_WRITE_BUFF1 = 0x84, ///< SRAM buffer 1 write.
- DFO_WRITE_BUFF2 = 0x87, ///< SRAM buffer 2 write.
- DFO_WRITE_BUFF1_TO_MEM_E = 0x83, ///< Buffer 1 to main memory page program with built-in erase.
- DFO_WRITE_BUFF2_TO_MEM_E = 0x86, ///< Buffer 2 to main memory page program with built-in erase.
- DFO_WRITE_BUFF1_TO_MEM = 0x88, ///< Buffer 1 to main memory page program without built-in erase.
- DFO_WRITE_BUFF2_TO_MEM = 0x89, ///< Buffer 2 to main memory page program without built-in erase.
- DFO_ERASE_PAGE = 0x81, ///< Erase page.
- DFO_ERASE_BLOCK = 0x50, ///< Erase block.
- DFO_ERASE_SECTOR = 0x7C, ///< Erase sector.
- DFO_WRITE_MEM_TR_BUFF1 = 0x82, ///< Write main memory page through buffer 1.
- DFO_WRITE_MEM_TR_BUFF2 = 0x85, ///< Write main memory page through buffer 2.
- /* \}*/
-
- /**
- * Additional dataflash commands.
- * \{
- */
- DFO_MOV_MEM_TO_BUFF1 = 0x53, ///< Transfer main mmemory to buffer 1.
- DFO_MOV_MEM_TO_BUFF2 = 0x55, ///< Transfer main mmemory to buffer 2.
- DFO_CMP_MEM_TO_BUFF1 = 0x60, ///< Compare main mmemory with buffer 1.
- DFO_CMP_MEM_TO_BUFF2 = 0x61, ///< Compare main mmemory with buffer 2.
- DFO_ARW_MEM_TR_BUFF1 = 0x58, ///< Auto page rewrite through buffer 1.
- DFO_ARW_MEM_TR_BUFF2 = 0x59, ///< Auto page rewrite through buffer 2
- DFO_PWR_DOWN = 0xB9, ///< Deep power-down.
- DFO_RESUME_PWR_DOWN = 0xAB, ///< Resume from deep power-down.
- DFO_READ_STATUS = 0xD7, ///< Read status register.
- DFO_ID_DEV = 0x9F ///< Read manufacturer and device ID.
- /* \}*/
-} DataFlashOpcode;
-
-
-/**
- * Structure used to describe a dataflash memory.
- */
-typedef struct DataflashInfo
-{
- uint8_t density_id; ///< Density id, used to check memory type.
- dataflash_size_t page_size; ///< Page size, in bytes.
- uint8_t page_bits; ///< Number of bits needed to access a page.
- uint16_t page_cnt; ///< Number of pages on memory.
- DataFlashOpcode read_cmd; ///< Command to be used to perform a continuous array.
-} DataflashInfo;
-
-
-bool dataflash_init(KFileDataflash *fd, KFile *ch, DataflashType type, dataflash_setCS_t *setCS, dataflash_setReset_t *setReset);
-
-#endif /* DRV_DATAFLASH_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Driver for the 24xx16 and 24xx256 I2C EEPROMS (implementation)
- *
- * \note This implementation is AVR specific.
- *
- * \version $Id$
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "eeprom.h"
-
-#include <cfg/debug.h>
-#include <appconfig.h> // CONFIG_EEPROM_VERIFY
-#include <cfg/macros.h> // MIN()
-#include <cpu/attr.h>
-#include CPU_HEADER(twi)
-#include <drv/wdt.h>
-#include <mware/byteorder.h> // cpu_to_be16()
-
-#include <string.h> // memset()
-
-
-// Configuration sanity checks
-#if !defined(CONFIG_EEPROM_VERIFY) || (CONFIG_EEPROM_VERIFY != 0 && CONFIG_EEPROM_VERIFY != 1)
- #error CONFIG_EEPROM_VERIFY must be defined to either 0 or 1
-#endif
-
-/**
- * EEPROM ID code
- */
-#define EEPROM_ID 0xA0
-
-/**
- * This macros form the correct slave address for EEPROMs
- */
-#define EEPROM_ADDR(x) (EEPROM_ID | (((uint8_t)(x)) << 1))
-
-
-
-
-/**
- * Copy \c count bytes from buffer \c buf to
- * eeprom at address \c addr.
- */
-static bool eeprom_writeRaw(e2addr_t addr, const void *buf, size_t count)
-{
- bool result = true;
- ASSERT(addr + count <= EEPROM_SIZE);
-
- while (count && result)
- {
- /*
- * Split write in multiple sequential mode operations that
- * don't cross page boundaries.
- */
- size_t size =
- MIN(count, (size_t)(EEPROM_BLKSIZE - (addr & (EEPROM_BLKSIZE - 1))));
-
- #if CONFIG_EEPROM_TYPE == EEPROM_24XX16
- /*
- * The 24LC16 uses the slave address as a 3-bit
- * block address.
- */
- uint8_t blk_addr = (uint8_t)((addr >> 8) & 0x07);
- uint8_t blk_offs = (uint8_t)addr;
-
- result =
- twi_start_w(EEPROM_ADDR(blk_addr))
- && twi_send(&blk_offs, sizeof blk_offs)
- && twi_send(buf, size);
-
- #elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
-
- // 24LC256 wants big-endian addresses
- uint16_t addr_be = cpu_to_be16(addr);
-
- result =
- twi_start_w(EEPROM_ID)
- && twi_send((uint8_t *)&addr_be, sizeof addr_be)
- && twi_send(buf, size);
-
- #else
- #error Unknown device type
- #endif
-
- twi_stop();
-
- // DEBUG
- //kprintf("addr=%d, count=%d, size=%d, *#?=%d\n",
- // addr, count, size,
- // (EEPROM_BLKSIZE - (addr & (EEPROM_BLKSIZE - 1)))
- //);
-
- /* Update count and addr for next operation */
- count -= size;
- addr += size;
- buf = ((const char *)buf) + size;
- }
-
- if (!result)
- TRACEMSG("Write error!");
- return result;
-}
-
-
-#if CONFIG_EEPROM_VERIFY
-/**
- * Check that the contents of an EEPROM range
- * match with a provided data buffer.
- *
- * \return true on success.
- */
-static bool eeprom_verify(e2addr_t addr, const void *buf, size_t count)
-{
- uint8_t verify_buf[16];
- bool result = true;
-
- while (count && result)
- {
- /* Split read in smaller pieces */
- size_t size = MIN(count, sizeof verify_buf);
-
- /* Read back buffer */
- if (eeprom_read(addr, verify_buf, size))
- {
- if (memcmp(buf, verify_buf, size) != 0)
- {
- TRACEMSG("Data mismatch!");
- result = false;
- }
- }
- else
- {
- TRACEMSG("Read error!");
- result = false;
- }
-
- /* Update count and addr for next operation */
- count -= size;
- addr += size;
- buf = ((const char *)buf) + size;
- }
-
- return result;
-}
-#endif /* CONFIG_EEPROM_VERIFY */
-
-
-bool eeprom_write(e2addr_t addr, const void *buf, size_t count)
-{
-#if CONFIG_EEPROM_VERIFY
- int retries = 5;
-
- while (retries--)
- if (eeprom_writeRaw(addr, buf, count)
- && eeprom_verify(addr, buf, count))
- return true;
-
- return false;
-
-#else /* !CONFIG_EEPROM_VERIFY */
- return eeprom_writeRaw(addr, buf, count);
-#endif /* !CONFIG_EEPROM_VERIFY */
-}
-
-
-/**
- * Copy \c count bytes at address \c addr
- * from eeprom to RAM to buffer \c buf.
- *
- * \return true on success.
- */
-bool eeprom_read(e2addr_t addr, void *buf, size_t count)
-{
- ASSERT(addr + count <= EEPROM_SIZE);
-
-#if CONFIG_EEPROM_TYPE == EEPROM_24XX16
- /*
- * The 24LC16 uses the slave address as a 3-bit
- * block address.
- */
- uint8_t blk_addr = (uint8_t)((addr >> 8) & 0x07);
- uint8_t blk_offs = (uint8_t)addr;
-
- bool res =
- twi_start_w(EEPROM_ADDR(blk_addr))
- && twi_send(&blk_offs, sizeof blk_offs)
- && twi_start_r(EEPROM_ADDR(blk_addr))
- && twi_recv(buf, count);
-
-#elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
-
- // 24LC256 wants big-endian addresses
- addr = cpu_to_be16(addr);
-
- bool res =
- twi_start_w(EEPROM_ID)
- && twi_send((uint8_t *)&addr, sizeof(addr))
- && twi_start_r(EEPROM_ID)
- && twi_recv(buf, count);
-#else
- #error Unknown device type
-#endif
-
- twi_stop();
-
- if (!res)
- TRACEMSG("Read error!");
- return res;
-}
-
-
-/**
- * Write a single character \a c at address \a addr.
- */
-bool eeprom_write_char(e2addr_t addr, char c)
-{
- return eeprom_write(addr, &c, 1);
-}
-
-
-/**
- * Read a single character at address \a addr.
- *
- * \return the requested character or -1 in case of failure.
- */
-int eeprom_read_char(e2addr_t addr)
-{
- char c;
-
- if (eeprom_read(addr, &c, 1))
- return c;
- else
- return -1;
-}
-
-
-/**
- * Erase specified part of eeprom, writing 0xFF.
- *
- * \param addr starting address
- * \param count length of block to erase
- */
-void eeprom_erase(e2addr_t addr, size_t count)
-{
- uint8_t buf[EEPROM_BLKSIZE];
- memset(buf, 0xFF, sizeof buf);
-
- // Clear all but struct hw_info at start of eeprom
- while (count)
- {
- // Long operation, reset watchdog
- wdt_reset();
-
- size_t size = MIN(count, sizeof buf);
- eeprom_write(addr, buf, size);
- addr += size;
- count -= size;
- }
-}
-
-
-/**
- * Initialize TWI module.
- */
-void eeprom_init(void)
-{
- twi_init();
-}
-
-
-#ifdef _DEBUG
-
-#include <string.h>
-
-void eeprom_test(void)
-{
- static const char magic[14] = "Humpty Dumpty";
- char buf[sizeof magic];
- size_t i;
-
- // Write something to EEPROM using unaligned sequential writes
- for (i = 0; i < 42; ++i)
- {
- wdt_reset();
- eeprom_write(i * sizeof magic, magic, sizeof magic);
- }
-
- // Read back with single-byte reads
- for (i = 0; i < 42 * sizeof magic; ++i)
- {
- wdt_reset();
- eeprom_read(i, buf, 1);
- kprintf("EEPROM byte read: %c (%d)\n", buf[0], buf[0]);
- ASSERT(buf[0] == magic[i % sizeof magic]);
- }
-
- // Read back again using sequential reads
- for (i = 0; i < 42; ++i)
- {
- wdt_reset();
- memset(buf, 0, sizeof buf);
- eeprom_read(i * sizeof magic, buf, sizeof magic);
- kprintf("EEPROM seq read @ 0x%x: '%s'\n", i * sizeof magic, buf);
- ASSERT(memcmp(buf, magic, sizeof magic) == 0);
- }
-}
-
-#endif // _DEBUG
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Driver for the 24xx16 and 24xx256 I2C EEPROMS (interface)
- */
-
-#ifndef DRV_EEPROM_H
-#define DRV_EEPROM_H
-
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-/**
- * \name Values for CONFIG_EEPROM_TYPE
- * \{
- */
-#define EEPROM_24XX16 1
-#define EEPROM_24XX256 2
-/*\}*/
-
-#if CONFIG_EEPROM_TYPE == EEPROM_24XX16
- #define EEPROM_BLKSIZE 0x10 ///< Eeprom block size (16byte)
- #define EEPROM_SIZE 0x800 ///< Eeprom total size (2kB)
-#elif CONFIG_EEPROM_TYPE == EEPROM_24XX256
- #define EEPROM_BLKSIZE 0x40 ///< Eeprom block size (64byte)
- #define EEPROM_SIZE 0x8000 ///< Eeprom total size (32kB)
-#else
- #error Unsupported EEPROM type.
-#endif
-
-/// Type for EEPROM addresses
-typedef uint16_t e2addr_t;
-
-/**
- * Macro for E2Layout offset calculation
- *
- * \note We can't just use offsetof() here because we could use
- * non-constant expressions to access array elements.
- *
- * \note 'type' is the structure type holding eeprom layout
- * and must be defined in user files.
- */
-#define e2addr(type, field) ((e2addr_t)&(((type *)0)->field))
-
-
-bool eeprom_write(e2addr_t addr, const void *buf, size_t count);
-bool eeprom_read(e2addr_t addr, void *buf, size_t count);
-bool eeprom_write_char(e2addr_t addr, char c);
-int eeprom_read_char(e2addr_t addr);
-void eeprom_erase(e2addr_t addr, size_t count);
-void eeprom_init(void);
-void eeprom_test(void);
-
-#endif /* DRV_EEPROM_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Function library for serial Flash memory.
- *
- * Module provide a kfile interface, that ensure an abstraction
- * from comunication channel and give a standard interface.
- * Typicaly this kind of memory use an SPI bus, but you should
- * use another comunication channel you have defined.
- *
- * \version $Id$
- * \author Daniele Basile <asterix@develer.com>
- */
-
-#include <avr/io.h>
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-#include <drv/timer.h>
-#include <drv/flash25.h>
-
-#if CONFIG_KERNEL
-#include <kern/proc.h>
-#endif
-
-/*
- * We use a spi bus, thus include hardware specific definition.
- * If you use another channel you must redefine this macros.
- */
-#include "hw_spi.h"
-
-#include <appconfig.h>
-
-/**
- * Global definition of channel handler (usually SPI).
- */
-static KFile *channel;
-
-/**
- * Wait until flash memory is ready.
- */
-static void flash25_waitReady(void)
-{
- uint8_t stat;
-
- while (1)
- {
- CS_ENABLE();
-
- kfile_putc(FLASH25_RDSR, channel);
- stat = kfile_getc(channel);
-
- CS_DISABLE();
-
- if (!(stat & RDY_BIT))
- break;
- #if CONFIG_KERNEL
- else
- proc_switch();
- #endif
- }
-}
-
-/**
- * Send a single command to serial flash memory.
- */
-static void flash25_sendCmd(Flash25Opcode cmd)
-{
- CS_ENABLE();
-
- kfile_putc(cmd, channel);
-
- CS_DISABLE();
-}
-
-/**
- * flash25 init function.
- * This function init a comunication channel and
- * try to read manufacturer id of serial memory,
- * then check if is equal to selected type.
- */
-static bool flash25_pin_init(void)
-{
- uint8_t device_id;
- uint8_t manufacturer;
-
- SPI_HW_INIT();
-
- CS_ENABLE();
- /*
- * Send read id productor opcode on
- * comunication channel
- * TODO:controllare se ha senso
- */
- kfile_putc(FLASH25_RDID, channel);
-
- manufacturer = kfile_getc(channel);
- device_id = kfile_getc(channel);
-
- CS_DISABLE();
-
- if((FLASH25_MANUFACTURER_ID == manufacturer) &&
- (FLASH25_DEVICE_ID == device_id))
- return true;
- else
- return false;
-}
-
-/**
- * Reopen a serial memory interface.
- *
- * For serial memory this function reinit only
- * the size and seek_pos in kfile stucture.
- * Return a kfile pointer, after assert check.
- */
-static KFile * flash25_reopen(struct KFile *fd)
-{
- KFILE_ASSERT_GENERIC(fd);
-
- fd->seek_pos = 0;
- fd->size = FLASH25_MEM_SIZE;
-
- kprintf("flash25 file opened\n");
- return fd;
-}
-
-/**
- * Close a serial memory interface.
- *
- * For serial memory this funtion do nothing,
- * and return always 0.
- */
-static int flash25_close(UNUSED_ARG(struct KFile *,fd))
-{
- kprintf("flash25 file closed\n");
- return 0;
-}
-
-/**
- * Read \a _buf lenght \a size byte from serial flash memmory.
- *
- * For read in serial flash memory we
- * enble cs pin and send one byte of read opcode,
- * and then 3 byte of address of memory cell we
- * want to read. After the last byte of address we
- * can read data from so pin.
- *
- * \return the number of bytes read.
- */
-static size_t flash25_read(struct KFile *fd, void *buf, size_t size)
-{
- uint8_t *data = (uint8_t *)buf;
-
- KFILE_ASSERT_GENERIC(fd);
-
- ASSERT(fd->seek_pos + size <= fd->size);
- size = MIN((uint32_t)size, fd->size - fd->seek_pos);
-
- //kprintf("Reading at addr[%lu], size[%d]\n", fd->seek_pos, size);
- CS_ENABLE();
-
- kfile_putc(FLASH25_READ, channel);
-
-
- /*
- * Address that we want to read.
- */
- kfile_putc((fd->seek_pos >> 16) & 0xFF, channel);
- kfile_putc((fd->seek_pos >> 8) & 0xFF, channel);
- kfile_putc(fd->seek_pos & 0xFF, channel);
-
- kfile_read(channel, data, size);
-
- CS_DISABLE();
-
- fd->seek_pos += size;
-
- return size;
-}
-
-/**
- * Write \a _buf in serial flash memory
- *
- * Before to write data into flash we must enable
- * memory writing. To do this we send a WRE command opcode.
- * After this command the flash is ready to be write, and so
- * we send a PROGRAM opcode followed to 3 byte of
- * address memory, at the end of last address byte
- * we can send the data.
- * When we finish to send all data, we disable cs
- * and flash write received data bytes on its memory.
- *
- * \note: WARNING: you could write only on erased memory section!
- * Each write time you could write max a memory page size,
- * because if you write more than memory page size the
- * address roll over to first byte of page.
- *
- * \return the number of bytes write.
- */
-static size_t flash25_write(struct KFile *fd, const void *_buf, size_t size)
-{
- flash25Offset_t offset;
- flash25Size_t total_write = 0;
- flash25Size_t wr_len;
- const uint8_t *data = (const uint8_t *) _buf;
-
- KFILE_ASSERT_GENERIC(fd);
- ASSERT(fd->seek_pos + size <= fd->size);
-
- size = MIN((flash25Size_t)size, fd->size - fd->seek_pos);
-
- while (size)
- {
- offset = fd->seek_pos % (flash25Size_t)FLASH25_PAGE_SIZE;
- wr_len = MIN((flash25Size_t)size, FLASH25_PAGE_SIZE - (flash25Size_t)offset);
-
- kprintf("[seek_pos-<%lu>, offset-<%d>]\n", fd->seek_pos, offset);
-
- /*
- * We check serial flash memory state, and wait until ready-flag
- * is high.
- */
- flash25_waitReady();
-
- /*
- * Start write cycle.
- * We could write only data not more long than one
- * page size.
- *
- * To write on serial flash memory we must first
- * enable write with a WREN opcode command, before
- * the PROGRAM opcode.
- *
- * \note: the same byte cannot be reprogrammed without
- * erasing the whole sector first.
- */
- flash25_sendCmd(FLASH25_WREN);
-
- CS_ENABLE();
- kfile_putc(FLASH25_PROGRAM, channel);
-
- /*
- * Address that we want to write.
- */
- kfile_putc((fd->seek_pos >> 16) & 0xFF, channel);
- kfile_putc((fd->seek_pos >> 8) & 0xFF, channel);
- kfile_putc(fd->seek_pos & 0xFF, channel);
-
- kfile_write(channel, data, wr_len);
-
- CS_DISABLE();
-
- data += wr_len;
- fd->seek_pos += wr_len;
- size -= wr_len;
- total_write += wr_len;
- }
-
- kprintf("written %u bytes\n", total_write);
- return total_write;
-}
-
-/**
- * Sector erase function.
- *
- * Erase a select \p sector of serial flash memory.
- *
- * \note A sector size is FLASH25_SECTOR_SIZE.
- * This operation could take a while.
- */
-void flash25_sectorErase(Flash25Sector sector)
-{
-
- /*
- * Erase a sector could take a while,
- * for debug we measure that time
- * see datasheet to compare this time.
- */
- DB(ticks_t start_time = timer_clock());
-
- CS_ENABLE();
-
- /*
- * To erase a sector of serial flash memory we must first
- * enable write with a WREN opcode command, before
- * the SECTOR_ERASE opcode. Sector is automatically
- * determinate if any address within the sector
- * is selected.
- */
- kfile_putc(FLASH25_WREN, channel);
- kfile_putc(FLASH25_SECTORE_ERASE, channel);
-
- /*
- * Address inside the sector that we want to
- * erase.
- */
- kfile_putc(sector, channel);
-
- CS_DISABLE();
-
- /*
- * We check serial flash memory state, and wait until ready-flag
- * is hight.
- */
- flash25_waitReady();
-
- DB(kprintf("Erased sector [%d] in %d ms\n", sector, ticks_to_ms(timer_clock() - start_time)));
-
-}
-
-/**
- * Chip erase function.
- *
- * Erase all sector of serial flash memory.
- *
- * \note This operation could take a while.
- */
-void flash25_chipErase(void)
-{
- /*
- * Erase all chip could take a while,
- * for debug we measure that time
- * see datasheet to compare this time.
- */
- DB(ticks_t start_time = timer_clock());
-
- /*
- * To erase serial flash memory we must first
- * enable write with a WREN opcode command, before
- * the CHIP_ERASE opcode.
- */
- flash25_sendCmd(FLASH25_WREN);
- flash25_sendCmd(FLASH25_CHIP_ERASE);
-
- /*
- * We check serial flash memory state, and wait until ready-flag
- * is high.
- */
- flash25_waitReady();
-
- DB(kprintf("Erased all memory in %d ms\n", ticks_to_ms(timer_clock() - start_time)));
-
-}
-
-/**
- * Init data flash memory interface.
- */
-void flash25_init(struct KFile *fd, struct KFile *_channel)
-{
- //Set kfile struct type as a generic kfile structure.
- DB(fd->_type = KFT_GENERIC);
-
- // Set up data flash programming functions.
- fd->reopen = flash25_reopen;
- fd->close = flash25_close;
- fd->read = flash25_read;
- fd->write = flash25_write;
- fd->seek = kfile_genericSeek;
-
- /*
- * Init a local channel structure and flash kfile interface.
- */
- channel = _channel;
- flash25_reopen(fd);
-
- /*
- * Init data flash memory and micro pin.
- */
- if (!flash25_pin_init())
- ASSERT(0);
-}
-
-#if CONFIG_TEST
-
-/**
- * Test function for flash25.
- *
- * \note: This implentation use a SPI channel.
- */
-bool flash25_test(KFile *channel)
-{
- KFile fd;
- uint8_t test_buf[256];
-
- /*
- * Init a spi kfile interface and
- * flash driver.
- */
- flash25_init(&fd, channel);
-
- kprintf("Init serial flash\n");
-
- flash25_chipErase();
-
- flash25_sectorErase(FLASH25_SECT1);
- flash25_sectorErase(FLASH25_SECT2);
- flash25_sectorErase(FLASH25_SECT3);
- flash25_sectorErase(FLASH25_SECT4);
-
- /*
- * Launche a kfile test interface.
- */
- kprintf("Kfile test start..\n");
- if (!kfile_test(&fd, test_buf, NULL, sizeof(test_buf)))
- return false;
-
- return true;
-}
-#endif /* CONFIG_TEST */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Function library for serial Flash memory.
- *
- *
- * \version $Id$
- * \author Daniele Basile <asterix@develer.com>
- */
-
-
-#ifndef DRV_FLASH25_H
-#define DRV_FLASH25_H
-
-#include <kern/kfile.h>
-#include <cfg/compiler.h>
-
-
-#include <appconfig.h>
-
-/**
- * Type definition for serial flash memory.
- */
-typedef uint32_t flash25Addr_t;
-typedef uint32_t flash25Size_t;
-typedef uint8_t flash25Offset_t;
-
-
-/**
- * Memory definition.
- *
- * \note Below are defined valid serial flash memory support to
- * this drive. Every time we call flash25_init() function we check
- * if memory defined are right (see flash25.c form more detail).
- * \{
- */
-#define FLASH25_AT25F2048 1
-
-#if CONFIG_FLASH25 == FLASH25_AT25F2048
- #define FLASH25_MANUFACTURER_ID 0x1F // ATMEL
- #define FLASH25_DEVICE_ID 0x63 // Device ID
- #define FLASH25_PAGE_SIZE 256 // Page size in byte
- #define FLASH25_NUM_SECTOR 4 // Number of section in serial memory
- #define FLASH25_SECTOR_SIZE 65536UL // Section size in byte
- #define FLASH25_MEM_SIZE FLASH25_NUM_SECTOR * FLASH25_SECTOR_SIZE
- #define FLASH25_NUM_PAGE FLASH25_MEM_SIZE / FLASH25_PAGE_SIZE
-#elif
- #error Nothing memory defined in CONFIG_FLASH25 are support.
-#endif
-
-#define RDY_BIT 0x1 // Statuts of write cycle
-/* \} */
-
-/**
- * Serial flash opcode commands.
- */
-typedef enum {
- FLASH25_WREN = 0x6, ///< Set write enable latch
- FLASH25_WRDI = 0x4, ///< Reset enable write latch
- FLASH25_RDSR = 0x5, ///< Read status register
- FLASH25_WRSR = 0x1, ///< Write status register
- FLASH25_READ = 0x3, ///< Read data from memory array
- FLASH25_PROGRAM = 0x2, ///< Program data into memory array
- FLASH25_SECTORE_ERASE = 0x52, ///< Erase one sector in memory array
- FLASH25_CHIP_ERASE = 0x62, ///< Erase all sector in memory array
- FLASH25_RDID = 0x15 ///< Read Manufacturer and product ID
-} Flash25Opcode;
-
-/**
- * Serial flash sector memory address.
- */
-#if CONFIG_FLASH25 != FLASH25_AT25F2048
- #error Nothing memory defined in CONFIG_FLASH25 are support.
-#endif
-
-typedef enum {
- FLASH25_SECT1 = 0x0, ///< Sector 1 (0x0 -0xFFFF)
- FLASH25_SECT2 = 0x10000, ///< Sector 2 (0x10000 -0x1FFFF)
- FLASH25_SECT3 = 0x20000, ///< Sector 3 (0x20000 -0x2FFFF)
- FLASH25_SECT4 = 0x30000, ///< Sector 4 (0x30000 -0x3FFFF)
-} Flash25Sector;
-
-void flash25_init(struct KFile *fd, struct KFile *_channel);
-void flash25_chipErase(void);
-void flash25_sectorErase(Flash25Sector sector);
-bool flash25_test(KFile *channel);
-
-#endif /* DRV_FLASH25_H */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2003 Bernardo Innocenti
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief Keyboard driver (implementation)
- */
-
-#include <hw_kbd.h>
-
-#include <drv/timer.h>
-#include <drv/kbd.h>
-
-#include <cfg/debug.h>
-#include <cfg/module.h>
-#include <appconfig.h>
-
-/* Configuration sanity checks */
-#if !defined(CONFIG_KBD_POLL) || (CONFIG_KBD_POLL != KBD_POLL_SOFTINT && CONFIG_KBD_POLL != CONFIG_POLL_FREERTOS)
- #error CONFIG_KBD_POLL must be defined to either KBD_POLL_SOFTINT or CONFIG_POLL_FREERTOS
-#endif
-#if !defined(CONFIG_KBD_BEEP) || (CONFIG_KBD_BEEP != 0 && CONFIG_KBD_BEEP != 1)
- #error CONFIG_KBD_BEEP must be defined to either 0 or 1
-#endif
-#if !defined(CONFIG_KBD_OBSERVER) || (CONFIG_KBD_OBSERVER != 0 && CONFIG_KBD_OBSERVER != 1)
- #error CONFIG_KBD_OBSERVER must be defined to either 0 or 1
-#endif
-#if !defined(CONFIG_KBD_LONGPRESS) || (CONFIG_KBD_LONGPRESS != 0 && CONFIG_KBD_LONGPRESS != 1)
- #error CONFIG_KBD_LONGPRESS must be defined to either 0 or 1
-#endif
-
-#if CONFIG_KBD_BEEP
- #include <drv/buzzer.h>
-#endif
-
-#define KBD_CHECK_INTERVAL 10 /**< (ms) Timing for kbd softint */
-#define KBD_DEBOUNCE_TIME 30 /**< (ms) Debounce time */
-#define KBD_BEEP_TIME 5 /**< (ms) Duration of keybeep */
-
-#define KBD_REPEAT_DELAY 400 /**< (ms) Keyboard repeat delay for first character */
-#define KBD_REPEAT_RATE 100 /**< (ms) Initial interchar delay for keyboard repeat */
-#define KBD_REPEAT_MAXRATE 20 /**< (ms) Minimum delay for keyboard repeat */
-#define KBD_REPEAT_ACCEL 5 /**< (ms) Keyboard repeat speed increase */
-
-#define KBD_LNG_DELAY 1000 /**< (ms) Keyboard long pression keys delay */
-
-
-/** Status for keyboard repeat state machine */
-static enum { KS_IDLE, KS_REPDELAY, KS_REPEAT } kbd_rptStatus;
-
-
-static volatile keymask_t kbd_buf; /**< Single entry keyboard buffer */
-static volatile keymask_t kbd_cnt; /**< Number of keypress events in \c kbd_buf */
-static keymask_t kbd_rpt_mask; /**< Mask of repeatable keys. */
-
-#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
-static Timer kbd_timer; /**< Keyboard softtimer */
-#endif
-
-static List kbd_rawHandlers; /**< Raw keyboard handlers */
-static List kbd_handlers; /**< Cooked keyboard handlers */
-
-static KbdHandler kbd_defHandler; /**< The default keyboard handler */
-static KbdHandler kbd_debHandler; /**< The debounce keyboard handler */
-static KbdHandler kbd_rptHandler; /**< Auto-repeat keyboard handler */
-
-#if CONFIG_KBD_LONGPRESS
-static KbdHandler kbd_lngHandler; /**< Long pression keys handler */
-#endif
-
-#if CONFIG_KBD_OBSERVER
- #include <mware/observer.h>
- Subject kbd_subject;
-#endif
-
-
-/**
- * Poll keyboard and dispatch keys to handlers.
- *
- * Read the key states and invoke all keyboard
- * handlers to process the new state.
- *
- * Call this function periodically using a software
- * timer, an interrupt or a process.
- */
-static void kbd_poll(void)
-{
- /** Currently depressed key */
- static keymask_t current_key;
-
- struct KbdHandler *handler;
- keymask_t key = kbd_readkeys();
-
- /* Call raw input handlers */
- FOREACH_NODE(handler, &kbd_rawHandlers)
- key = handler->hook(key);
-
- /* If this key was not previously pressed */
- if (key != current_key)
- {
- /* Remember last key */
- current_key = key;
-
- /* Call cooked input handlers */
- FOREACH_NODE(handler, &kbd_handlers)
- key = handler->hook(key);
- }
-}
-
-#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
-
-/**
- * Keyboard soft-irq handler.
- */
-static void kbd_softint(UNUSED_ARG(iptr_t, arg))
-{
- kbd_poll();
- timer_add(&kbd_timer);
-}
-
-#elif CONFIG_KBD_POLL == CONFIG_POLL_FREERTOS
-
-#include "FreeRTOS.h"
-#include "task.h"
-
-static portTASK_FUNCTION(kbd_task, arg)
-{
- for (;;)
- {
- kbd_poll();
- timer_delay(KBD_CHECK_INTERVAL);
- }
-}
-
-#endif /* CONFIG_KBD_POLL */
-
-/**
- * \brief Read a key from the keyboard buffer.
- *
- * When a key is kept depressed between calls of this function a value
- * is returned only after the time specified with KBD_REPAT_DELAY to
- * avoid too fast keyboard repeat.
- *
- * \note Calls \c schedule() internally.
- *
- * \note This function is \b not interrupt safe!
- *
- * \return The mask of depressed keys or 0 if no keys are depressed.
- *
- */
-keymask_t kbd_peek(void)
-{
- keymask_t key = 0;
-
-// FIXME: make it optional
- /* Let other tasks run for a while */
- extern void schedule(void);
- schedule();
-
- /* Extract an event from the keyboard buffer */
- IRQ_DISABLE;
- if (kbd_cnt)
- {
- --kbd_cnt;
- key = kbd_buf;
- }
- IRQ_ENABLE;
-
- return key;
-}
-
-/**
- * Wait for a keypress and return the mask of depressed keys.
- *
- * \note This function is \b not interrupt safe!
- */
-keymask_t kbd_get(void)
-{
- keymask_t key;
-
- while (!(key = kbd_peek())) {}
-
- return key;
-}
-
-
-/**
- * Wait up to \c timeout ms for a keypress
- * and return the mask of depressed keys, or K_TIMEOUT
- * if the timeout was reacked.
- */
-keymask_t kbd_get_timeout(mtime_t timeout)
-{
- keymask_t key;
-
- ticks_t start = timer_clock();
- ticks_t stop = ms_to_ticks(timeout);
- do
- {
- if ((key = kbd_peek()))
- return key;
- }
- while (timer_clock() - start < stop);
-
- return K_TIMEOUT;
-}
-
-
-void kbd_addHandler(struct KbdHandler *handler)
-{
- KbdHandler *node;
- List *list;
-
- cpuflags_t flags;
- IRQ_SAVE_DISABLE(flags);
-
- /* Choose between raw and coocked handlers list */
- list = (handler->flags & KHF_RAWKEYS) ?
- &kbd_rawHandlers : &kbd_handlers;
-
- /*
- * Search for the first node whose priority
- * is lower than the timer we want to add.
- */
- FOREACH_NODE(node,list)
- if (node->pri < handler->pri)
- break;
-
- /* Enqueue handler in the handlers chain */
- INSERT_BEFORE(&handler->link, &node->link);
-
- IRQ_RESTORE(flags);
-}
-
-
-void kbd_remHandler(struct KbdHandler *handler)
-{
- /* Remove the handler */
- ATOMIC(REMOVE(&handler->link));
-}
-
-
-/**
- * This is the default key handler, called after
- * all other handlers have had their chance to
- * do their special processing. This handler
- * pushes all input in the keyboard FIFO buffer.
- */
-static keymask_t kbd_defHandlerFunc(keymask_t key)
-{
- if (key)
- {
- /* Force a single event in kbd buffer */
- kbd_buf = key;
- kbd_cnt = 1;
-
- #if CONFIG_KBD_OBSERVER
- observer_notify(&kbd_subject, KBD_EVENT_KEY, &key);
- #endif
-
- #if CONFIG_KBD_BEEP
- if (!(key & K_REPEAT))
- buz_beep(KBD_BEEP_TIME);
- #endif
- }
-
- /* Eat all input */
- return 0;
-}
-
-/**
- * Handle keyboard debounce
- */
-static keymask_t kbd_debHandlerFunc(keymask_t key)
-{
- /** Buffer for debounce */
- static keymask_t debounce_key;
-
- /** Timer for keyboard debounce */
- static ticks_t debounce_time;
-
- /** Key aquired after debounce */
- static keymask_t new_key;
-
-
- ticks_t now = timer_clock();
-
- if (key != debounce_key)
- {
- /* Reset debounce timer */
- debounce_key = key;
- debounce_time = now;
- }
- else if ((new_key != debounce_key)
- && (now - debounce_time > ms_to_ticks(KBD_DEBOUNCE_TIME)))
- {
- new_key = debounce_key;
- debounce_time = now;
- }
-
- return new_key;
-}
-
-#if CONFIG_KBD_LONGPRESS
-/**
- * Handle long pression keys.
- */
-static keymask_t kbd_lngHandlerFunc(keymask_t key)
-{
- static ticks_t start;
- ticks_t now = timer_clock();
-
- if (key & K_LNG_MASK)
- {
- if (now - start > ms_to_ticks(KBD_LNG_DELAY))
- key |= K_LONG;
- }
- else
- start = now;
- return key;
-}
-#endif
-
-/**
- * Set current mask of repeatable keys.
- */
-keymask_t kbd_setRepeatMask(keymask_t mask)
-{
- keymask_t oldmask = kbd_rpt_mask;
- ATOMIC(kbd_rpt_mask = mask);
- return oldmask;
-}
-
-/**
- * Handle keyboard repeat
- */
-static keymask_t kbd_rptHandlerFunc(keymask_t key)
-{
- /* Timer for keyboard repeat events. */
- static ticks_t repeat_time;
-
- /* Current repeat rate (for acceleration). */
- static ticks_t repeat_rate; /** Current repeat rate (for acceleration) */
-
- ticks_t now = timer_clock();
-
- switch (kbd_rptStatus)
- {
- case KS_IDLE:
- if (key & kbd_rpt_mask)
- {
- repeat_time = now;
- kbd_rptStatus = KS_REPDELAY;
- }
- break;
-
- case KS_REPDELAY:
- if (key & kbd_rpt_mask)
- {
- if (now - repeat_time > ms_to_ticks(KBD_REPEAT_DELAY))
- {
- key = (key & kbd_rpt_mask) | K_REPEAT;
- repeat_time = now;
- repeat_rate = ms_to_ticks(KBD_REPEAT_RATE);
- kbd_rptStatus = KS_REPEAT;
- }
- else
- key = 0;
- }
- else
- kbd_rptStatus = KS_IDLE;
- break;
-
- case KS_REPEAT:
- if (key & kbd_rpt_mask)
- {
- if (now - repeat_time > repeat_rate)
- {
- /* Enqueue a new event in the buffer */
- key = (key & kbd_rpt_mask) | K_REPEAT;
- repeat_time = now;
-
- /* Repeat rate acceleration */
- if (repeat_rate > ms_to_ticks(KBD_REPEAT_MAXRATE))
- repeat_rate -= ms_to_ticks(KBD_REPEAT_ACCEL);
- }
- else
- key = 0;
- }
- else
- kbd_rptStatus = KS_IDLE;
-
- break;
- }
-
- return key;
-}
-
-
-MOD_DEFINE(kbd)
-
-/**
- * Initialize keyboard ports and softtimer
- */
-void kbd_init(void)
-{
-#if CONFIG_KBD_BEEP
- MOD_CHECK(buzzer);
-#endif
-
- KBD_HW_INIT;
-
- /* Init handlers lists */
- LIST_INIT(&kbd_handlers);
- LIST_INIT(&kbd_rawHandlers);
-
- /* Add debounce keyboard handler */
- kbd_debHandler.hook = kbd_debHandlerFunc;
- kbd_debHandler.pri = 100; /* high priority */
- kbd_debHandler.flags = KHF_RAWKEYS;
- kbd_addHandler(&kbd_debHandler);
-
- #if CONFIG_KBD_LONGPRESS
- /* Add long pression keyboard handler */
- kbd_lngHandler.hook = kbd_lngHandlerFunc;
- kbd_lngHandler.pri = 90; /* high priority */
- kbd_lngHandler.flags = KHF_RAWKEYS;
- kbd_addHandler(&kbd_lngHandler);
- #endif
-
- /* Add repeat keyboard handler */
- kbd_rptHandler.hook = kbd_rptHandlerFunc;
- kbd_rptHandler.pri = 80; /* high priority */
- kbd_rptHandler.flags = KHF_RAWKEYS;
- kbd_addHandler(&kbd_rptHandler);
-
- /* Add default keyboard handler */
- kbd_defHandler.hook = kbd_defHandlerFunc;
- kbd_defHandler.pri = -128; /* lowest priority */
- kbd_addHandler(&kbd_defHandler);
-
-#if CONFIG_KBD_OBSERVER
- observer_InitSubject(&kbd_subject);
-#endif
-
-#if CONFIG_KBD_POLL == KBD_POLL_SOFTINT
-
- MOD_CHECK(timer);
-
- /* Add kbd handler to soft timers list */
- event_initSoftInt(&kbd_timer.expire, kbd_softint, NULL);
- timer_setDelay(&kbd_timer, ms_to_ticks(KBD_CHECK_INTERVAL));
- timer_add(&kbd_timer);
-
-#elif CONFIG_KBD_POLL == CONFIG_POLL_FREERTOS
-
- /* Create a timer specific thread */
- xTaskCreate(kbd_task, "kbd", CONFIG_STACK_KBD,
- NULL, CONFIG_PRI_KBD, NULL);
-
-#else
- #error "Define keyboard poll method"
-#endif
-
- MOD_INIT(kbd);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2003 Bernardo Innocenti
- *
- * -->
- *
- * \brief Keyboard driver (interface)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#ifndef DRV_KBD_H
-#define DRV_KBD_H
-
-#include <kbd_map.h>
-#include <cfg/compiler.h>
-#include <mware/list.h>
-#include <appconfig.h> // CONFIG_KBD_OBSERVER
-
-/**
- * \name Keyboard polling modes.
- *
- * Define CONFIG_KBD_POLL to one of these.
- *
- * \{
- */
-#define KBD_POLL_SOFTINT 1
-#define KBD_POLL_FREERTOS 2
-/* \} */
-
-/**
- * Keyboard handler descriptor
- */
-typedef struct KbdHandler
-{
- Node link;
- keymask_t (*hook)(keymask_t); /**< Hook function */
- int8_t pri; /**< Priority in input queue */
- uint8_t flags; /**< See below for definitions */
-} KbdHandler;
-
-#define KHF_RAWKEYS BV(0) /**< Handler gets raw key events */
-
-
-void kbd_init(void);
-keymask_t kbd_peek(void);
-keymask_t kbd_get(void);
-keymask_t kbd_get_timeout(mtime_t timeout);
-void kbd_addHandler(struct KbdHandler *handler);
-void kbd_remHandler(struct KbdHandler *handler);
-keymask_t kbd_setRepeatMask(keymask_t mask);
-
-#if CONFIG_KBD_OBSERVER
- struct Subject;
-
- /** Subject structure for keyboard observers. */
- extern struct Subject kbd_subject;
-
- enum
- {
- /* Event for key presses. */
- KBD_EVENT_KEY = 0x100
- };
-#endif
-
-#endif /* DRV_KBD_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000, 2001, 2002 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \brief General pourpose debug support for embedded systems (implementation).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#include <cpu/irq.h>
-#include <cpu/attr.h>
-#include <cpu/types.h>
-
-#include <cfg/macros.h> /* for BV() */
-#include <cfg/debug.h>
-
-#include <appconfig.h>
-#warning what about these?
-//#include <hw_cpu.h> /* for CLOCK_FREQ */
-//#include <hw_ser.h> /* Required for bus macros overrides */
-
-#include <mware/formatwr.h> /* for _formatted_write() */
-#include <mware/pgm.h>
-
-#ifdef _DEBUG
-
-#if CPU_HARVARD && !defined(_PROGMEM)
- #error This module build correctly only in program memory!
-#endif
-
-
-#if OS_HOSTED
- #include <stdio.h>
- #define KDBG_WAIT_READY() do { /*nop*/ } while(0)
- #define KDBG_WRITE_CHAR(c) putc((c), stderr)
- #define KDBG_MASK_IRQ(old) do { (void)(old); } while(0)
- #define KDBG_RESTORE_IRQ(old) do { /*nop*/ } while(0)
- typedef char kdbg_irqsave_t; /* unused */
-
- #define kdbg_hw_init() do {} while (0) ///< Not needed
-
- #if CONFIG_KDEBUG_PORT == 666
- #error BITBANG debug console missing for this platform
- #endif
-#else
- #include CPU_CSOURCE(kdebug)
-#endif
-
-
-void kdbg_init(void)
-{
- /* Init debug hw */
- kdbg_hw_init();
- kputs("\n\n*** BeRTOS DBG START ***\n");
-}
-
-
-/**
- * Output one character to the debug console
- */
-static void __kputchar(char c, UNUSED_ARG(void *, unused))
-{
- /* Poll while serial buffer is still busy */
- KDBG_WAIT_READY();
-
- /* Send '\n' as '\r\n' for dumb terminals */
- if (c == '\n')
- {
- KDBG_WRITE_CHAR('\r');
- KDBG_WAIT_READY();
- }
-
- KDBG_WRITE_CHAR(c);
-}
-
-
-void kputchar(char c)
-{
- /* Mask serial TX intr */
- kdbg_irqsave_t irqsave;
- KDBG_MASK_IRQ(irqsave);
-
- __kputchar(c, 0);
-
- /* Restore serial TX intr */
- KDBG_RESTORE_IRQ(irqsave);
-}
-
-
-static void PGM_FUNC(kvprintf)(const char * PGM_ATTR fmt, va_list ap)
-{
-#if CONFIG_PRINTF
- /* Mask serial TX intr */
- kdbg_irqsave_t irqsave;
- KDBG_MASK_IRQ(irqsave);
-
- PGM_FUNC(_formatted_write)(fmt, __kputchar, 0, ap);
-
- /* Restore serial TX intr */
- KDBG_RESTORE_IRQ(irqsave);
-#else
- /* A better than nothing printf() surrogate. */
- PGM_FUNC(kputs)(fmt);
-#endif /* CONFIG_PRINTF */
-}
-
-void PGM_FUNC(kprintf)(const char * PGM_ATTR fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- PGM_FUNC(kvprintf)(fmt, ap);
- va_end(ap);
-}
-
-void PGM_FUNC(kputs)(const char * PGM_ATTR str)
-{
- char c;
-
- /* Mask serial TX intr */
- kdbg_irqsave_t irqsave;
- KDBG_MASK_IRQ(irqsave);
-
- while ((c = PGM_READ_CHAR(str++)))
- __kputchar(c, 0);
-
- KDBG_RESTORE_IRQ(irqsave);
-}
-
-
-/**
- * Cheap function to print small integers without using printf().
- */
-int kputnum(int num)
-{
- int output_len = 0;
- int divisor = 10000;
- int digit;
-
- do
- {
- digit = num / divisor;
- num %= divisor;
-
- if (digit || output_len || divisor == 1)
- {
- kputchar(digit + '0');
- ++output_len;
- }
- }
- while (divisor /= 10);
-
- return output_len;
-}
-
-
-static void klocation(const char * PGM_ATTR file, int line)
-{
- PGM_FUNC(kputs)(file);
- kputchar(':');
- kputnum(line);
- PGM_FUNC(kputs)(PGM_STR(": "));
-}
-
-int PGM_FUNC(__assert)(const char * PGM_ATTR cond, const char * PGM_ATTR file, int line)
-{
- klocation(file, line);
- PGM_FUNC(kputs)(PGM_STR("Assertion failed: "));
- PGM_FUNC(kputs)(cond);
- kputchar('\n');
- BREAKPOINT;
- return 1;
-}
-
-/*
- * Unfortunately, there's no way to get __func__ in
- * program memory, so we waste quite a lot of RAM in
- * AVR and other Harvard processors.
- */
-void PGM_FUNC(__trace)(const char *name)
-{
- PGM_FUNC(kprintf)(PGM_STR("%s()\n"), name);
-}
-
-void PGM_FUNC(__tracemsg)(const char *name, const char * PGM_ATTR fmt, ...)
-{
- va_list ap;
-
- PGM_FUNC(kprintf)(PGM_STR("%s(): "), name);
- va_start(ap, fmt);
- PGM_FUNC(kvprintf)(fmt, ap);
- va_end(ap);
- kputchar('\n');
-}
-
-int PGM_FUNC(__invalid_ptr)(void *value, const char * PGM_ATTR name, const char * PGM_ATTR file, int line)
-{
- klocation(file, line);
- PGM_FUNC(kputs)(PGM_STR("Invalid ptr: "));
- PGM_FUNC(kputs)(name);
- #if CONFIG_PRINTF
- PGM_FUNC(kprintf)(PGM_STR(" = 0x%p\n"), value);
- #else
- (void)value;
- kputchar('\n');
- #endif
- return 1;
-}
-
-
-void __init_wall(long *wall, int size)
-{
- while(size--)
- *wall++ = WALL_VALUE;
-}
-
-
-int PGM_FUNC(__check_wall)(long *wall, int size, const char * PGM_ATTR name, const char * PGM_ATTR file, int line)
-{
- int i, fail = 0;
-
- for (i = 0; i < size; i++)
- {
- if (wall[i] != WALL_VALUE)
- {
- klocation(file, line);
- PGM_FUNC(kputs)(PGM_STR("Wall broken: "));
- PGM_FUNC(kputs)(name);
- #if CONFIG_PRINTF
- PGM_FUNC(kprintf)(PGM_STR("[%d] (0x%p) = 0x%lx\n"), i, wall + i, wall[i]);
- #else
- kputchar('\n');
- #endif
- fail = 1;
- }
- }
-
- return fail;
-}
-
-
-#if CONFIG_PRINTF
-
-/**
- * Dump binary data in hex
- */
-void kdump(const void *_buf, size_t len)
-{
- const unsigned char *buf = (const unsigned char *)_buf;
-
- while (len--)
- kprintf("%02X", *buf++);
- kputchar('\n');
-}
-
-#endif /* CONFIG_PRINTF */
-
-#endif /* _DEBUG */
+++ /dev/null
-/**
- * \file
- * <!--
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- * This file is part of DevLib - See README.devlib for information.
- * -->
- *
- * \version $Id: lcd_gfx.h,v 1.6 2006/07/19 12:56:25 bernie Exp $
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Displaytech 32122A LCD driver
- */
-#ifndef LCD_GFX_H
-#define LCD_GFX_H
-
-/* Predefined LCD PWM contrast values */
-#define LCD_DEF_PWM 145
-#define LCD_MAX_PWM 505
-#define LCD_MIN_PWM 130
-
-/* Display bitmap dims */
-#define LCD_WIDTH 128
-#define LCD_HEIGHT 64
-
-/* fwd decl */
-struct Bitmap;
-
-extern struct Bitmap lcd_bitmap;
-
-void lcd_init(void);
-void lcd_setPwm(int duty);
-void lcd_blitBitmap(struct Bitmap *bm);
-
-#endif /* LCD_GFX_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Custom control for graphics LCD emulation (interface)
- */
-
-#include "lcd_gfx_qt.h"
-#include <emul/emul.h>
-#include <cfg/debug.h>
-#include <gfx/gfx.h> // CONFIG_BITMAP_FMT
-
-#include <QtGui/QPainter>
-#include <QtGui/QImage>
-#include <QtGui/QSizePolicy>
-#include <QtCore/QSize>
-
-// Display colors
-#define LCD_FG_COLOR 0x0, 0x0, 0x0
-#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
-
-
-EmulLCD::EmulLCD(QWidget *parent, const char *name) :
- QFrame(parent, name, Qt::WRepaintNoErase | Qt::WResizeNoErase),
- fg_color(LCD_FG_COLOR),
- bg_color(LCD_BG_COLOR)
-{
- // initialize bitmap
- memset(raster, 0xAA, sizeof(raster));
-
- // set widget frame
- setFrameStyle(QFrame::Panel | QFrame::Sunken);
- frame_width = frameWidth();
-}
-
-
-EmulLCD::~EmulLCD()
-{
- // nop
-}
-
-
-QSizePolicy EmulLCD::sizePolicy() const
-{
- return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
-}
-
-
-QSize EmulLCD::sizeHint() const
-{
- return QSize(
- WIDTH + frame_width * 2,
- HEIGHT + frame_width * 2);
-}
-
-
-void EmulLCD::paintEvent(QPaintEvent * /*event*/)
-{
- QPainter p(this);
- QImage img(raster, WIDTH, HEIGHT, 1, NULL, 0, QImage::BigEndian);
-
- p.setBackgroundMode(Qt::OpaqueMode);
- p.setPen(fg_color);
- p.setBackgroundColor(bg_color);
- p.drawImage(frame_width, frame_width, img);
-}
-
-void EmulLCD::writeRaster(uint8_t *new_raster)
-{
-#if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
-
- /* Straight copy */
- memcpy(raster, new_raster, sizeof(raster));
-
-#elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
-
- /* Rotation */
- for (int y = 0; y < HEIGHT; ++y)
- {
- for (int xbyte = 0; xbyte < WIDTH/8; ++xbyte)
- {
- uint8_t v = 0;
- for (int xbit = 0; xbit < 8; ++xbit)
- v |= (new_raster[(xbyte * 8 + xbit) + (y / 8) * WIDTH] & (1 << (y%8)) )
- ? 0 : (1 << (7 - xbit));
-
- raster[y * ((WIDTH + 7) / 8) + xbyte] = v;
- }
- }
-
-#else
- #error Unsupported bitmap format
-#endif
-
- repaint();
-}
-
-
-
-#include <gfx/gfx.h>
-#include <cfg/debug.h>
-
-DECLARE_WALL(wall_before_raster, WALL_SIZE)
-/**
- * Raster buffer to draw into.
- *
- * Bits in the bitmap bytes have vertical orientation,
- * as required by the LCD driver.
- */
-static uint8_t lcd_raster[RAST_SIZE(EmulLCD::WIDTH, EmulLCD::HEIGHT)];
-DECLARE_WALL(wall_after_raster, WALL_SIZE)
-
-/** Default LCD bitmap */
-struct Bitmap lcd_bitmap;
-
-/*extern "C"*/ void lcd_init(void)
-{
- //FIXME INIT_WALL(wall_before_raster);
- //FIXME INIT_WALL(wall_after_raster);
- gfx_bitmapInit(&lcd_bitmap, lcd_raster, EmulLCD::WIDTH, EmulLCD::HEIGHT);
- gfx_bitmapClear(&lcd_bitmap);
-}
-
-/*extern "C"*/ void lcd_blitBitmap(Bitmap *bm)
-{
- //FIXME CHECK_WALL(wall_before_raster);
- //FIXME CHECK_WALL(wall_after_raster);
- emul->emulLCD->writeRaster(bm->raster);
-}
-
-#include "lcd_gfx_qt_moc.cpp"
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Custom control for graphics LCD emulation (interface)
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.5 2006/05/28 12:17:57 bernie
- *#* Drop almost all the Qt3 cruft.
- *#*
- *#* Revision 1.4 2006/02/20 02:00:40 bernie
- *#* Port to Qt 4.1.
- *#*
- *#* Revision 1.3 2006/02/15 09:13:16 bernie
- *#* Switch to BITMAP_FMT_PLANAR_V_LSB.
- *#*
- *#* Revision 1.2 2006/02/10 12:33:51 bernie
- *#* Make emulator display a bit larger.
- *#*
- *#* Revision 1.1 2006/01/16 03:51:35 bernie
- *#* Add LCD Qt emulator.
- *#*
- *#*/
-
-#ifndef DRV_LCD_GFX_QT_H
-#define DRV_LCD_GFX_QT_H
-
-#include <QtGui/QColor>
-#include <QtGui/QFrame>
-
-// fwd decls
-class QSizePolicy;
-class QPaintEvent;
-class QResizeEvent;
-
-
-class EmulLCD : public QFrame
-{
- Q_OBJECT
-
-public:
-// Attributes
- enum { WIDTH = 128, HEIGHT = 64 };
-
-// Construction
- EmulLCD(QWidget *parent = 0, const char *name = 0);
- virtual ~EmulLCD();
-
-// Base class overrides
-protected:
- virtual QSizePolicy sizePolicy() const;
- virtual QSize sizeHint() const;
- virtual void paintEvent(QPaintEvent *event);
-
-// Operations
-public:
- void writeRaster(uint8_t *raster);
-
-// Implementation
-protected:
- /// Frame thickness
- int frame_width;
-
- /// LCD colors
- QColor fg_color, bg_color;
-
- /// Pixel storage
- unsigned char raster[(WIDTH * HEIGHT) / 8];
-};
-
-#endif // DRV_LCD_GFX_QT_H
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief dot-matrix LCD test.
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.3 2006/01/17 23:00:26 bernie
- *#* Don't use hardcoded coordinates.
- *#*
- *#* Revision 1.2 2006/01/17 02:31:57 bernie
- *#* Test gfx with the usual pentagons.
- *#*
- *#* Revision 1.1 2006/01/16 03:51:35 bernie
- *#* Add LCD Qt emulator.
- *#*
- *#*/
-
-#include <emul/emul.h>
-#include <drv/lcd_gfx.h>
-#include <gfx/gfx.h>
-
-static void magic(struct Bitmap *bitmap, coord_t x, coord_t y)
-{
- static const coord_t coords[] = { 120, 34, 90, 90, 30, 90, 0, 34, 60, 0, 90, 90, 0, 34, 120, 34, 30, 90, 60, 0 };
- unsigned int i;
-
- gfx_moveTo(bitmap, coords[countof(coords)-2]/2 + x, coords[countof(coords)-1]/3 + y);
- for (i = 0; i < countof(coords); i += 2)
- gfx_lineTo(bitmap, coords[i]/2 + x, coords[i+1]/3 + y);
-}
-
-int main(int argc, char *argv[])
-{
- emul_init(&argc, argv);
- lcd_init();
-
- coord_t x = 0, y = LCD_WIDTH / 2;
- coord_t xdir = +1, ydir = -1;
- Bitmap *bm = &lcd_bitmap;
-
- for(;;)
- {
- gfx_bitmapClear(bm);
- gfx_setClipRect(bm, 0, 0, bm->width, bm->height);
- gfx_rectDraw(bm, 10, 10, bm->width-10, bm->height-10);
- gfx_setClipRect(bm, 11, 11, bm->width-11, bm->height-11);
- magic(bm, x, y);
-
- x += xdir;
- y += ydir;
- if (x >= bm->width) xdir = -1;
- if (x <= -50) xdir = +1;
- if (y >= bm->height) ydir = -1;
- if (y <= -50) ydir = +1;
-
- lcd_blit_bitmap(bm);
- emul_idle();
- usleep(10000);
- }
-
- emul_cleanup();
- return 0;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief LM044L type LCD hardware module (impl.)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#include "lcd_hd44.h"
-#include "hw_lcd.h"
-#include <cfg/arch_config.h>
-#include <drv/timer.h>
-
-#if defined(LCD_READ_H) && defined(LCD_READ_L) && defined(LCD_WRITE_H) && defined(LCD_WRITE_L)
- #define CONFIG_LCD_4BIT 1
-#elif defined(LCD_READ) && defined(LCD_WRITE)
- #define CONFIG_LCD_4BIT 0
-#else
- #error Incomplete or missing LCD_READ/LCD_WRITE macros
-#endif
-
-/** Flag di stato del display */
-#define LCDF_BUSY BV(7)
-
-#if CONFIG_LCD_ADDRESS_FAST == 1
-#define lcd_address(x) lcd_address[x]
-/**
- * Addresses of LCD display character positions, expanded
- * for faster access (DB7 = 1).
- */
-static const uint8_t lcd_address[] =
-{
- /* row 0 */
- 0x80, 0x81, 0x82, 0x83,
- 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8A, 0x8B,
- 0x8C, 0x8D, 0x8E, 0x8F,
-#if LCD_COLS > 16
- 0x90, 0x91, 0x92, 0x93,
-#endif
-
- /* row 1 */
- 0xC0, 0xC1, 0xC2, 0xC3,
- 0xC4, 0xC5, 0xC6, 0xC7,
- 0xC8, 0xC9, 0xCA, 0xCB,
- 0xCC, 0xCD, 0xCE, 0xCF,
-#if LCD_COLS > 16
- 0xD0, 0xD1, 0xD2, 0xD3,
-#endif
-
-#if LCD_ROWS > 2
- /* row 2 */
- 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9A, 0x9B,
- 0x9C, 0x9D, 0x9E, 0x9F,
- 0xA0, 0xA1, 0xA2, 0xA3,
-#if LCD_COLS > 16
- 0xA4, 0xA5, 0xA6, 0xA7,
-#endif
-
- /* row 3 */
- 0xD4, 0xD5, 0xD6, 0xD7,
- 0xD8, 0xD9, 0xDA, 0xDB,
- 0xDC, 0xDD, 0xDE, 0xDF,
- 0xE0, 0xE1, 0xE2, 0xE3,
-#if LCD_COLS > 16
- 0xE4, 0xE5, 0xE6, 0xE7,
-#endif
-
-#endif /* LCD_ROWS > 2 */
-};
-
-STATIC_ASSERT(countof(lcd_address) == LCD_ROWS * LCD_COLS);
-#else /* CONFIG_LCD_ADDRESS_FAST == 0 */
-
-static const uint8_t col_address[] =
-{
- 0x80,
- 0xC0,
-#if LCD_ROWS > 2
- 0x94,
- 0xD4
-#endif
-};
-STATIC_ASSERT(countof(col_address) == LCD_ROWS);
-/**
- * Addresses of LCD display character positions, calculated runtime to save RAM
- */
-static uint8_t lcd_address(uint8_t addr)
-{
- return col_address[addr / LCD_COLS] + addr % LCD_COLS;
-}
-#endif /* CONFIG_LCD_ADDRESS_FAST */
-
-/**
- * Current display position. We remember this to optimize
- * LCD output by avoiding to set the address every time.
- */
-static lcdpos_t lcd_current_addr;
-
-
-#if !defined(ARCH_EMUL) || !(ARCH & ARCH_EMUL)
-/* __________________
- * RS
- *
- * R/W __________________
- * _______
- * ENA _____/ \____
- *
- * DATA -<================
- */
-INLINE void lcd_dataWrite(uint8_t data)
-{
-#if CONFIG_LCD_4BIT
- /* Write high nibble */
- LCD_WRITE_H(data);
- LCD_SET_E;
- LCD_DELAY_WRITE;
- LCD_CLR_E;
- LCD_DELAY_WRITE;
-
- /* Write low nibble */
- LCD_WRITE_L(data);
- LCD_SET_E;
- LCD_DELAY_WRITE;
- LCD_CLR_E;
- LCD_DELAY_WRITE;
-
-#else /* !CONFIG_LCD_4BIT */
-
- /* Write data */
- LCD_WRITE(data);
- LCD_SET_E;
- LCD_DELAY_WRITE;
- LCD_CLR_E;
- LCD_DELAY_WRITE;
-
-#endif /* !CONFIG_LCD_4BIT */
-}
-
-/* __________________
- * RS
- * ____________
- * R/W __/ \__
- * _______
- * ENA _____/ \____
- * ______ ____
- * DATA X/ \====/
- */
-INLINE uint8_t lcd_dataRead(void)
-{
- uint8_t data;
-
- LCD_SET_RD;
- LCD_DB_IN; /* Set bus as input! */
- LCD_DELAY_READ;
-
-#if CONFIG_LCD_4BIT
-
- /* Read high nibble */
- LCD_SET_E;
- LCD_DELAY_READ;
- data = LCD_READ_H;
- LCD_CLR_E;
- LCD_DELAY_READ;
-
- /* Read low nibble */
- LCD_SET_E;
- LCD_DELAY_READ;
- data |= LCD_READ_L;
- LCD_CLR_E;
- LCD_DELAY_READ;
-
-#else /* !CONFIG_LCD_4BIT */
-
- /* Read data */
- LCD_SET_E;
- LCD_DELAY_READ;
- data = LCD_READ;
- LCD_CLR_E;
- LCD_DELAY_READ;
-
-#endif /* !CONFIG_LCD_4BIT */
-
- LCD_CLR_RD;
- LCD_DB_OUT; /* Reset bus as output! */
-
- return data;
-}
-
-/* ___ __
- * RS \___________/
- *
- * READ __________________
- * _______
- * ENA _____/ \____
- *
- * DATA --<===============
- */
-INLINE void lcd_regWrite(uint8_t data)
-{
- LCD_CLR_RS;
- lcd_dataWrite(data);
- LCD_SET_RS;
-}
-
-/* __ _
- * RS \_____________/
- * ___________
- * READ ___/ \__
- * _______
- * ENA _____/ \____
- * ______ ____
- * DATA X/ \====/
- */
-INLINE uint8_t lcd_regRead(void)
-{
- uint8_t data;
-
- LCD_CLR_RS;
- data = lcd_dataRead();
- LCD_SET_RS;
- return data;
-}
-
-#if CONFIG_LCD_4BIT
-
-INLINE void lcd_mode4Bit(void)
-{
- LCD_CLR_RS;
-
- LCD_WRITE_H(LCD_CMD_SETFUNC);
- LCD_SET_E;
- LCD_DELAY_WRITE;
- LCD_CLR_E;
- LCD_DELAY_WRITE;
-
- LCD_SET_RS;
-}
-
-#endif /* CONFIG_LCD_4BIT */
-
-#else /* ARCH_EMUL */
-
-extern void Emul_LCDWriteReg(uint8_t d);
-extern uint8_t Emul_LCDReadReg(void);
-extern void Emul_LCDWriteData(uint8_t d);
-extern uint8_t Emul_LCDReadData(void);
-
-#define lcd_regWrite(d) Emul_LCDWriteReg(d)
-#define lcd_regRead(d) Emul_LCDReadReg()
-#define lcd_dataWrite(d) Emul_LCDWriteData(d)
-#define lcd_dataRead(d) Emul_LCDReadData()
-
-#endif /* ARCH_EMUL */
-
-
-/**
- * Wait until the LCD busy flag clears.
- */
-void lcd_waitBusy(void)
-{
- for (;;)
- {
- uint8_t val = lcd_regRead();
- if (!(val & LCDF_BUSY))
- break;
- }
-}
-
-
-/**
- * Move the cursor to \a addr, only if not already there.
- */
-void lcd_moveTo(uint8_t addr)
-{
- if (addr != lcd_current_addr)
- {
- lcd_waitBusy();
- lcd_regWrite(lcd_address(addr));
- lcd_current_addr = addr;
- }
-}
-
-
-/**
- * Write a value in LCD data register, waiting for the busy flag.
- */
-void lcd_setReg(uint8_t val)
-{
- lcd_waitBusy();
- lcd_regWrite(val);
-}
-
-#include <cfg/debug.h>
-/**
- * Write the character \a c on display address \a addr.
- *
- * NOTE: argh, the HD44 lcd type is a bad beast: our
- * move/write -> write optimization requires this mess
- * because display lines are interleaved!
- */
-void lcd_putc(uint8_t addr, uint8_t c)
-{
- if (addr != lcd_current_addr)
- lcd_setReg(lcd_address(addr));
-
- lcd_waitBusy();
- lcd_dataWrite(c);
- lcd_current_addr = addr + 1;
-
- /* If we are at end of display wrap the address to 0 */
- if (lcd_current_addr == LCD_COLS * LCD_ROWS)
- lcd_current_addr = 0;
-
- /* If we are at the end of a row put the cursor at the beginning of the next */
- if (!(lcd_current_addr % LCD_COLS))
- lcd_setReg(lcd_address(lcd_current_addr));
-}
-
-
-/**
- * Remap the glyph of a character.
- *
- * glyph - bitmap of 8x8 bits.
- * code - must be 0-7 for the Hitachi LCD-II controller.
- */
-void lcd_remapChar(const char *glyph, char code)
-{
- int i;
-
- /* Set CG RAM address */
- lcd_setReg((uint8_t)((1<<6) | (code << 3)));
-
- /* Write bitmap data */
- for (i = 0; i < 8; i++)
- {
- lcd_waitBusy();
- lcd_dataWrite(glyph[i]);
- }
-
- /* Move back to original address */
- lcd_setReg(lcd_address(lcd_current_addr));
-}
-
-
-#if 0 /* unused */
-void lcd_remapfont(void)
-{
- static const char lcd_glyphs[8] =
- {
- 0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x04, 0x00 /* up arrow */
- };
- int i;
-
- for (i = 0; i < 15; i++)
- lcd_remapChar(i, bernie_char);
-
-
- lcd_setAddr(lcd_DefLayer, 0);
- for (i = 0; i < 80; i++)
- lcd_putCharUnlocked(i);
-}
-#endif /* unused */
-
-void lcd_hw_init(void)
-{
- lcd_bus_init();
-
- timer_delay(50);
-
-#if CONFIG_LCD_4BIT
- lcd_mode4Bit();
- timer_delay(2);
-#endif /* CONFIG_LCD_4BIT */
-
- lcd_regWrite(LCD_CMD_SETFUNC);
- timer_delay(2);
-
- lcd_regWrite(LCD_CMD_DISPLAY_ON);
- timer_delay(2);
-
- lcd_regWrite(LCD_CMD_CLEAR);
- timer_delay(2);
-
-#if !CONFIG_LCD_4BIT
- lcd_regWrite(LCD_CMD_RESET_DDRAM); // 4 bit mode doesn't allow char reprogramming
-#endif
- lcd_regWrite(LCD_CMD_DISPLAYMODE);
- timer_delay(2);
-}
-
-#if CONFIG_TEST
-
-void lcd_hw_test(void)
-{
- lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 3);
- timer_delay(1);
- kprintf("3 -> %02X\n", lcd_regRead());
- timer_delay(1);
-
- for (int i = 0; i < 10; i++)
- {
- lcd_dataWrite('c');
- timer_delay(1);
- kprintf("addr = %02X\n", lcd_regRead());
- timer_delay(1);
- }
-
- lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 0x4a);
- timer_delay(1);
- kprintf("4A -> %02X\n", lcd_regRead());
- timer_delay(1);
-
- lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 0x52);
- timer_delay(1);
- kprintf("52 -> %02X\n", lcd_regRead());
- timer_delay(1);
-
- lcd_regWrite(LCD_CMD_SET_DDRAMADDR | 0x1F);
- timer_delay(1);
- kprintf("1F -> %02X\n", lcd_regRead());
- timer_delay(1);
-}
-
-#endif /* CONFIG_TEST */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Hitachi HD44780 and clones LCD module (interface)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#ifndef DRV_LCD_HD44_H
-#define DRV_LCD_HD44_H
-
-#include <appconfig.h>
-#include <cfg/compiler.h> /* For stdint types */
-
-/**
- * \name Display dimensions (in chars)
- * \{
- */
-#define LCD_ROWS 2
-#define LCD_COLS 16
-/* \} */
-
-/**
- * \name Hitachi HD44 commands.
- * \{
- */
-#define LCD_CMD_DISPLAY_INI 0x30
-
-#if CONFIG_LCD_4BIT
- #define LCD_CMD_SETFUNC 0x28 /**< 4 bits, 2 lines, 5x7 dots */
-#else
- #define LCD_CMD_SETFUNC 0x38 /**< 8 bits, 2 lines, 5x7 dots */
-#endif
-
-#define LCD_CMD_DISPLAY_ON 0x0F /**< Switch on display */
-#define LCD_CMD_DISPLAY_OFF 0x08 /**< Switch off display */
-#define LCD_CMD_CLEAR 0x01 /**< Clear display */
-#define LCD_CMD_CURSOR_BLOCK 0x0D /**< Show cursor (block) */
-#define LCD_CMD_CURSOR_LINE 0x0F /**< Show cursor (line) */
-#define LCD_CMD_CURSOR_OFF 0x0C /**< Hide cursor */
-#define LCD_CMD_DISPLAYMODE 0x06
-#define LCD_CMD_SET_CGRAMADDR 0x40
-#define LCD_CMD_RESET_DDRAM 0x80
-#define LCD_CMD_SET_DDRAMADDR 0x80
-#define LCD_CMD_DISPLAY_SHIFT 0x18
-#define LCD_CMD_MOVESHIFT_LEFT 0x00
-#define LCD_CMD_MOVESHIFT_RIGHT 0x04
-/*\}*/
-
-/** Type for combined LCD cursor position (x,y). */
-typedef uint8_t lcdpos_t;
-
-void lcd_waitBusy(void);
-void lcd_moveTo(uint8_t addr);
-void lcd_setReg(uint8_t val);
-void lcd_putc(uint8_t a, uint8_t c);
-void lcd_remapChar(const char *glyph, char code);
-void lcd_hw_init(void);
-void lcd_hw_test(void);
-
-#endif /* DRV_LCD_HD44_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.1 2006/01/16 03:51:35 bernie
- *#* Add LCD Qt emulator.
- *#*
- *#*/
-
-#include <qpainter.h>
-#include <qfont.h>
-#include <qsizepolicy.h>
-#include <qsize.h>
-#include "EmulLCD.h"
-#include "Emul.h"
-
-
-// Display colors
-#define LCD_FG_COLOR 0x0, 0x0, 0x0
-#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
-
-
-EmulLCD::EmulLCD(QWidget *parent, const char *name) :
- QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
- lcd_font("courier", 18),
- fg_color(LCD_FG_COLOR),
- bg_color(LCD_BG_COLOR),
- cr_row(0),
- cr_col(0),
- cgramaddr(-1),
- show_cursor(true)
-{
- // initialize DDRAM
- memcpy(ddram,
- "01234567890123456789"
- "abcdefghijhlmnopqrst"
- "ABCDEFGHIJKLMNOPQRST"
- "!@#$%^&*()_+|{}':?><",
- sizeof(ddram));
-
- // setup font
- lcd_font.setFixedPitch(true);
- setFont(lcd_font);
-
- // get exact font size
- QFontMetrics fm(lcd_font);
- font_width = fm.width(QChar(' '));
- font_height = fm.height();
-
- // set widget frame
- setFrameStyle(QFrame::Panel | QFrame::Sunken);
-// setLineWidth(2);
- frame_width = frameWidth();
-}
-
-
-EmulLCD::~EmulLCD()
-{
- // nop
-}
-
-
-QSizePolicy EmulLCD::sizePolicy() const
-{
- return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
-}
-
-
-QSize EmulLCD::sizeHint() const
-{
- return QSize(
- font_width * COLS + frame_width * 2,
- font_height * ROWS + frame_width * 2);
-}
-
-
-void EmulLCD::drawContents(QPainter *p)
-{
- RedrawText(*p);
-}
-
-
-void EmulLCD::SetPainter(QPainter & p)
-{
- p.setBackgroundMode(OpaqueMode);
- p.setPen(fg_color);
- p.setBackgroundColor(bg_color);
-}
-
-
-void EmulLCD::RedrawText(QPainter & p)
-{
- int r, c;
-
- SetPainter(p);
-
- for (r = 0; r < ROWS; r++)
- for (c = 0; c < COLS; c++)
- PrintChar(p, r, c);
-}
-
-
-void EmulLCD::PrintChar(QPainter & p, int row, int col)
-{
- // Fetch char from DD RAM
- unsigned char c = ddram[row][col];
-
- // Map some Hitachi characters to ISO Latin1
- switch(c)
- {
- case 0xDF:
- c = 0xBA; // "degrees" glyph
- break;
-
- case 0xE4:
- c = 0xB5; // "micro" glyph
- break;
-
- default: // all others
- break;
- }
-
- // Draw char on display
- int x = col * font_width + frame_width;
- int y = row * font_height + frame_width;
- bool restore_colors = false;
-
- if (show_cursor && (row == cr_row) && (col == cr_col))
- {
- // Exchange FG/BG colors
- p.setPen(bg_color);
- p.setBackgroundColor(fg_color);
- restore_colors = true;
- }
-
- p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/,
- QString(QChar(c)), 1);
-
- if (restore_colors)
- {
- // Restore FG/BG colors
- p.setPen(fg_color);
- p.setBackgroundColor(bg_color);
- }
-}
-
-
-void EmulLCD::MoveCursor(int r, int c)
-{
- // Save old cursor position
- int old_row = cr_row;
- int old_col = cr_col;
-
- // Move the cursor
- cgramaddr = -1;
- cr_row = r;
- cr_col = c;
-
- if (show_cursor && (old_col != cr_col || old_row != cr_row))
- {
- QPainter p(this);
- SetPainter(p);
-
- // Draw new cursor
- PrintChar(p, cr_row, cr_col);
-
- // Erase old cursor
- PrintChar(p, old_row, old_col);
- }
-}
-
-
-void EmulLCD::ShowCursor(bool show)
-{
- show_cursor = show;
-
- // Draw (or erase) cursor
- QPainter p(this);
- SetPainter(p);
- PrintChar(p, cr_row, cr_col);
-}
-
-
-void EmulLCD::AdvanceCursor()
-{
- // Move the cursor
- if (cr_col == COLS - 1)
- {
- if (cr_row == ROWS - 1)
- MoveCursor(0, 0);
- else
- MoveCursor(cr_row + 1, 0);
- }
- else
- MoveCursor(cr_row, cr_col + 1);
-}
-
-
-void EmulLCD::PutChar(unsigned char c)
-{
- if (cgramaddr != -1)
- {
- // Write data in CGRAM
- cgram[cgramaddr] = c;
-
- // Auto increment CGRAM address
- cgramaddr = (cgramaddr + 1) & 0x3F;
- }
- else
- {
- // Writing in DDRAM
- ddram[cr_row][cr_col] = c;
-
- // Update display
- {
- QPainter p(this);
- SetPainter(p);
- PrintChar(p, cr_row, cr_col);
- }
- AdvanceCursor();
- }
-}
-
-
-char EmulLCD::GetChar()
-{
- char c = ddram[cr_row][cr_col];
- AdvanceCursor();
- return c;
-}
-
-
-void EmulLCD::Clear()
-{
- memset(ddram, ' ', sizeof(ddram));
- cr_row = cr_col = 0;
-
- QPainter p(this);
- RedrawText(p);
-}
-
-
-void EmulLCD::SetCGRamAddr(unsigned char addr)
-{
- cgramaddr = addr & (sizeof(cgram) - 1);
-}
-
-
-// Hitachi LM044L register-level emulation
-
-#define INI_DISPLAY 0x30
-#define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */
-#define ON_DISPLAY 0x0F /* Switch on display */
-#define OFF_DISPLAY 0x08 /* Switch off display */
-#define CLR_DISPLAY 0x01 /* Clear display */
-#define CURSOR_BLOCK 0x0D /* Show cursor (block) */
-#define CURSOR_LINE 0x0F /* Show cursor (line) */
-#define CURSOR_OFF 0x0C /* Hide cursor */
-#define MODE_DISPL 0x06
-#define SHIFT_DISPLAY 0x18
-#define MOVESHIFT_LEFT 0x00
-#define MOVESHIFT_RIGHT 0x04
-#define LCD_CGRAMADDR (1<<6)
-#define LCD_DDRAMADDR (1<<7)
-
-
-extern "C" void Emul_LCDWriteReg(unsigned char d)
-{
- static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 };
-
- switch(d)
- {
- case CLR_DISPLAY:
- emul->emulLCD->Clear();
- break;
-
- case CURSOR_BLOCK:
- case CURSOR_LINE:
- emul->emulLCD->ShowCursor(true);
- break;
-
- case CURSOR_OFF:
- emul->emulLCD->ShowCursor(false);
- break;
-
- default:
- // Set DDRAM address?
- if (d & LCD_DDRAMADDR)
- {
- for (int i = 0; i < EmulLCD::ROWS; i++)
- {
- if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS))
- {
- emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]);
- break;
- }
- }
- }
- else if (d & LCD_CGRAMADDR)
- emul->emulLCD->SetCGRamAddr(d);
- break;
- }
-}
-
-
-extern "C" unsigned char Emul_LCDReadReg(void)
-{
- return 0; /* This LCD model is never busy ;-) */
-}
-
-
-extern "C" void Emul_LCDWriteData(unsigned char d)
-{
- emul->emulLCD->PutChar(d);
-}
-
-
-extern "C" unsigned char Emul_LCDReadData(void)
-{
- return emul->emulLCD->GetChar();
-}
-
-#include "EmulLCD.moc"
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.1 2006/01/16 03:51:35 bernie
- *#* Add LCD Qt emulator.
- *#*
- *#*/
-
-#ifndef EMULLCD_H
-#define EMULLCD_H
-
-#include <qframe.h>
-#include <qfont.h>
-#include <qcolor.h>
-
-// fwd decls
-class QSizePolicy;
-class QPaintEvent;
-class QResizeEvent;
-
-/**
- * Qt widget to emulate a dot-matrix LCD display.
- */
-class EmulLCD : public QFrame
-{
- Q_OBJECT
-
-public:
-// Attributes
- enum { COLS = 20, ROWS = 4 };
-
-// Construction
- EmulLCD(QWidget *parent = 0, const char *name = 0);
- virtual ~EmulLCD();
-
-// Base class overrides
-protected:
- virtual QSizePolicy sizePolicy() const;
- virtual QSize sizeHint() const;
- virtual void drawContents(QPainter *p);
-
-// Operations
-public:
- void MoveCursor (int col, int row);
- void ShowCursor (bool show = true);
- void PutChar (unsigned char c);
- char GetChar ();
- void Clear ();
- void SetCGRamAddr (unsigned char addr);
-
-// Implementation
-protected:
- void SetPainter(QPainter & p);
- void RedrawText(QPainter & p);
- void PrintChar(QPainter & p, int row, int col);
- void AdvanceCursor();
-
- QFont lcd_font; ///< Display character font
- QColor fg_color, bg_color; ///< LCD colors
- int font_width, font_height; ///< Font dimensions
- int frame_width; ///< Frame width (and height)
- int cr_row, cr_col; ///< Cursor position
- int cgramaddr; ///< CGRAM Address (-1 disabled)
- unsigned char ddram[ROWS][COLS];///< Display data RAM
- unsigned char cgram[8*8]; ///< CGRAM
- bool show_cursor; ///< Cursor enabled?
-};
-
-#endif // !defined(EMULLCD_H)
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Generic text LCD driver (impl.).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/09/20 20:02:43 marco
- *#* Replaced ISLISTEMPTY with LIST_EMPTY
- *#*
- *#* Revision 1.3 2006/07/19 12:56:25 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.2 2006/02/24 00:27:14 bernie
- *#* Use new naming convention for list macros.
- *#*
- *#* Revision 1.1 2005/11/04 18:00:42 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.11 2005/06/14 14:43:43 bernie
- *#* Add DevLib headers.
- *#*
- *#* Revision 1.10 2005/06/06 17:41:57 batt
- *#* Add lcd_layerSet function.
- *#*
- *#* Revision 1.9 2005/06/01 16:40:07 batt
- *#* Remove debug string.
- *#*
- *#* Revision 1.8 2005/06/01 16:38:04 batt
- *#* Adapt to changes in mware/list.h.
- *#*
- *#* Revision 1.7 2005/06/01 10:45:22 batt
- *#* lcd_setAddr(): Bugfix boundary condition; Misc cleanup.
- *#*
- *#* Revision 1.6 2005/06/01 10:36:23 batt
- *#* Layer: Rename member variables and Doxygenize.
- *#*
- *#* Revision 1.5 2005/05/27 11:05:58 batt
- *#* Do not write on lcd if layer is hidden.
- *#*/
-
-#include "lcd_text.h"
-#include "lcd_hd44.h"
-#include <drv/timer.h> // timer_delay()
-#include <mware/formatwr.h> // _formatted_write()
-#include <mware/list.h> // LIST_EMPTY()
-#include <cfg/macros.h> // BV()
-#include <cfg/debug.h>
-
-#include <string.h> // strlen()
-
-
-/** Maximum number of layers. */
-#define LCD_LAYERS 6
-
-#if CONFIG_KERNEL
- /** Semaphore to arbitrate access to the display. */
- static struct Semaphore lcd_semaphore;
- #define LOCK_LCD sem_obtain(&lcd_semaphore)
- #define UNLOCK_LCD sem_release(&lcd_semaphore)
-#else /* !CONFIG_KERNEL */
- #define LOCK_LCD do {} while (0)
- #define UNLOCK_LCD do {} while (0)
-#endif /* !CONFIG_KERNEL */
-
-DECLARE_LIST_TYPE(Layer);
-
-Layer *lcd_DefLayer;
-static Layer lcd_LayersPool[LCD_LAYERS];
-static LIST_TYPE(Layer) lcd_Layers;
-static LIST_TYPE(Layer) lcd_FreeLayers;
-
-/**
- * Current cursor status.
- *
- * One of LCD_CMD_CURSOR_OFF, LCD_CMD_CURSOR_BLOCK or LCD_CMD_CURSOR_LINE.
- */
-static uint8_t lcd_CursorStatus;
-
-/** Current cursor position, encoded as a Cursor position and status. */
-static lcdpos_t lcd_CursorAddr;
-
-
-void lcd_setAddr(Layer *layer, lcdpos_t addr)
-{
- /* Sanity check: wrap around to display limits */
- while (addr >= LCD_ROWS * LCD_COLS)
- addr -= LCD_ROWS * LCD_COLS;
-
- layer->addr = addr;
-}
-
-#if CONFIG_KERNEL
-
-void lcd_lock(void)
-{
- LOCK_LCD;
-}
-
-
-void lcd_unlock(void)
-{
- UNLOCK_LCD;
-}
-
-#endif /* CONFIG_KERNEL */
-
-
-/**
- * Write one character to the display at the current
- * cursor prosition, then move the cursor right. The
- * cursor is wrapped to the next line when it moves
- * beyond the end of the current line.
- *
- * \note Does _NOT_ lock the display semaphore.
- */
-static void lcd_putCharUnlocked(char c, Layer *layer)
-{
- Layer *l2;
- lcdpos_t addr = layer->addr;
-
- /* Store character in layer buffer */
- layer->buf[addr] = c;
-
- /* Move to next character */
- if (++layer->addr >= LCD_COLS * LCD_ROWS)
- layer->addr = 0;
-
- /* Do not write on LCD if layer is hidden. */
- if (layer->pri == LAYER_HIDDEN)
- return;
-
- /*
- * Check if this location is obscured by
- * other layers above us.
- */
- for (l2 = layer->pred; l2->pred; l2 = l2->pred)
- {
- if (l2->buf[addr])
- {
- /* DB(kprintf("layer %04x obs %04x at %d\n", l2, layer, addr);) */
- return;
- }
- }
-
- /* Write character */
- if (c)
- lcd_putc(addr, c);
- else
- /* FIXME: should look for layers beneath! */
- lcd_putc(addr, ' ');
-}
-
-
-void lcd_putChar(char c, Layer *layer)
-{
- LOCK_LCD;
- lcd_putCharUnlocked(c, layer);
- UNLOCK_LCD;
-}
-
-void lcd_layerSet(Layer *layer, char c)
-{
- int i;
-
- LOCK_LCD;
- lcd_setAddr(layer, 0);
- for (i = 0; i < LCD_COLS * LCD_ROWS; i++)
- lcd_putCharUnlocked(c, layer);
- UNLOCK_LCD;
-}
-
-
-void lcd_clear(Layer *layer)
-{
- lcd_layerSet(layer, 0);
-}
-
-
-void lcd_clearLine(Layer *layer, int y)
-{
- int i;
-
- LOCK_LCD;
- lcd_setAddr(layer, LCD_POS(0, y));
- for (i = 0; i < LCD_COLS; i++)
- lcd_putCharUnlocked(0, layer);
- UNLOCK_LCD;
-}
-
-
-void lcd_moveCursor(lcdpos_t addr)
-{
- LOCK_LCD;
- lcd_moveTo(addr);
- UNLOCK_LCD;
-}
-
-
-char lcd_setCursor(char mode)
-{
- static const char cursor_cmd[3] =
- {
- LCD_CMD_CURSOR_OFF, LCD_CMD_CURSOR_BLOCK, LCD_CMD_CURSOR_LINE
- };
- char oldmode = lcd_CursorStatus;
-
- LOCK_LCD;
- lcd_CursorStatus = mode;
- lcd_setReg(cursor_cmd[(int)mode]);
- if (mode)
- lcd_moveCursor(lcd_CursorAddr);
- UNLOCK_LCD;
-
- return oldmode;
-}
-
-
-int lcd_vprintf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, va_list ap)
-{
- int len;
-
- LOCK_LCD;
-
- /*
- * Se il cursore era acceso, spegnilo durante
- * l'output per evitare che salti alla posizione
- * in cui si scrive.
- */
- if (lcd_CursorStatus)
- lcd_setReg(LCD_CMD_CURSOR_OFF);
-
- /* Spostamento del cursore */
- lcd_setAddr(layer, addr);
-
- if (mode & LCD_CENTER)
- {
- int pad;
-
- /*
- * NOTE: calculating the string lenght BEFORE it gets
- * printf()-formatted. Real lenght may differ.
- */
- pad = (LCD_COLS - strlen(format)) / 2;
- while (pad--)
- lcd_putCharUnlocked(' ', layer);
- }
-
- len = _formatted_write(format, (void (*)(char, void *))lcd_putCharUnlocked, layer, ap);
-
- if (mode & (LCD_FILL | LCD_CENTER))
- while (layer->addr % LCD_COLS)
- lcd_putCharUnlocked(' ', layer);
-
- /*
- * Riaccendi il cursore e riportalo alla
- * vecchia posizione
- */
- if (lcd_CursorStatus)
- lcd_setCursor(lcd_CursorStatus);
-
- UNLOCK_LCD;
-
- return len;
-}
-
-
-int lcd_printf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, ...)
-{
- int len;
- va_list ap;
-
- va_start(ap, format);
- len = lcd_vprintf(layer, addr, mode, format, ap);
- va_end(ap);
-
- return len;
-}
-
-
-/**
- * Internal function to move a layer between two positions.
- *
- * \note The layer must be *already* enqueued in some list.
- * \note The display must be already locked!
- */
-static void lcd_enqueueLayer(Layer *layer, char pri)
-{
- Layer *l2;
-
- /* Remove layer from whatever list it was in before */
- REMOVE(layer);
-
- layer->pri = pri;
-
- /*
- * Search for the first layer whose priority
- * is less or equal to the layer we are adding.
- */
- FOREACH_NODE(l2, &lcd_Layers)
- if (l2->pri <= pri)
- break;
-
- /* Enqueue layer */
- INSERT_BEFORE(layer, l2);
-}
-
-Layer *lcd_newLayer(char pri)
-{
- Layer *layer;
-
- LOCK_LCD;
-
- if (LIST_EMPTY(&lcd_FreeLayers))
- {
- UNLOCK_LCD;
- //ASSERT(false);
- return NULL;
- }
-
- layer = (Layer *)LIST_HEAD(&lcd_FreeLayers);
- layer->addr = 0;
- memset(layer->buf, 0, LCD_ROWS * LCD_COLS);
-
- lcd_enqueueLayer(layer, pri);
-
- UNLOCK_LCD;
- return layer;
-}
-
-/**
- * Redraw the display (internal).
- *
- * \note The display must be already locked.
- */
-static void lcd_refresh(void)
-{
- lcdpos_t addr;
- Layer *l;
-
- for (addr = 0; addr < LCD_ROWS * LCD_COLS; ++addr)
- {
- FOREACH_NODE(l, &lcd_Layers)
- {
- //kprintf("%d %x %p\n", addr, l->buf[0], l);
- if (l->pri == LAYER_HIDDEN)
- break;
-
- if (l->buf[addr])
- {
- /* Refresh location */
- lcd_putc(addr, l->buf[addr]);
- goto done;
- }
- }
-
- /* Draw background */
- lcd_putc(addr, ' ');
- done:
- ;
- }
-}
-
-/**
- * Rearrange layer depth and refresh display accordingly.
- *
- * \note Setting a priority of LAYER_HIDDEN makes the layer invisible.
- */
-void lcd_setLayerDepth(Layer *layer, char pri)
-{
- if (pri != layer->pri)
- {
- LOCK_LCD;
- lcd_enqueueLayer(layer, pri);
- /* Vile but simple */
- lcd_refresh();
- UNLOCK_LCD;
- }
-}
-
-void lcd_deleteLayer(Layer *layer)
-{
- LOCK_LCD;
-
-/* We use lcd_refresh() instead. Much simpler than this mess, but slower. */
-#if 0
- Layer *l2;
- lcdpos_t addr;
-
- /* Repair damage on underlaying layers */
- for (addr = 0; addr < LCD_ROWS * LCD_COLS; ++addr)
- {
- /* If location was covered by us */
- if (layer->buf[addr])
- {
- /* ...and it wasn't covered by others above us... */
- for (l2 = layer->pred; l2->pred; l2 = l2->pred)
- if (l2->buf[addr])
- /* can't just break here! */
- goto not_visible;
-
- /* ...scan underlaying layers to repair damage */
- for (l2 = layer->succ; l2->succ; l2 = l2->succ)
- if (l2->buf[addr])
- {
- /* Refresh character */
- lcd_putc(addr, l2->buf[addr]);
-
- /* No need to search on deeper layers */
- break;
- }
-
- not_visible:
- ;
- }
- }
-#endif
-
- // Remove layer from lcd_Layers list.
- REMOVE(layer);
-
- /* Put layer back into free list */
- ADDHEAD(&lcd_FreeLayers, layer);
-
- lcd_refresh();
-
- UNLOCK_LCD;
-}
-
-
-static void lcd_setDefLayer(Layer *layer)
-{
- lcd_DefLayer = layer;
-}
-
-#include <cfg/debug.h>
-void lcd_init(void)
-{
- int i;
-
- LIST_INIT(&lcd_Layers);
- LIST_INIT(&lcd_FreeLayers);
- for (i = 0; i < LCD_LAYERS; ++i)
- ADDHEAD(&lcd_FreeLayers, &lcd_LayersPool[i]);
-
- lcd_setDefLayer(lcd_newLayer(0));
-
- lcd_hw_init();
-
- lcd_setCursor(0);
-}
-
-#if CONFIG_TEST
-void lcd_test(void)
-{
- int i;
-
- for (i = 0; i < LCD_ROWS * LCD_COLS; ++i)
- {
- lcd_putCharUnlocked('0' + (i % 10), lcd_DefLayer);
- timer_delay(100);
- }
-}
-#endif /* CONFIG_TEST */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Generic text LCD driver (interface).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.3 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.2 2006/02/23 10:59:14 bernie
- *#* Documentation fixes.
- *#*
- *#* Revision 1.1 2005/11/04 18:00:42 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.5 2005/06/14 14:43:43 bernie
- *#* Add DevLib headers.
- *#*
- *#* Revision 1.4 2005/06/06 17:41:57 batt
- *#* Add lcd_layerSet function.
- *#*
- *#* Revision 1.3 2005/06/01 10:36:23 batt
- *#* Layer: Rename member variables and Doxygenize.
- *#*
- *#* Revision 1.2 2005/05/26 08:31:23 batt
- *#* Add layer hiding/showing.
- *#*
- *#* Revision 1.1 2005/05/24 09:17:58 batt
- *#* Move drivers to top-level.
- *#*/
-
-#ifndef DRV_LCD_H
-#define DRV_LCD_H
-
-#include "lcd_hd44.h"
-
-#include <cfg/macros.h>
-#include <cfg/compiler.h>
-#include <mware/list.h>
-
-#include <stdarg.h> // vprintf()
-
-
-/* flags for lcd_printf() */
-#define LCD_NORMAL 0 /* Scrittura normale */
-#define LCD_FILL BV(0) /* Fill rest of line with spaces */
-#define LCD_CENTER BV(1) /* Center string in line */
-#define LCD_NOCURSOR BV(2) /* Scrittura senza spostamento cursore */
-
-/** Special priority value for lcd_setLayerDepth(). */
-#define LAYER_HIDDEN -128
-
-/* Compute LCD address from x/y coordinates */
-#define LCD_POS(x,y) ((lcdpos_t)((uint8_t)(x) + (uint8_t)(y) * (uint8_t)LCD_COLS))
-#define LCD_ROW0 (LCD_COLS * 0)
-#define LCD_ROW1 (LCD_COLS * 1)
-#define LCD_ROW2 (LCD_COLS * 2)
-#define LCD_ROW3 (LCD_COLS * 3)
-
-/**
- * Overwrapping layer context.
- */
-typedef struct _Layer
-{
- /**
- * Active layers are linked together in a list
- * sorted in top to bottom order.
- */
- DECLARE_NODE_ANON(struct _Layer)
-
- /** Current XY address into this layer, for write operations. */
- lcdpos_t addr;
-
- /** Priority of this layer (greater in front of lesser). */
- char pri;
-
- /**
- * Layer backing store buffer.
- *
- * All writes through the layer are copied into this buffer.
- * Characters cells with value 0 are transparent with respect
- * to other layers in the background.
- */
- char buf[LCD_COLS * LCD_ROWS];
-} Layer;
-
-
-/* Global variables */
-extern Layer *lcd_DefLayer;
-
-/* Function prototypes */
-extern void lcd_init(void);
-extern void lcd_test(void);
-
-extern void lcd_moveCursor(lcdpos_t addr);
-extern char lcd_setCursor(char state);
-
-extern void lcd_setAddr(Layer *layer, lcdpos_t addr);
-extern void lcd_putChar(char c, Layer *layer);
-extern int lcd_vprintf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, va_list ap) FORMAT(printf, 4, 0);
-extern int lcd_printf(Layer *layer, lcdpos_t addr, uint8_t mode, const char *format, ...) FORMAT(printf, 4, 5);
-extern void lcd_clear(Layer *layer);
-extern void lcd_layerSet(Layer *layer, char c);
-extern void lcd_clearLine(Layer *layer, int y);
-
-extern void lcd_setLayerDepth(Layer *layer, char pri);
-extern Layer *lcd_newLayer(char pri);
-extern void lcd_deleteLayer(Layer *layer);
-extern void lcd_lock(void);
-extern void lcd_unlock(void);
-
-#endif /* DRV_LCD_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief MCP41xxx digital potentiomenter driver (implementation)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#include <drv/timer.h>
-
-#include <cfg/macros.h>
-#include <cfg/compiler.h>
-
-#include <hw_mcp41.h>
-#include <drv/mcp41.h>
-#include <drv/ser.h>
-
-static Serial *spi_ser;
-
-/**
- * Set resitance for digital pot \a dev
- */
-void mcp41_setResistance(Mcp41Dev dev, mcp41_res_t res)
-{
- MCP41_ON(dev);
- /* send command byte */
- ser_putchar(MCP41_WRITE_DATA, spi_ser);
- ser_putchar(((MCP41_HW_MAX * (uint32_t)res) + (MCP41_MAX / 2)) / MCP41_MAX, spi_ser);
- ser_drain(spi_ser);
-
- MCP41_OFF(dev);
-}
-
-
-/**
- * Initialize mcp41 potentiometer driver
- */
-void mcp41_init(Serial *spi_port)
-{
- Mcp41Dev dev;
-
- /* Init all potentiometer ports */
- for (dev = 0; dev < MCP41_CNT; dev++)
- {
- SET_MCP41_DDR(dev);
- MCP41_OFF(dev);
- }
-
- spi_ser = spi_port;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief MCP41xxx digital potentiomenter driver (interface)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#ifndef DRV_MCP41_H
-#define DRV_MCP41_H
-
-#include <hw/mcp41_map.h>
-#include <cfg/compiler.h>
-#include <drv/ser.h>
-
-#define MCP41_WRITE_DATA 0x11
-#define MCP41_HW_MAX 255
-#define MCP41_MAX 999
-
-/**
- * Type for digital potentiometer resistance.
- */
-typedef uint16_t mcp41_res_t;
-
-void mcp41_setResistance(Mcp41Dev dev, mcp41_res_t res);
-void mcp41_init(Serial *spi_port);
-
-#endif /* DRV_MCP41_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005 Develer S.r.l. (http://www.de+veler.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Driver for NTC (reads a temperature through an ADC)
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- *
- *
- * This module handles an external NTC bound to an AD converter. As usual,
- * it relies on a low-level API (ntc_hw_*) (see below):
- *
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 17:59:47 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.1 2005/05/24 09:17:58 batt
- *#* Move drivers to top-level.
- *#*/
-
-#include <drv/ntc.h>
-#include <hw_ntc.h>
-#include <ntc_map.h>
-
-#include <cfg/debug.h>
-
-DB(bool ntc_initialized;)
-
-/**
- * Find in a table of values \a orig_table of size \a size, the index which
- * value is less or equal to \a val.
- *
- * \retval 0 When \a val is higher than the first table entry.
- * \retval size When \a val is lower than the last table entry.
- * \retval 1..size-1 When \a val is within the table.
- */
-static size_t upper_bound(const res_t *orig_table, size_t size, res_t val)
-{
- const res_t *table = orig_table;
-
- while (size)
- {
- size_t pos = size / 2;
- if (val > table[pos])
- size = pos;
- else
- {
- table += pos+1;
- size -= pos+1;
- }
- }
-
- return table - orig_table;
-}
-
-
-/**
- * Read the temperature for the NTC channel \a dev.
- * First read the resistence of the NTC through ntc_hw_read(), then,
- * for the conversion from resistance to temperature, since the formula
- * varies from device to device, we implemented a generic system using
- * a table of data which maps temperature (index) to resistance (data).
- * The range of the table (min/max temperature) and the step
- * (temperature difference between two consecutive elements of the table)
- * is variable and can be specified. Notice that values inbetween the
- * table elements are still possible as the library does a linear
- * interpolation using the actual calculated resistance to find out
- * the exact temperature.
- *
- * The low-level API provides a function to get access to a description
- * of the NTC (ntc_hw_getInfo()), including the resistance table.
- *
- */
-deg_t ntc_read(NtcDev dev)
-{
- const NtcHwInfo* hw = ntc_hw_getInfo(dev);
- const res_t* r = hw->resistances;
-
- float rx;
- size_t i;
- deg_t degrees;
-
- rx = ntc_hw_read(dev);
-
-
- i = upper_bound(r, hw->num_resistances, rx);
- ASSERT(i <= hw->num_resistances);
-
- if (i >= hw->num_resistances)
- return NTC_SHORT_CIRCUIT;
- else if (i == 0)
- return NTC_OPEN_CIRCUIT;
-
- /*
- * Interpolated value in 0.1 degrees multiplied by 10:
- * delta t step t
- * ---------- = ----------------
- * (rx - r[i]) (r[i-1] - r [i])
- */
- float tmp;
- tmp = 10 * hw->degrees_step * (rx - r[i]) / (r[i - 1] - r[i]);
-
- /*
- * degrees = integer part corresponding to the superior index
- * in the table multiplied by 10
- * - decimal part interpolated (already multiplied by 10)
- */
- degrees = (i * hw->degrees_step + hw->degrees_min) * 10 - (int)(tmp);
-
- //kprintf("dev= %d, I=%d, degrees = %d\n", dev, i , degrees);
-
- return degrees;
-}
-
-
-/**
- * Init NTC hardware.
- */
-void ntc_init(void)
-{
- NTC_HW_INIT;
- DB(ntc_initialized = true;)
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Driver for NTC (reads a temperature through an ADC)
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 17:59:47 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.3 2005/06/10 08:56:47 batt
- *#* Avoid calling DEG_T_TO_DEG().
- *#*
- *#* Revision 1.2 2005/06/10 08:54:58 batt
- *#* Rename deg_t conversion macros to accomplish coding standard.
- *#*
- *#* Revision 1.1 2005/05/24 09:17:58 batt
- *#* Move drivers to top-level.
- *#*/
-
-#ifndef DRV_NTC_H
-#define DRV_NTC_H
-
-#include <ntc_map.h>
-#include <cfg/debug.h>
-#include <cfg/compiler.h>
-
-#define NTC_OPEN_CIRCUIT -32768
-#define NTC_SHORT_CIRCUIT 32767
-
-typedef int16_t deg_t; /** type for celsius degrees deg_t = °C * 10 */
-
-/** Macro for converting from deg to deg_t type */
-#define DEG_TO_DEG_T(x) ((deg_t)((x) * 10))
-
-/** Macro for converting from deg_t to celsius degrees (returns only the integer part) */
-#define DEG_T_TO_INTDEG(x) ((x) / 10)
-
-/** Macro for converting from deg_t to celsius degrees (returns only the decimal part) */
-#define DEG_T_TO_DECIMALDEG(x) ((x) % 10)
-
-/** Macro for converting from deg_t to celsius degrees (returns type is float) */
-#define DEG_T_TO_FLOATDEG(x) ((x) / 10.0)
-
-
-typedef uint32_t res_t; /** type for resistor res_t = Ohm * 100 */
-typedef float amp_t; /** type for defining amplifications amp_t = A, where A is a pure number */
-
-DB(extern bool ntc_initialized;)
-
-
-/** Describe a NTC chip */
-typedef struct NtcHwInfo
-{
- const res_t *resistances; ///< resistances of the NTC (ohms * 100)
- size_t num_resistances; ///< number of resistances
- deg_t degrees_min; ///< degrees corresponding to the first entry in the table (celsius * 10)
- deg_t degrees_step; ///< difference in degrees between two consecutive elements in the table (celsius * 10)
-} NtcHwInfo;
-
-/** Initialize the NTC module */
-void ntc_init(void);
-
-/** Read a single temperature value from the NTC */
-deg_t ntc_read(NtcDev dev);
-
-#endif /* DRV_NTC_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Phase control driver (implementation)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#include <drv/timer.h>
-
-
-#include <cfg/macros.h>
-#include <cpu/irq.h>
-#include <cpu/types.h>
-#include <cfg/compiler.h>
-
-
-#include <hw_phase.h>
-#include <drv/phase.h>
-
-#include <math.h>
-
-/** Array of triacs */
-static Triac triacs[TRIAC_CNT];
-
-DB(bool phase_initialized;)
-
-/**
- * Zerocross interrupt, call when 220V cross zero.
- *
- * This function turn off all triacs that have duty < 100%
- * and arm the triac timers for phase control.
- * This function is frequency adaptive so can work both at 50 or 60Hz.
- */
-DEFINE_ZEROCROSS_ISR()
-{
- ticks_t period, now;
- static ticks_t prev_time;
- TriacDev dev;
-
- now = timer_clock_unlocked();
- period = now - prev_time;
-
- for (dev = 0; dev < TRIAC_CNT; dev++)
- {
- /* Only turn off triac if duty is != 100% */
- if (triacs[dev].duty != TRIAC_MAX_DUTY)
- TRIAC_OFF(dev);
- /* Compute delay from duty */
- timer_setDelay(&triacs[dev].timer, DIV_ROUND(period * (TRIAC_MAX_DUTY - triacs[dev].duty), TRIAC_MAX_DUTY));
-
- /* This check avoids inserting the same timer twice
- * in case of an intempestive zerocross or spike */
- if (triacs[dev].running)
- {
- timer_abort(&triacs[dev].timer);
- //kprintf("[%lu]\n", timer_clock());
- }
-
- triacs[dev].running = true;
- timer_add(&triacs[dev].timer);
- }
- prev_time = now;
-}
-
-
-
-/**
- * Set duty of the triac channel \a dev (interrupt safe).
- */
-void phase_setDuty(TriacDev dev, triac_duty_t duty)
-{
- cpuflags_t flags;
- IRQ_SAVE_DISABLE(flags);
-
- phase_setDutyUnlock(dev,duty);
-
- IRQ_RESTORE(flags);
-}
-
-
-
-/**
- * Set duty of the triac channel \a dev (NOT INTERRUPT SAFE).
- */
-void phase_setDutyUnlock(TriacDev dev, triac_duty_t duty)
-{
- triacs[dev].duty = MIN(duty, (triac_duty_t)TRIAC_MAX_DUTY);
-}
-
-
-
-/**
- * Set power of the triac channel \a dev (interrupt safe).
- *
- * This function approsimate the sine wave to a triangular wave to compute
- * RMS power.
- */
-void phase_setPower(TriacDev dev, triac_power_t power)
-{
- bool greater_fifty = false;
- triac_duty_t duty;
-
- power = MIN(power, (triac_power_t)TRIAC_MAX_POWER);
-
- if (power > TRIAC_MAX_POWER / 2)
- {
- greater_fifty = true;
- power = TRIAC_MAX_POWER - power;
- }
-
- duty = TRIAC_POWER_K * sqrt(power);
-
- if (greater_fifty)
- duty = TRIAC_MAX_DUTY - duty;
- phase_setDuty(dev, duty);
-}
-
-
-
-/**
- * Soft int for each \a _dev triac.
- *
- * The triacs are turned on at different time to achieve phase control.
- */
-static void phase_softint(void *_dev)
-{
- TriacDev dev = (TriacDev)_dev;
-
- /* Only turn on if duty is !=0 */
- if (triacs[dev].duty)
- TRIAC_ON(dev);
- triacs[dev].running = false;
-}
-
-
-
-/**
- * Initialize phase control driver
- */
-void phase_init(void)
-{
- cpuflags_t flags;
- TriacDev dev;
-
- /* Init timers and ensure that all triac are off */
- for (dev = 0; dev < TRIAC_CNT; dev++)
- {
- triacs[dev].duty = 0;
- triacs[dev].running = false;
- SET_TRIAC_DDR(dev);
- TRIAC_OFF(dev);
- timer_set_event_softint(&triacs[dev].timer, (Hook)phase_softint, (void *)dev);
- }
- IRQ_SAVE_DISABLE(flags);
-
- /* Init zero cross interrupt */
- PHASE_HW_INIT;
- DB(phase_initialized = true;)
- IRQ_RESTORE(flags);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Phase control driver (interface)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:06:44 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.1 2005/05/24 09:17:58 batt
- *#* Move drivers to top-level.
- *#*
- *#* Revision 1.9 2005/05/09 16:34:14 batt
- *#* Change some function names to accomplish coding standard; Add debug phase_initialized; Change duty_t and power_t to uint16_t.
- *#*
- *#* Revision 1.8 2005/05/02 12:37:33 batt
- *#* Split hw triac map in phase_map.h.
- *#*
- *#* Revision 1.7 2005/05/02 09:05:03 batt
- *#* Rename duty_t and power_t in triac_duty_t and triac_power_t
- *#*
- *#* Revision 1.6 2005/04/28 15:10:11 batt
- *#* Use timer API to add and set events.
- *#*
- *#* Revision 1.5 2005/04/28 12:04:46 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.4 2005/04/28 10:35:45 batt
- *#* Complete phase_setpower.
- *#*
- *#* Revision 1.3 2005/04/27 19:23:40 batt
- *#* Reformat.
- *#*
- *#* Revision 1.1 2005/04/27 17:13:56 batt
- *#* Add triac phase control driver.
- *#*
- *#*/
-
-
-#ifndef DRV_PHASE_H
-#define DRV_PHASE_H
-
-#include <drv/timer.h>
-#include <phase_map.h>
-#include <cfg/debug.h>
-
-#define TRIAC_MAX_DUTY 100
-#define TRIAC_MAX_POWER 100
-#define TRIAC_POWER_K TRIAC_MAX_DUTY * (1 / sqrt(2 * TRIAC_MAX_POWER))
-
-/**
- * \name Types for duty and power.
- * \{
- */
-typedef uint16_t triac_duty_t;
-typedef uint16_t triac_power_t;
-/* \} */
-
-
-DB(extern bool phase_initialized;)
-
-/**
- * \name Type for triac control.
- * \{
- */
-typedef struct Triac
-{
- Timer timer; /**< Timer for phase control. */
- triac_duty_t duty; /**< Duty cycle of the channel. */
- bool running; /**< True when the timer is active. */
-} Triac;
-/* \} */
-
-void phase_setDutyUnlock(TriacDev dev, triac_duty_t duty);
-void phase_setDuty(TriacDev dev, triac_duty_t duty);
-void phase_setPower(TriacDev dev, triac_power_t power);
-
-void phase_init(void);
-
-
-#endif /* DRV_PHASE_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- *
- * \brief PWM driver (implementation)
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- */
-
-#include <cpu/types.h>
-#include <cpu/irq.h>
-
-#include <drv/pwm.h>
-#include <drv/pwm_at91.h>
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-
-/**
- * Set duty of pwm channel \p dev.
- */
-void pwm_setDuty(PwmDev dev, pwm_duty_t duty)
-{
- pwm_period_t period = 0;
- pwm_duty_t real_duty = 0;
-
- duty = MIN(duty, (pwm_duty_t)PWM_MAX_DUTY);
-
- period = pwm_hw_getPeriod(dev);
-
- real_duty = (uint64_t)(duty * period) >> (uint64_t)PWM_MAX_PERIOD_LOG2;
-
-// kprintf("real_duty[%d] duty[%d], period[%d]\n", real_duty, duty, period);
- pwm_hw_setDutyUnlock(dev, real_duty);
-}
-
-/**
- * Set frequency of pwm channel \p dev at \p freq in Hz.
- */
-void pwm_setFrequency(PwmDev dev, pwm_freq_t freq)
-{
- pwm_hw_setFrequency(dev, freq);
-}
-
-/**
- * Set duty of pwm channel \p dev.
- */
-void pwm_enable(PwmDev dev, bool state)
-{
- if (state)
- pwm_hw_enable(dev);
- else
- pwm_hw_disable(dev);
-}
-
-/**
- * Initialize PWM hw.
- */
-void pwm_init(void)
-{
- cpuflags_t flags;
- PwmDev dev;
-
- IRQ_SAVE_DISABLE(flags);
-
- /* set all pwm to 0 */
- for (dev = 0; dev < PWM_CNT; dev++)
- pwm_setDuty(dev, 0);
-
- pwm_hw_init();
-
- IRQ_RESTORE(flags);
-}
-
-
-
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief PWM driver (interface)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#ifndef DRV_PWM_H
-#define DRV_PWM_H
-
-#include <pwm_map.h>
-#include <cfg/compiler.h>
-
-typedef uint16_t pwm_duty_t;
-
-void pwm_setDuty(PwmDev dev, pwm_duty_t duty);
-void pwm_init(void);
-
-#define PWM_MAX_DUTY 100
-
-#endif /* DRV_PWM_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- *
- * \brief Test for PWM driver (implementation)
- *
- * \version $Id$
- *
- * \author Daniele Basile <asterix@develer.com>
- */
-
-#include <cpu/types.h>
-#include <cpu/irq.h>
-
-#include <drv/pwm.h>
-#include <drv/pwm_at91.h>
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-/*
- * Esample of value for duty cycle"
- *
- * - 100% => 0xFFFFFFFF
- * - 80% => 0xCCCCCCCC
- * - 75% => 0xBFFFFFFF
- * - 50% => 0x7FFFFFFF
- * - 25% => 0x3FFFFFFF
- * - 33% => 0x55555555
- * - 16% => 0x2AAAAAAA
- */
-
-#define PWM_TEST_CH0 0
-#define PWM_TEST_CH0_FREQ 100UL // 100Hz
-#define PWM_TEST_CH0_DUTY 0xCCCC // 80%
-
-#define PWM_TEST_CH1 1
-#define PWM_TEST_CH1_FREQ 1000UL // 1000Hz
-#define PWM_TEST_CH1_DUTY 0xBFFF // 75%
-
-#define PWM_TEST_CH2 2
-#define PWM_TEST_CH2_FREQ 12356 // 12356Hz
-#define PWM_TEST_CH2_DUTY 0x7FFF // 50%
-
-#define PWM_TEST_CH3 3
-#define PWM_TEST_CH3_FREQ 100000UL // 100KHz
-#define PWM_TEST_CH3_DUTY 0x5555 // 33%
-
-#define PWM_TEST_CH_SET(index) \
- do { \
- pwm_setFrequency(PWM_TEST_CH##index , PWM_TEST_CH##index##_FREQ); \
- pwm_setDuty(PWM_TEST_CH##index, PWM_TEST_CH##index##_DUTY); \
- pwm_enable(PWM_TEST_CH##index, true); \
- } while (0)
-
-/**
- * Test suit for genation of pwm waveform.
- *
- */
-void pwm_test(void)
-{
-
- pwm_init();
- kputs("Init pwm..\n");
-
- PWM_TEST_CH_SET(0);
- kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH0, PWM_TEST_CH0_FREQ, PWM_TEST_CH0_DUTY);
- PWM_TEST_CH_SET(1);
- kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH1, PWM_TEST_CH1_FREQ, PWM_TEST_CH1_DUTY);
- PWM_TEST_CH_SET(2);
- kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH2, PWM_TEST_CH2_FREQ, PWM_TEST_CH2_DUTY);
- PWM_TEST_CH_SET(3);
- kprintf("Set pwm ch[%d] =>freq[%ld], duty[%d]\n", PWM_TEST_CH3, PWM_TEST_CH3_FREQ, PWM_TEST_CH3_DUTY);
-}
-
-
-
-
-
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \brief Buffered serial I/O driver
- *
- * The serial rx interrupt buffers incoming data in a software FIFO
- * to decouple the higher level protocols from the line speed.
- * Outgoing data is buffered as well for better performance.
- * This driver is not optimized for best performance, but it
- * has proved to be fast enough to handle transfer rates up to
- * 38400bps on a 16MHz 80196.
- *
- * MODULE CONFIGURATION
- *
- * \li \c CONFIG_SER_HWHANDSHAKE - set to 1 to enable RTS/CTS handshake.
- * Support is incomplete/untested.
- * \li \c CONFIG_SER_TXTIMEOUT - Enable software serial transmission timeouts
- *
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "ser.h"
-#include "wdt.h"
-#include "ser_p.h"
-#include <mware/formatwr.h>
-#include <cfg/debug.h>
-#include <appconfig.h>
-
-#include <string.h> /* memset */
-
-/*
- * Sanity check for config parameters required by this module.
- */
-#if !defined(CONFIG_KERNEL) || ((CONFIG_KERNEL != 0) && CONFIG_KERNEL != 1)
- #error CONFIG_KERNEL must be set to either 0 or 1 in config.h
-#endif
-#if !defined(CONFIG_SER_RXTIMEOUT)
- #error CONFIG_SER_TXTIMEOUT missing in config.h
-#endif
-#if !defined(CONFIG_SER_RXTIMEOUT)
- #error CONFIG_SER_RXTIMEOUT missing in config.h
-#endif
-#if !defined(CONFIG_SER_DEFBAUDRATE)
- #error CONFIG_SER_DEFBAUDRATE missing in config.h
-#endif
-
-#if CONFIG_KERNEL
- #include <kern/proc.h>
-#endif
-
-#if CONFIG_SER_TXTIMEOUT != -1 || CONFIG_SER_RXTIMEOUT != -1
- #include <drv/timer.h>
-#endif
-
-
-struct Serial ser_handles[SER_CNT];
-
-/**
- * Insert \a c in tx FIFO buffer.
- * \note This function will switch out the calling process
- * if the tx buffer is full. If the buffer is full
- * and \a port->txtimeout is 0 return EOF immediatly.
- *
- * \return EOF on error or timeout, \a c otherwise.
- */
-static int ser_putchar(int c, struct Serial *port)
-{
- if (fifo_isfull_locked(&port->txfifo))
- {
-#if CONFIG_SER_TXTIMEOUT != -1
- /* If timeout == 0 we don't want to wait */
- if (port->txtimeout == 0)
- return EOF;
-
- ticks_t start_time = timer_clock();
-#endif
-
- /* Wait while buffer is full... */
- do
- {
- wdt_reset();
-#if CONFIG_KERNEL && CONFIG_KERN_SCHED
- /* Give up timeslice to other processes. */
- proc_switch();
-#endif
-#if CONFIG_SER_TXTIMEOUT != -1
- if (timer_clock() - start_time >= port->txtimeout)
- {
- ATOMIC(port->status |= SERRF_TXTIMEOUT);
- return EOF;
- }
-#endif /* CONFIG_SER_TXTIMEOUT */
- }
- while (fifo_isfull_locked(&port->txfifo));
- }
-
- fifo_push_locked(&port->txfifo, (unsigned char)c);
-
- /* (re)trigger tx interrupt */
- port->hw->table->txStart(port->hw);
-
- /* Avoid returning signed extended char */
- return (int)((unsigned char)c);
-}
-
-
-/**
- * Fetch a character from the rx FIFO buffer.
- * \note This function will switch out the calling process
- * if the rx buffer is empty. If the buffer is empty
- * and \a port->rxtimeout is 0 return EOF immediatly.
- *
- * \return EOF on error or timeout, \a c otherwise.
- */
-static int ser_getchar(struct Serial *port)
-{
- if (fifo_isempty_locked(&port->rxfifo))
- {
-#if CONFIG_SER_RXTIMEOUT != -1
- /* If timeout == 0 we don't want to wait for chars */
- if (port->rxtimeout == 0)
- return EOF;
-
- ticks_t start_time = timer_clock();
-#endif
- /* Wait while buffer is empty */
- do
- {
- wdt_reset();
-#if CONFIG_KERNEL && CONFIG_KERN_SCHED
- /* Give up timeslice to other processes. */
- proc_switch();
-#endif
-#if CONFIG_SER_RXTIMEOUT != -1
- if (timer_clock() - start_time >= port->rxtimeout)
- {
- ATOMIC(port->status |= SERRF_RXTIMEOUT);
- return EOF;
- }
-#endif /* CONFIG_SER_RXTIMEOUT */
- }
- while (fifo_isempty_locked(&port->rxfifo) && (ser_getstatus(port) & SERRF_RX) == 0);
- }
-
- /*
- * Get a byte from the FIFO (avoiding sign-extension),
- * re-enable RTS, then return result.
- */
- if (ser_getstatus(port) & SERRF_RX)
- return EOF;
- return (int)(unsigned char)fifo_pop_locked(&port->rxfifo);
-}
-
-/**
- * Fetch a character from the rx FIFO buffer.
- * If the buffer is empty, ser_getchar_nowait() returns
- * EOF immediatly.
- * \note Deprecated, use ser_getchar with rx_timeout set to 0.
- */
-int ser_getchar_nowait(struct KFileSerial *fd)
-{
- if (fifo_isempty_locked(&fd->ser->rxfifo))
- return EOF;
-
- /* NOTE: the double cast prevents unwanted sign extension */
- return (int)(unsigned char)fifo_pop_locked(&fd->ser->rxfifo);
-}
-
-
-
-/**
- * Read at most \a size bytes from \a port and put them in \a buf
- *
- * \return number of bytes actually read.
- */
-static size_t ser_read(struct KFile *fd, void *_buf, size_t size)
-{
- KFileSerial *fds = KFILESERIAL(fd);
-
- size_t i = 0;
- char *buf = (char *)_buf;
- int c;
-
- while (i < size)
- {
- if ((c = ser_getchar(fds->ser)) == EOF)
- break;
- buf[i++] = c;
- }
-
- return i;
-}
-
-/**
- * \brief Write a buffer to serial.
- *
- * \return 0 if OK, EOF in case of error.
- *
- * \todo Optimize with fifo_pushblock()
- */
-static size_t ser_write(struct KFile *fd, const void *_buf, size_t size)
-{
- KFileSerial *fds = KFILESERIAL(fd);
- const char *buf = (const char *)_buf;
- size_t i = 0;
-
- while (size--)
- {
- if (ser_putchar(*buf++, fds->ser) == EOF)
- break;
- i++;
- }
- return i;
-}
-
-
-#if CONFIG_SER_RXTIMEOUT != -1 || CONFIG_SER_TXTIMEOUT != -1
-void ser_settimeouts(struct KFileSerial *fd, mtime_t rxtimeout, mtime_t txtimeout)
-{
- fd->ser->rxtimeout = ms_to_ticks(rxtimeout);
- fd->ser->txtimeout = ms_to_ticks(txtimeout);
-}
-#endif /* CONFIG_SER_RXTIMEOUT || CONFIG_SER_TXTIMEOUT */
-
-#if CONFIG_SER_RXTIMEOUT != -1
-/**
- * Discard input to resynchronize with remote end.
- *
- * Discard incoming data until the port stops receiving
- * characters for at least \a delay milliseconds.
- *
- * \note Serial errors are reset before and after executing the purge.
- */
-void ser_resync(struct KFileSerial *fd, mtime_t delay)
-{
- mtime_t old_rxtimeout = ticks_to_ms(fd->ser->rxtimeout);
-
- ser_settimeouts(fd, delay, ticks_to_ms(fd->ser->txtimeout));
- do
- {
- ser_setstatus(fd->ser, 0);
- ser_getchar(fd->ser);
- }
- while (!(ser_getstatus(fd->ser) & SERRF_RXTIMEOUT));
-
- /* Restore port to an usable status */
- ser_setstatus(fd->ser, 0);
- ser_settimeouts(fd, old_rxtimeout, ticks_to_ms(fd->ser->txtimeout));
-}
-#endif /* CONFIG_SER_RXTIMEOUT */
-
-
-void ser_setbaudrate(struct KFileSerial *fd, unsigned long rate)
-{
- fd->ser->hw->table->setBaudrate(fd->ser->hw, rate);
-}
-
-
-void ser_setparity(struct KFileSerial *fd, int parity)
-{
- fd->ser->hw->table->setParity(fd->ser->hw, parity);
-}
-
-static int ser_error(struct KFile *fd)
-{
- KFileSerial *fds = KFILESERIAL(fd);
- return ser_getstatus(fds->ser);
-}
-
-static void ser_clearerr(struct KFile *fd)
-{
- KFileSerial *fds = KFILESERIAL(fd);
- ser_setstatus(fds->ser, 0);
-}
-
-
-
-/**
- * Flush both the RX and TX buffers.
- */
-void ser_purge(struct KFileSerial *fd)
-{
- ser_purgeRx(fd);
- ser_purgeTx(fd);
-}
-
-/**
- * Flush RX buffer.
- */
-void ser_purgeRx(struct KFileSerial *fd)
-{
- fifo_flush_locked(&fd->ser->rxfifo);
-}
-
-/**
- * Flush TX buffer.
- */
-void ser_purgeTx(struct KFileSerial *fd)
-{
- fifo_flush_locked(&fd->ser->txfifo);
-}
-
-
-/**
- * Wait until all pending output is completely
- * transmitted to the other end.
- *
- * \note The current implementation only checks the
- * software transmission queue. Any hardware
- * FIFOs are ignored.
- */
-static int ser_flush(struct KFile *fd)
-{
- KFileSerial *fds = KFILESERIAL(fd);
-
- /*
- * Wait until the FIFO becomes empty, and then until the byte currently in
- * the hardware register gets shifted out.
- */
- while (!fifo_isempty(&fds->ser->txfifo)
- || fds->ser->hw->table->txSending(fds->ser->hw))
- {
- #if CONFIG_KERNEL && CONFIG_KERN_SCHED
- /* Give up timeslice to other processes. */
- proc_switch();
- #endif
- wdt_reset();
- }
- return 0;
-}
-
-
-/**
- * Initialize a serial port.
- *
- * \param fd KFile Serial struct interface.
- * \param unit Serial unit to open. Possible values are architecture dependant.
- */
-static struct Serial *ser_open(struct KFileSerial *fd, unsigned int unit)
-{
- struct Serial *port;
-
- ASSERT(unit < countof(ser_handles));
- port = &ser_handles[unit];
-
- ASSERT(!port->is_open);
- DB(port->is_open = true);
-
- port->unit = unit;
-
- port->hw = ser_hw_getdesc(unit);
-
- /* Initialize circular buffers */
- ASSERT(port->hw->txbuffer);
- ASSERT(port->hw->rxbuffer);
- fifo_init(&port->txfifo, port->hw->txbuffer, port->hw->txbuffer_size);
- fifo_init(&port->rxfifo, port->hw->rxbuffer, port->hw->rxbuffer_size);
-
- port->hw->table->init(port->hw, port);
-
- fd->ser = port;
- /* Set default values */
-#if CONFIG_SER_RXTIMEOUT != -1 || CONFIG_SER_TXTIMEOUT != -1
- ser_settimeouts(fd, CONFIG_SER_RXTIMEOUT, CONFIG_SER_TXTIMEOUT);
-#endif
-#if CONFIG_SER_DEFBAUDRATE
- ser_setbaudrate(fd, CONFIG_SER_DEFBAUDRATE);
-#endif
-
- /* Clear error flags */
- ser_setstatus(port, 0);
-
- return port;
-}
-
-
-/**
- * Clean up serial port, disabling the associated hardware.
- */
-static int ser_close(struct KFile *fd)
-{
- KFileSerial *fds = KFILESERIAL(fd);
- Serial *port = fds->ser;
-
- ASSERT(port->is_open);
- DB(port->is_open = false);
-
- // Wait until we finish sending everything
- ser_flush(fd);
-
- port->hw->table->cleanup(port->hw);
- DB(port->hw = NULL);
-
- /*
- * We purge the FIFO buffer only after the low-level cleanup, so that
- * we are sure that there are no more interrupts.
- */
- ser_purge(fds);
- return 0;
-}
-
-/**
- * Reopen serial port.
- */
-static struct KFile *ser_reopen(struct KFile *fd)
-{
- KFileSerial *fds = KFILESERIAL(fd);
-
- ser_close(fd);
- ser_open(fds, fds->ser->unit);
- return (KFile *)fds;
-}
-
-/**
- * Init serial driver for \a unit.
- */
-void ser_init(struct KFileSerial *fds, unsigned int unit)
-{
- memset(fds, 0, sizeof(*fds));
-
- DB(fds->fd._type = KFT_SERIAL);
- fds->fd.reopen = ser_reopen;
- fds->fd.close = ser_close;
- fds->fd.read = ser_read;
- fds->fd.write = ser_write;
- fds->fd.flush = ser_flush;
- fds->fd.error = ser_error;
- fds->fd.clearerr = ser_clearerr;
- ser_open(fds, unit);
-}
-
-
-/**
- * Read data from SPI bus.
- * Since we are master, we have to trigger slave by sending
- * fake chars on the bus.
- */
-static size_t spimaster_read(struct KFile *fd, void *_buf, size_t size)
-{
- KFileSerial *fd_spi = KFILESERIAL(fd);
-
- ser_flush(&fd_spi->fd);
- ser_purgeRx(fd_spi);
-
- size_t total_rd = 0;
- uint8_t *buf = (uint8_t *)_buf;
- int c;
-
- while (size--)
- {
- /*
- * Send and receive chars 1 by 1, otherwise the rxfifo
- * will overrun.
- */
- ser_putchar(0, fd_spi->ser);
-
- if ((c = ser_getchar(fd_spi->ser)) == EOF)
- break;
-
- *buf++ = c;
- total_rd++;
- }
- return total_rd;
-}
-
-/**
- * Write data to SPI bus.
- */
-static size_t spimaster_write(struct KFile *fd, const void *buf, size_t size)
-{
- KFileSerial *fd_spi = KFILESERIAL(fd);
-
- ser_purgeRx(fd_spi);
-
- return ser_write(&fd_spi->fd, buf, size);
-}
-
-
-/**
- * Init SPI serial driver \a unit in master mode.
- *
- * This interface implements the SPI master protocol over a serial SPI
- * driver. This is needed because normal serial driver send/receive data
- * at the same time. SPI slaves like memories and other peripherals
- * first receive and *then* send response back instead.
- * To achieve this, when we are master and we are *sending*,
- * we have to discard all incoming data. Then, when we want to
- * receive, we must write fake data to SPI to trigger slave devices.
- */
-void spimaster_init(KFileSerial *fds, unsigned int unit)
-{
- ser_init(fds, unit);
- fds->fd.read = spimaster_read;
- fds->fd.write = spimaster_write;
-}
-
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \brief High level serial I/O API
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef DRV_SER_H
-#define DRV_SER_H
-
-#include <kern/kfile.h>
-#include <mware/fifobuf.h>
-#include <cfg/compiler.h>
-
-#if OS_HOSTED
- #include <cfg/macros.h> /* BV() */
-
- typedef uint16_t serstatus_t;
-
- /* Software errors */
- #define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */
- #define SERRF_RXTIMEOUT BV(1) /**< Receive timeout */
- #define SERRF_TXTIMEOUT BV(2) /**< Transmit timeout */
-
- /* Hardware errors */
- #define SERRF_RXSROVERRUN 0 /**< Unsupported in emulated serial port. */
- #define SERRF_FRAMEERROR 0 /**< Unsupported in emulated serial port. */
- #define SERRF_PARITYERROR 0 /**< Unsupported in emulated serial port. */
- #define SERRF_NOISEERROR 0 /**< Unsupported in emulated serial port. */
-
- enum
- {
- SER_UART0,
- SER_UART1,
-
- SER_CNT /**< Number of serial ports */
- };
-
-#else
- #include CPU_HEADER(ser)
-#endif
-
-#include <appconfig.h>
-
-
-
-/**
- * \name Masks to group TX/RX errors.
- * \{
- */
-#define SERRF_RX \
- ( SERRF_RXFIFOOVERRUN \
- | SERRF_RXTIMEOUT \
- | SERRF_RXSROVERRUN \
- | SERRF_PARITYERROR \
- | SERRF_FRAMEERROR \
- | SERRF_NOISEERROR)
-#define SERRF_TX (SERRF_TXTIMEOUT)
-/*\}*/
-
-/**
- * \name LSB or MSB first data order for SPI driver.
- * \{
- */
-#define SER_MSB_FIRST 0
-#define SER_LSB_FIRST 1
-/*\}*/
-
-/**
- * \name Parity settings for ser_setparity().
- *
- * \note Values are AVR-specific for performance reasons.
- * Other processors should either decode them or
- * redefine these macros.
- * \{
- */
-#define SER_PARITY_NONE 0
-#define SER_PARITY_EVEN 2
-#define SER_PARITY_ODD 3
-/*\}*/
-
-
-struct SerialHardware;
-
-/** Human-readable serial error descriptions */
-extern const char * const serial_errors[8];
-
-/** Serial handle structure */
-typedef struct Serial
-{
- /** Physical port number */
- unsigned int unit;
-
-#ifdef _DEBUG
- bool is_open;
-#endif
-
- /**
- * \name Transmit and receive FIFOs.
- *
- * Declared volatile because handled asinchronously by interrupts.
- *
- * \{
- */
- FIFOBuffer txfifo;
- FIFOBuffer rxfifo;
- /* \} */
-
-#if CONFIG_SER_RXTIMEOUT != -1
- ticks_t rxtimeout;
-#endif
-#if CONFIG_SER_TXTIMEOUT != -1
- ticks_t txtimeout;
-#endif
-
- /** Holds the flags defined above. Will be 0 when no errors have occurred. */
- volatile serstatus_t status;
-
- /** Low-level interface to hardware. */
- struct SerialHardware* hw;
-} Serial;
-
-typedef struct KFileSerial
-{
- KFile fd;
- Serial *ser;
-} KFileSerial;
-
-/**
- * ID for serial.
- */
-#define KFT_SERIAL MAKE_ID('S', 'E', 'R', 'L')
-
-
-INLINE KFileSerial * KFILESERIAL(KFile *fd)
-{
- ASSERT(fd->_type == KFT_SERIAL);
- return (KFileSerial *)fd;
-}
-
-/* Function prototypes */
-//extern int ser_getchar_nowait(struct Serial *port);
-
-void ser_setbaudrate(struct KFileSerial *fd, unsigned long rate);
-void ser_setparity(struct KFileSerial *fd, int parity);
-void ser_settimeouts(struct KFileSerial *fd, mtime_t rxtimeout, mtime_t txtimeout);
-void ser_resync(struct KFileSerial *fd, mtime_t delay);
-int ser_getchar_nowait(struct KFileSerial *fd);
-
-void ser_purgeRx(struct KFileSerial *fd);
-void ser_purgeTx(struct KFileSerial *fd);
-void ser_purge(struct KFileSerial *fd);
-void ser_init(struct KFileSerial *fds, unsigned int unit);
-void spimaster_init(KFileSerial *fds, unsigned int unit);
-
-
-/**
- * \name Additional functions implemented as macros
- *
- * \{
- */
-#define ser_getstatus(h) ((h)->status)
-#define ser_setstatus(h, x) ((h)->status = (x))
-/* \} */
-
-#endif /* DRV_SER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Hardware dependent serial driver (interface)
- *
- * \version $Id$
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-
-#ifndef DRV_SER_P_H
-#define DRV_SER_P_H
-
-#include <cfg/compiler.h> /* size_t */
-
-struct SerialHardware;
-struct Serial;
-
-struct SerialHardwareVT
-{
- void (*init)(struct SerialHardware *ctx, struct Serial *ser);
- void (*cleanup)(struct SerialHardware *ctx);
- void (*setBaudrate)(struct SerialHardware *ctx, unsigned long rate);
- void (*setParity)(struct SerialHardware *ctx, int parity);
- void (*txStart)(struct SerialHardware *ctx);
- bool (*txSending)(struct SerialHardware *ctx);
-};
-
-struct SerialHardware
-{
- const struct SerialHardwareVT *table;
- unsigned char *txbuffer;
- unsigned char *rxbuffer;
- size_t txbuffer_size;
- size_t rxbuffer_size;
-};
-
-struct SerialHardware *ser_hw_getdesc(int unit);
-
-#endif /* DRV_SER_P_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Serial port emulator for hosted environments.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2006/02/17 22:28:00 bernie
- *#* Rename ser_emul.c to ser_posix.c.
- *#*
- *#* Revision 1.4 2006/02/17 22:23:06 bernie
- *#* Update POSIX serial emulator.
- *#*
- *#* Revision 1.3 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.2 2005/04/11 19:10:27 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.1 2004/12/31 17:40:00 bernie
- *#* Add a simple serial emulation driver.
- *#*
- *#*/
-
-#include "ser.h"
-#include "ser_p.h"
-
-#include <cfg/debug.h>
-#include <cfg/compiler.h>
-#include <mware/fifobuf.h>
-
-#include <appconfig.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h> /* open() */
-#include <unistd.h> /* read(), write() */
-
-
-/* From the high-level serial driver */
-extern struct Serial ser_handles[SER_CNT];
-
-/* TX and RX buffers */
-static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
-static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
-static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
-static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
-
-
-/**
- * Internal state structure
- */
-struct EmulSerial
-{
- struct SerialHardware hw;
- struct Serial *ser;
- int fd;
-};
-
-
-/*
- * Callbacks
- */
-static void uart_init(struct SerialHardware *_hw, struct Serial *ser)
-{
- struct EmulSerial *hw = (struct EmulSerial *)_hw;
-
- hw->ser = ser;
- hw->fd = open("/dev/ttyS0", O_RDWR);
-}
-
-static void uart_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
-{
- struct EmulSerial *hw = (struct EmulSerial *)_hw;
-
- close(hw->fd);
- hw->fd = -1;
-}
-
-static void uart_txStart(struct SerialHardware * _hw)
-{
- struct EmulSerial *hw = (struct EmulSerial *)_hw;
-
- while(!fifo_isempty(&hw->ser->txfifo))
- {
- char c = fifo_pop(&hw->ser->txfifo);
- write(hw->fd, &c, 1);
- }
-}
-
-static bool uart_txSending(UNUSED_ARG(struct SerialHardware *, _hw))
-{
- return false;
-}
-
-
-static void uart_setBaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
-{
- TRACEMSG("rate=%lu", rate);
- // TODO
-
-}
-
-static void uart_setParity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
-{
- TRACEMSG("parity=%d", parity);
- // TODO
-}
-
-// FIXME: move into compiler.h? Ditch?
-#if COMPILER_C99
- #define C99INIT(name,val) .name = val
-#elif defined(__GNUC__)
- #define C99INIT(name,val) name: val
-#else
- #warning No designated initializers, double check your code
- #define C99INIT(name,val) (val)
-#endif
-
-/*
- * High-level interface data structures.
- */
-static const struct SerialHardwareVT uart_vtable =
-{
- C99INIT(init, uart_init),
- C99INIT(cleanup, uart_cleanup),
- C99INIT(setBaudrate, uart_setBaudrate),
- C99INIT(setParity, uart_setParity),
- C99INIT(txStart, uart_txStart),
- C99INIT(txSending, uart_txSending),
-};
-
-static struct EmulSerial UARTDescs[SER_CNT] =
-{
- {
- C99INIT(hw, /**/) {
- C99INIT(table, &uart_vtable),
- C99INIT(txbuffer, uart0_txbuffer),
- C99INIT(rxbuffer, uart0_rxbuffer),
- C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
- C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
- },
- C99INIT(ser, NULL),
- C99INIT(fd, -1),
- },
- {
- C99INIT(hw, /**/) {
- C99INIT(table, &uart_vtable),
- C99INIT(txbuffer, uart1_txbuffer),
- C99INIT(rxbuffer, uart1_rxbuffer),
- C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
- C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
- },
- C99INIT(ser, NULL),
- C99INIT(fd, -1),
- },
-};
-
-struct SerialHardware *ser_hw_getdesc(int unit)
-{
- ASSERT(unit < SER_CNT);
- return &UARTDescs[unit].hw;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \brief Emulated SPI Master for DSP firmware download (impl.)
- *
- * \version $Id: spi.c 15328 2007-03-21 15:07:04Z batt $
- *
- * \author Francesco Sacchi <batt@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- */
-
-
-#include <cfg/cpu.h>
-#include <cfg/module.h>
-#include <drv/spi_emu.h>
-#include "hw_spi.h"
-
-void spi_assertSS(void)
-{
- ATOMIC(SS_ACTIVE());
-}
-
-void spi_deassertSS(void)
-{
- ATOMIC(SS_INACTIVE());
-}
-
-/**
- * Send byte \c c over MOSI line, CONFIG_SPI_DATAORDER first.
- * SS pin state is left unchanged.
- */
-uint8_t spi_sendRecv(uint8_t c)
-{
- uint8_t data = 0;
- uint8_t shift = SPI_DATAORDER_START;
-
-
- ATOMIC(
- for (int i = 0; i < 8; i++)
- {
- /* Shift the i-th bit to MOSI */
- if (c & shift)
- MOSI_HIGH();
- else
- MOSI_LOW();
- /* Assert clock */
- SCK_ACTIVE();
- data |= IS_MISO_HIGH() ? shift : 0;
- /* De-assert clock */
- SCK_INACTIVE();
- SPI_DATAORDER_SHIFT(shift);
- }
- );
- return data;
-}
-
-MOD_DEFINE(spi);
-void spi_init(void)
-{
- ATOMIC(SPI_HW_INIT());
- MOD_INIT(spi);
-}
-
-/**
- * Read \param len from spi, and put it in \param _buff .
- */
-void spi_read(void *_buff, size_t len)
-{
- uint8_t *buff = (uint8_t *)_buff;
-
- while (len--)
- /* Read byte from spi and put it in buffer. */
- *buff++ = spi_sendRecv(0);
-
-}
-
-/**
- * Write \param len to spi, and take it from \param _buff .
- */
-void spi_write(const void *_buff, size_t len)
-{
- const uint8_t *buff = (const uint8_t *)_buff;
-
- while (len--)
- /* Write byte pointed at by *buff to spi */
- spi_sendRecv(*buff++);
-
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \brief Emulated SPI Master for DSP firmware download (interface)
- *
- * \version $Id: spi.h 15321 2007-03-21 14:45:12Z asterix $
- *
- * \author Francesco Sacchi <batt@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- */
-
-
-#ifndef DRV_SPI_EMU_H
-#define DRV_SPI_EMU_H
-
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-/**
- * Define send and receive order bit.
- * \{
- */
-#define SPI_LSB_FIRST 1
-#define SPI_MSB_FIRST 2
-/* \} */
-
-#if CONFIG_SPI_DATAORDER == SPI_LSB_FIRST
- #define SPI_DATAORDER_START 1
- #define SPI_DATAORDER_SHIFT(i) ((i) <<= 1)
-#elif CONFIG_SPI_DATAORDER == SPI_MSB_FIRST
- #define SPI_DATAORDER_START 0x80
- #define SPI_DATAORDER_SHIFT(i) ((i) >>= 1)
-#endif
-
-void spi_write(const void *buf, size_t len);
-void spi_read(void *buf, size_t len);
-uint8_t spi_sendRecv(uint8_t c);
-void spi_init(void);
-void spi_assertSS(void);
-void spi_deassertSS(void);
-
-#endif /* DRV_SPI_EMU_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief TC520 ADC driver (implementation)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- * \author Marco Benelli <marco@develer.com>
- */
-
-#include <drv/tc520.h>
-#include <drv/timer.h>
-
-#include <hw_tc520.h>
-
-#include <cfg/macros.h>
-#include <cfg/compiler.h>
-
-#include <drv/ser.h>
-
-static Serial *spi_ser;
-
-#define TC520_CONVERSION_TIMEOUT ms_to_ticks(1000)
-#define INIT_LOAD_VALUE 0x00
-
-/**
- * Start an AD conversion and return result.
- *
- * To start a conversion first we must pull down CE pin.
- * The ADC starts a convertion and keeps the DV pin high until the end.
- * At this point, we can read the conversion value by SPI.
- * The convertion result is yield in 3 bytes.
- *
- * \verbatim
- *
- * First byte:
- * bit | Value
- * ----|-------
- * 7 | Overrange
- * 6 | Polarity
- * 5:0 | data bits 15:10
- *
- * Second byte: data 9:2
- *
- * Third byte:
- * bit | Value
- * ----|-------
- * 7 | data bit 1
- * 6 | data bit 0
- * 5:0 | '0'
- *
- * \endverbatim
- *
- * So, to get the result we must shift and recompose the bits.
- * \note Overrange bit is handled as the 17th data bit.
- */
-tc520_data_t tc520_read(void)
-{
- /* Start convertion and wait */
- CE_LOW();
- ticks_t start = timer_clock();
- do
- {
- /* timeout check */
- if (timer_clock() - start >= TC520_CONVERSION_TIMEOUT)
- {
- ASSERT(0);
- CE_HIGH();
- return TC520_MAX_VALUE;
- }
- }
- while(DV_LOW());
-
- start = timer_clock();
- do
- {
- /* timeout check */
- if (timer_clock() - start >= TC520_CONVERSION_TIMEOUT)
- {
- ASSERT(0);
- CE_HIGH();
- return TC520_MAX_VALUE;
- }
- }
- while(DV_HIGH());
-
- /* Ok, convertion finished, read result */
- CE_HIGH();
- READ_LOW();
-
- /* RX buffer could be dirty...*/
- ser_purge(spi_ser);
-
- /* I/O buffer */
- uint8_t buf[3] = "\x0\x0\x0";
-
- /* Dummy write to activate recv */
- ser_write(spi_ser, buf, sizeof(buf));
- ser_drain(spi_ser);
- READ_HIGH();
-
- /* recv */
- ASSERT(ser_read(spi_ser, buf, sizeof(buf)) == sizeof(buf));
-
- tc520_data_t res;
-
- /* Recompose data */
- res = (((tc520_data_t)(buf[0] & 0x3F)) << 10) | (((tc520_data_t)buf[1]) << 2) | (((tc520_data_t)buf[2]) >> 6);
-
- #define OVERRANGE_BIT BV(7)
- /* Handle overrange bit as 17th bit */
- if (buf[0] & OVERRANGE_BIT)
- res |= BV32(16);
-
- return res;
-}
-
-
-/**
- * Initialize tc520 A/D converter driver
- */
-void tc520_init(Serial *spi_port)
-{
- spi_ser = spi_port;
- /* init io ports */
- TC520_HW_INIT;
- /* Send initial load value */
- LOAD_LOW();
- ser_putchar(INIT_LOAD_VALUE, spi_ser);
- ser_drain(spi_ser);
- LOAD_HIGH();
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief TC520 ADC driver (intercace)
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- * \author Marco Benelli <marco@develer.com>
- */
-
-#ifndef DRV_TC520_H
-#define DRV_TC520_H
-
-#include <drv/ser.h>
-#include <cfg/compiler.h>
-
-typedef uint32_t tc520_data_t;
-
-/* 17 bit max value */
-#define TC520_MAX_VALUE 0x1FFFFUL
-
-tc520_data_t tc520_read(void);
-void tc520_init(Serial *spi_port);
-
-#endif /* DRV_TC520_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Thermo-control driver
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.3 2006/09/20 20:12:41 marco
- *#* Names convention, MOD_* macros.
- *#*
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 17:59:47 bernie
- *#* Import into DevLib.
- *#*
- *#*/
-#include <thermo_map.h>
-#include <hw_thermo.h>
-
-#include <drv/thermo.h>
-#include <drv/timer.h>
-#include <drv/ntc.h>
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-
-/** Interval at which thermo control is performed. */
-#define THERMO_INTERVAL_MS 100
-
-/** Number of different samples we interpolate over to get the hifi temperature. */
-#define THERMO_HIFI_NUM_SAMPLES 10
-
-/** Timer for thermo-regulation. */
-static Timer thermo_timer;
-
-typedef struct ThermoControlDev
-{
- deg_t hifi_samples[THERMO_HIFI_NUM_SAMPLES];
- deg_t cur_hifi_sample;
- deg_t target;
- thermostatus_t status;
- ticks_t expire;
-} ThermoControlDev;
-
-/** Array of thermo-devices. */
-ThermoControlDev devs[THERMO_CNT];
-
-
-/**
- * Return the status of the specific \a dev thermo-device.
- */
-thermostatus_t thermo_status(ThermoDev dev)
-{
- return devs[dev].status;
-}
-
-
-/**
- * Do a single thermo control for device \a dev.
- */
-static void thermo_do(ThermoDev index)
-{
- ThermoControlDev* dev = &devs[index];
- deg_t cur_temp;
- deg_t tolerance = thermo_hw_tolerance(index);
-
- cur_temp = thermo_hw_read(index);
-
- // Store the sample into the hifi FIFO buffer for later interpolation
- dev->hifi_samples[dev->cur_hifi_sample] = cur_temp;
- if (++dev->cur_hifi_sample == THERMO_HIFI_NUM_SAMPLES)
- dev->cur_hifi_sample = 0;
-
- cur_temp = thermo_readTemperature(index);
-
- if (cur_temp == NTC_SHORT_CIRCUIT || cur_temp == NTC_OPEN_CIRCUIT)
- {
- if (cur_temp == NTC_SHORT_CIRCUIT)
- {
- #ifdef _DEBUG
- if (!(dev->status & THERMOERRF_NTCSHORT))
- kprintf("dev[%d], thermo_do: NTC_SHORT\n",index);
- #endif
- dev->status |= THERMOERRF_NTCSHORT;
- }
- else
- {
- #ifdef _DEBUG
- if (!(dev->status & THERMOERRF_NTCOPEN))
- kprintf("dev[%d], thermo_do: NTC_OPEN\n", index);
- #endif
- dev->status |= THERMOERRF_NTCOPEN;
- }
-
- /* Reset timeout when there is an ntc error */
- dev->expire = thermo_hw_timeout(index) + timer_clock();
- thermo_hw_off(index);
- return;
- }
- dev->status &= ~(THERMOERRF_NTCOPEN | THERMOERRF_NTCSHORT);
-
- if ((cur_temp < dev->target - tolerance) || (cur_temp > dev->target + tolerance))
- {
- dev->status &= ~THERMO_TGT_REACH;
-
- /* Check for timeout */
- if (timer_clock() - dev->expire > 0)
- {
- dev->status |= THERMOERRF_TIMEOUT;
- kprintf("dev[%d], thermo_do: TIMEOUT\n", index);
- }
- }
- else /* In target */
- {
- /* Clear errors */
- dev->status &= ~THERMO_ERRMASK;
- dev->status |= THERMO_TGT_REACH;
-
- /* Reset timeout in case we go out of target in the future */
- dev->expire = thermo_hw_timeout(index) + timer_clock();
- }
-
- if (cur_temp < dev->target)
- dev->status = (dev->status | THERMO_HEATING) & ~THERMO_FREEZING;
- else
- dev->status = (dev->status & ~THERMO_HEATING) | THERMO_FREEZING;
-
- thermo_hw_set(index, dev->target, cur_temp);
-
-}
-
-
-/**
- * Thermo soft interrupt.
- */
-static void thermo_softint(void)
-{
- int i;
- for (i = 0; i < THERMO_CNT; ++i)
- if (devs[i].status & THERMO_ACTIVE)
- thermo_do((ThermoDev)i);
-
- timer_add(&thermo_timer);
-}
-
-
-/**
- * Set the target temperature \a temperature for a specific \a dev thermo-device.
- */
-void thermo_setTarget(ThermoDev dev, deg_t temperature)
-{
- ASSERT(dev < THERMO_CNT);
- devs[dev].target = temperature;
- devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
-
- kprintf("setTarget dev[%d], T[%d.%d]\n", dev, temperature / 10, temperature % 10);
-}
-
-/**
- * Starts a thermo-regulation for channel \a dev.
- */
-void thermo_start(ThermoDev dev)
-{
- int i;
- deg_t temp;
-
- ASSERT(dev < THERMO_CNT);
-
- devs[dev].status |= THERMO_ACTIVE;
-
- /* Initialize the hifi FIFO with a constant value (the current temperature) */
- temp = thermo_hw_read(dev);
- for (i = 0; i < THERMO_HIFI_NUM_SAMPLES; ++i)
- devs[dev].hifi_samples[i] = temp;
- devs[dev].cur_hifi_sample = 0;
-
- /* Reset timeout */
- devs[dev].expire = timer_clock() + thermo_hw_timeout(dev);
-}
-
-/**
- * Stops a thermo-regulation for channel \a dev.
- */
-void thermo_stop(ThermoDev dev)
-{
- ASSERT(dev < THERMO_CNT);
-
- devs[dev].status &= ~THERMO_ACTIVE;
- thermo_hw_off(dev);
-}
-
-
-/**
- * Clear errors for channel \a dev.
- */
-void thermo_clearErrors(ThermoDev dev)
-{
- ASSERT(dev < THERMO_CNT);
- devs[dev].status &= ~(THERMO_ERRMASK);
-}
-
-
-/**
- * Read the temperature of the thermo-device \a dev using mobile mean.
- */
-deg_t thermo_readTemperature(ThermoDev dev)
-{
- int i;
- long accum = 0;
-
- MOD_CHECK(thermo);
-
- for (i = 0; i < THERMO_HIFI_NUM_SAMPLES; i++)
- accum += devs[dev].hifi_samples[i];
-
- return (deg_t)(accum / THERMO_HIFI_NUM_SAMPLES);
-}
-
-MOD_DEFINE(thermo)
-
-/**
- * Init thermo-control and associated hw.
- */
-void thermo_init(void)
-{
- THERMO_HW_INIT;
-
- /* Set all status to off */
- for (int i = 0; i < THERMO_CNT; i++)
- devs[i].status = THERMO_OFF;
-
- MOD_INIT(thermo);
-
- timer_setDelay(&thermo_timer, ms_to_ticks(THERMO_INTERVAL_MS));
- timer_set_event_softint(&thermo_timer, (Hook)thermo_softint, 0);
- timer_add(&thermo_timer);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Thermo-control driver
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- *
- * This module implements multiple thermo controls, which is the logic needed to try
- * keeping the temperature of a device constant. For this module, a "device" is a black box
- * whose temperature can be measured, and which has a mean to make it hotter or colder.
- * For instance, a device could be the combination of a NTC (analog temperature reader) and
- * a Peltier connected to the same physic block.
- *
- * This module relies on a low-level driver to communicate with the device (implementation
- * of the black box). This low-level driver also controls the units in which the temperature
- * is expressed: thermo control treats it just as a number.
- *
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.3 2006/09/20 20:12:41 marco
- *#* Names convention, MOD_* macros.
- *#*
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 17:59:47 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.2 2005/06/14 10:13:36 batt
- *#* Better thermo errors handling.
- *#*
- *#* Revision 1.1 2005/05/24 09:17:58 batt
- *#* Move drivers to top-level.
- *#*
- *#* Revision 1.4 2005/05/10 16:55:10 batt
- *#* Add timeout to thermo-regulator; better thermo control handling; change thermo_getStatus() to thermo_status().
- *#*
- *#* Revision 1.3 2005/05/10 09:26:54 batt
- *#* Add thermo_getStatus for getting status/errors of thermo control.
- *#*
- *#* Revision 1.2 2005/05/09 19:18:40 batt
- *#* Remove old logs.
- *#*
- *#* Revision 1.1 2005/05/09 16:40:44 batt
- *#* Add thermo-control driver
- *#*/
-
-
-#ifndef DRV_THERMO_H
-#define DRV_THERMO_H
-
-#include <drv/ntc.h>
-#include <thermo_map.h>
-
-void thermo_init(void);
-
-
-/**
- * Set the target temperature at which a given device should be kept.
- *
- * \param dev Device
- * \param temperature Target temperature
- */
-void thermo_setTarget(ThermoDev dev, deg_t temperature);
-
-/** Start thermo control for a certain device \a dev */
-void thermo_start(ThermoDev dev);
-
-/** Stop thermo control for a certain device \a dev */
-void thermo_stop(ThermoDev dev);
-
-/** Clear errors for channel \a dev */
-void thermo_clearErrors(ThermoDev dev);
-
-/** Return the status of the specific \a dev thermo-device. */
-thermostatus_t thermo_status(ThermoDev dev);
-
-/**
- * Return the current temperature of a device currently under thermo
- * control.
- *
- * \param dev Device
- * \return Current temperature (Celsius degrees * 10)
- */
-deg_t thermo_readTemperature(ThermoDev dev);
-
-
-#endif /* DRV_THERMO_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Hardware independent timer driver (implementation)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "timer.h"
-
-#include <cpu/attr.h>
-#include <cpu/types.h>
-#include <cpu/irq.h>
-
-#include <cfg/os.h>
-#include <cfg/debug.h>
-#include <cfg/module.h>
-#include <appconfig.h>
-
-/*
- * Include platform-specific binding code if we're hosted.
- * Try the CPU specific one for bare-metal environments.
- */
-#if OS_HOSTED
- #include OS_CSOURCE(timer)
-#else
- #include CPU_CSOURCE(timer)
-#endif
-
-/*
- * Sanity check for config parameters required by this module.
- */
-#if !defined(CONFIG_KERNEL) || ((CONFIG_KERNEL != 0) && CONFIG_KERNEL != 1)
- #error CONFIG_KERNEL must be set to either 0 or 1 in config.h
-#endif
-#if !defined(CONFIG_WATCHDOG) || ((CONFIG_WATCHDOG != 0) && CONFIG_WATCHDOG != 1)
- #error CONFIG_WATCHDOG must be set to either 0 or 1 in config.h
-#endif
-
-#if CONFIG_WATCHDOG
- #include <drv/wdt.h>
-#endif
-
-#if CONFIG_KERNEL
- #include <config_kern.h>
- #if CONFIG_KERN_PREEMPTIVE
- #include <hw/switch.h>
- #endif
- #if CONFIG_KERN_SIGNALS
- #include <kern/signal.h> /* sig_wait(), sig_check() */
- #include <kern/proc.h> /* proc_current() */
- #include <cfg/macros.h> /* BV() */
- #endif
-#endif
-
-
-/**
- * \def CONFIG_TIMER_STROBE
- *
- * This is a debug facility that can be used to
- * monitor timer interrupt activity on an external pin.
- *
- * To use strobes, redefine the macros TIMER_STROBE_ON,
- * TIMER_STROBE_OFF and TIMER_STROBE_INIT and set
- * CONFIG_TIMER_STROBE to 1.
- */
-#if !defined(CONFIG_TIMER_STROBE) || !CONFIG_TIMER_STROBE
- #define TIMER_STROBE_ON do {/*nop*/} while(0)
- #define TIMER_STROBE_OFF do {/*nop*/} while(0)
- #define TIMER_STROBE_INIT do {/*nop*/} while(0)
-#endif
-
-
-/// Master system clock (1 tick accuracy)
-volatile ticks_t _clock;
-
-
-#ifndef CONFIG_TIMER_DISABLE_EVENTS
-
-/**
- * List of active asynchronous timers.
- */
-REGISTER static List timers_queue;
-
-
-/**
- * Add the specified timer to the software timer service queue.
- * When the delay indicated by the timer expires, the timer
- * device will execute the event associated with it.
- *
- * \note Interrupt safe
- */
-void timer_add(Timer *timer)
-{
- Timer *node;
- cpuflags_t flags;
-
-
- /* Inserting timers twice causes mayhem. */
- ASSERT(timer->magic != TIMER_MAGIC_ACTIVE);
- DB(timer->magic = TIMER_MAGIC_ACTIVE;)
-
- IRQ_SAVE_DISABLE(flags);
-
- /* Calculate expiration time for this timer */
- timer->tick = _clock + timer->_delay;
-
- /*
- * Search for the first node whose expiration time is
- * greater than the timer we want to add.
- */
- node = (Timer *)LIST_HEAD(&timers_queue);
- while (node->link.succ)
- {
- /*
- * Stop just after the insertion point.
- * (this fancy compare takes care of wrap-arounds).
- */
- if (node->tick - timer->tick > 0)
- break;
-
- /* Go to next node */
- node = (Timer *)node->link.succ;
- }
-
- /* Enqueue timer request into the list */
- INSERT_BEFORE(&timer->link, &node->link);
-
- IRQ_RESTORE(flags);
-}
-
-
-/**
- * Remove a timer from the timer queue before it has expired.
- */
-Timer *timer_abort(Timer *timer)
-{
- ATOMIC(REMOVE(&timer->link));
- DB(timer->magic = TIMER_MAGIC_INACTIVE;)
-
- return timer;
-}
-
-#endif /* CONFIG_TIMER_DISABLE_EVENTS */
-
-
-/**
- * Wait for the specified amount of timer ticks.
- */
-void timer_delayTicks(ticks_t delay)
-{
-#if defined(IRQ_ENABLED)
- /* We shouldn't sleep with interrupts disabled */
- ASSERT(IRQ_ENABLED());
-#endif
-
-#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
- Timer t;
-
- ASSERT(!sig_check(SIG_SINGLE));
- timer_set_event_signal(&t, proc_current(), SIG_SINGLE);
- timer_setDelay(&t, delay);
- timer_add(&t);
- sig_wait(SIG_SINGLE);
-
-#else /* !CONFIG_KERN_SIGNALS */
-
- ticks_t start = timer_clock();
-
- /* Busy wait */
- while (timer_clock() - start < delay)
- {
-#if CONFIG_WATCHDOG
- wdt_reset();
-#endif
- }
-
-#endif /* !CONFIG_KERN_SIGNALS */
-}
-
-
-#ifndef CONFIG_TIMER_DISABLE_UDELAY
-
-/**
- * Busy wait until the specified amount of high-precision ticks have elapsed.
- *
- * \note This function is interrupt safe, the only
- * requirement is a running hardware timer.
- */
-void timer_busyWait(hptime_t delay)
-{
- hptime_t now, prev = timer_hw_hpread();
- hptime_t delta;
-
- for(;;)
- {
- now = timer_hw_hpread();
- /*
- * We rely on hptime_t being unsigned here to
- * reduce the modulo to an AND in the common
- * case of TIMER_HW_CNT.
- */
- delta = (now - prev) % TIMER_HW_CNT;
- if (delta >= delay)
- break;
- delay -= delta;
- prev = now;
- }
-}
-
-/**
- * Wait for the specified amount of time (expressed in microseconds).
- *
- * \bug In AVR arch the maximum amount of time that can be used as
- * delay could be very limited, depending on the hardware timer
- * used. Check timer_avr.h, and what register is used as hptime_t.
- */
-void timer_delayHp(hptime_t delay)
-{
- if (UNLIKELY(delay > us_to_hptime(1000)))
- {
- timer_delayTicks(delay / (TIMER_HW_HPTICKS_PER_SEC / TIMER_TICKS_PER_SEC));
- delay %= (TIMER_HW_HPTICKS_PER_SEC / TIMER_TICKS_PER_SEC);
- }
-
- timer_busyWait(delay);
-}
-#endif /* CONFIG_TIMER_DISABLE_UDELAY */
-
-
-/**
- * Timer interrupt handler. Find soft timers expired and
- * trigger corresponding events.
- */
-DEFINE_TIMER_ISR
-{
- /*
- * With the Metrowerks compiler, the only way to force the compiler generate
- * an interrupt service routine is to put a pragma directive within the function
- * body.
- */
- #ifdef __MWERKS__
- #pragma interrupt saveall
- #endif
-
-#ifndef CONFIG_TIMER_DISABLE_EVENTS
- Timer *timer;
-#endif
- /*
- * On systems sharing IRQ line and vector, this check is needed
- * to ensure that IRQ is generated by timer source.
- */
- if (!timer_hw_triggered())
- return;
-
- TIMER_STROBE_ON;
-
- /* Perform hw IRQ handling */
- timer_hw_irq();
-
- /* Update the master ms counter */
- ++_clock;
-
-#ifndef CONFIG_TIMER_DISABLE_EVENTS
- /*
- * Check the first timer request in the list and process
- * it when it has expired. Repeat this check until the
- * first node has not yet expired. Since the list is sorted
- * by expiry time, all the following requests are guaranteed
- * to expire later.
- */
- while ((timer = (Timer *)LIST_HEAD(&timers_queue))->link.succ)
- {
- /* This request in list has not yet expired? */
- if (_clock - timer->tick < 0)
- break;
-
- /* Retreat the expired timer */
- REMOVE(&timer->link);
- DB(timer->magic = TIMER_MAGIC_INACTIVE;)
-
- /* Execute the associated event */
- event_do(&timer->expire);
- }
-#endif /* CONFIG_TIMER_DISABLE_EVENTS */
-
- TIMER_STROBE_OFF;
-}
-
-MOD_DEFINE(timer)
-
-/**
- * Initialize timer
- */
-void timer_init(void)
-{
- TIMER_STROBE_INIT;
-
-#ifndef CONFIG_TIMER_DISABLE_EVENTS
- LIST_INIT(&timers_queue);
-#endif
-
- _clock = 0;
-
- timer_hw_init();
-
- MOD_INIT(timer);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Hardware independent timer driver (interface)
- */
-
-#ifndef DRV_TIMER_H
-#define DRV_TIMER_H
-
-#include <cfg/os.h>
-#include <cfg/macros.h>
-#include <cpu/attr.h>
-#include <cpu/irq.h>
-
-
-/*
- * Include platform-specific binding header if we're hosted.
- * Try the CPU specific one for bare-metal environments.
- */
-#if OS_HOSTED
- #include OS_HEADER(timer)
-#else
- #include CPU_HEADER(timer)
-#endif
-
-#include <mware/list.h>
-#include <cfg/debug.h>
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-
-extern volatile ticks_t _clock;
-
-/**
- * \brief Return the system tick counter (expressed in ticks)
- *
- * The result is guaranteed to increment monotonically,
- * but client code must be tolerant with respect to overflows.
- *
- * The following code is safe:
- *
- * \code
- * ticks_t tea_start_time = timer_clock();
- *
- * boil_water();
- *
- * if (timer_clock() - tea_start_time > TEAPOT_DELAY)
- * printf("Your tea, Sir.\n");
- * \endcode
- *
- * \note This function must disable interrupts on 8/16bit CPUs because the
- * clock variable is larger than the processor word size and can't
- * be copied atomically.
- */
-INLINE ticks_t timer_clock(void)
-{
- ticks_t result;
-
- ATOMIC(result = _clock);
-
- return result;
-}
-
-/**
- * Faster version of timer_clock(), to be called only when the timer
- * interrupt is disabled (DISABLE_INTS) or overridden by a
- * higher-priority or non-nesting interrupt.
- *
- * \sa timer_clock
- */
-INLINE ticks_t timer_clock_unlocked(void)
-{
- return _clock;
-}
-
-/** Convert \a ms [ms] to ticks. */
-INLINE ticks_t ms_to_ticks(mtime_t ms)
-{
-#if TIMER_TICKS_PER_SEC < 1000
- /* Slow timer: avoid rounding down too much. */
- return (ms * TIMER_TICKS_PER_SEC) / 1000;
-#else
- /* Fast timer: don't overflow ticks_t. */
- return ms * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000);
-#endif
-}
-
-/** Convert \a us [us] to ticks. */
-INLINE ticks_t us_to_ticks(utime_t us)
-{
-#if TIMER_TICKS_PER_SEC < 1000
- /* Slow timer: avoid rounding down too much. */
- return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
-#else
- /* Fast timer: don't overflow ticks_t. */
- return (us * DIV_ROUND(TIMER_TICKS_PER_SEC, 1000)) / 1000;
-#endif
-}
-
-/** Convert \a ticks [ticks] to ms. */
-INLINE mtime_t ticks_to_ms(ticks_t ticks)
-{
-#if TIMER_TICKS_PER_SEC < 1000
- /* Slow timer: avoid rounding down too much. */
- return (ticks * 1000) / TIMER_TICKS_PER_SEC;
-#else
- /* Fast timer: avoid overflowing ticks_t. */
- return ticks / (TIMER_TICKS_PER_SEC / 1000);
-#endif
-}
-
-/** Convert \a ticks [ticks] to us. */
-INLINE utime_t ticks_to_us(ticks_t ticks)
-{
-#if TIMER_TICKS_PER_SEC < 1000
- /* Slow timer: avoid rounding down too much. */
- return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
-#else
- /* Fast timer: avoid overflowing ticks_t. */
- return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
-#endif
-}
-
-/** Convert \a us [us] to hpticks */
-INLINE hptime_t us_to_hptime(utime_t us)
-{
-#if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
- return us * DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000000UL);
-#else
- return (us * ((TIMER_HW_HPTICKS_PER_SEC + 500) / 1000UL) + 500) / 1000UL;
-#endif
-}
-
-/** Convert \a hpticks [hptime] to usec */
-INLINE utime_t hptime_to_us(hptime_t hpticks)
-{
-#if TIMER_HW_HPTICKS_PER_SEC < 100000UL
- return hpticks * DIV_ROUND(1000000UL, TIMER_HW_HPTICKS_PER_SEC);
-#else
- return (hpticks * 1000UL) / DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, 1000UL);
-#endif /* TIMER_HW_HPTICKS_PER_SEC < 100000UL */
-}
-
-
-void timer_init(void);
-void timer_delayTicks(ticks_t delay);
-INLINE void timer_delay(mtime_t delay)
-{
- timer_delayTicks(ms_to_ticks(delay));
-}
-
-#if !defined(CONFIG_TIMER_DISABLE_UDELAY)
-void timer_busyWait(hptime_t delay);
-void timer_delayHp(hptime_t delay);
-INLINE void timer_udelay(utime_t delay)
-{
- timer_delayHp(us_to_hptime(delay));
-}
-#endif
-
-#ifndef CONFIG_TIMER_DISABLE_EVENTS
-
-#include <mware/event.h>
-
-/**
- * The timer driver supports multiple synchronous timers
- * that can trigger an event when they expire.
- *
- * \sa timer_add()
- * \sa timer_abort()
- */
-typedef struct Timer
-{
- Node link; /**< Link into timers queue */
- ticks_t _delay; /**< Timer delay in ms */
- ticks_t tick; /**< Timer will expire at this tick */
- Event expire; /**< Event to execute when the timer expires */
- DB(uint16_t magic;)
-} Timer;
-
-/** Timer is active when Timer.magic contains this value (for debugging purposes). */
-#define TIMER_MAGIC_ACTIVE 0xABBA
-#define TIMER_MAGIC_INACTIVE 0xBAAB
-
-extern void timer_add(Timer *timer);
-extern Timer *timer_abort(Timer *timer);
-
-/** Set the timer so that it calls an user hook when it expires */
-INLINE void timer_set_event_softint(Timer *timer, Hook func, iptr_t user_data)
-{
- event_initSoftInt(&timer->expire, func, user_data);
-}
-
-/** Set the timer delay (the time before the event will be triggered) */
-INLINE void timer_setDelay(Timer *timer, ticks_t delay)
-{
- timer->_delay = delay;
-}
-
-#endif /* CONFIG_TIMER_DISABLE_EVENTS */
-
-#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
-
-/** Set the timer so that it sends a signal when it expires */
-INLINE void timer_set_event_signal(Timer *timer, struct Process *proc, sigmask_t sigs)
-{
- event_initSignal(&timer->expire, proc, sigs);
-}
-
-#endif /* CONFIG_KERN_SIGNALS */
-
-
-#endif /* DRV_TIMER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005,2008 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Low-level timer module for Qt emulator (implementation).
- */
-#include <cfg/compiler.h> // hptime.t
-#include <os/hptime.h>
-
-#include <signal.h> // sigaction()
-#include <sys/time.h> // setitimer()
-#include <string.h> // memset()
-
-
-// Forward declaration for the user interrupt server routine.
-void timer_isr(int);
-
-/// HW dependent timer initialization.
-static void timer_hw_init(void)
-{
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
-
- // Setup interrupt callback
- sa.sa_handler = timer_isr;
- sigemptyset(&sa.sa_mask);
- sigaddset(&sa.sa_mask, SIGALRM);
- sa.sa_flags = SA_RESTART;
- sigaction(SIGALRM, &sa, NULL);
-
- // Setup POSIX realtime timer to interrupt every 1/TIMER_TICKS_PER_SEC.
- static struct itimerval itv =
- {
- { 0, 1000000 / TIMER_TICKS_PER_SEC }, /* it_interval */
- { 0, 1000000 / TIMER_TICKS_PER_SEC } /* it_value */
- };
- setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-INLINE hptime_t timer_hw_hpread(void)
-{
- return hptime_get();
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Low-level timer module for POSIX systems (interface).
- */
-#ifndef DRV_TIMER_POSIX_H
-#define DRV_TIMER_POSIX_H
-
-// HW dependent timer initialization
-
-#define DEFINE_TIMER_ISR void timer_isr(UNUSED_ARG(int, arg))
-
-/** Most Linux kernels can't do better than this (CONFIG_HZ=250). */
-#define TIMER_TICKS_PER_SEC 250
-
-#define TIMER_HW_CNT (1<<31) /* We assume 32bit integers here */
-
-#include <os/hptime.h>
-
-/// Frequency of the hardware high-precision timer.
-#define TIMER_HW_HPTICKS_PER_SEC HPTIME_TICKS_PER_SECOND
-
-/// Not needed.
-#define timer_hw_irq() do {} while (0)
-
-#endif /* DRV_TIMER_POSIX_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Low-level timer module for Qt emulator (implementation).
- */
-#include <cfg/compiler.h> /* hptime.t */
-
-// Qt headers
-#include <QtCore/QDateTime>
-#include <QtCore/QTimer>
-
-
-// The user interrupt server routine
-void timer_isr(void);
-
-
-/**
- * Singleton class for Qt-based hardware timer emulation.
- */
-class EmulTimer : public QObject
-{
-private:
- Q_OBJECT;
-
- /// System timer (counts ms since application startup)
- QTime system_time;
-
- /// The 1ms "hardware" tick counter.
- QTimer timer;
-
- /**
- * We deliberately don't use RAII because the real hardware
- * we're simulating needs to be initialized manually.
- */
- bool initialized;
-
- /// Private ctor (singleton)
- EmulTimer() : initialized(false) { }
-
-public:
- /// Return singleton instance
- static EmulTimer &instance()
- {
- static EmulTimer et;
- return et;
- }
-
- /// Start timer emulator.
- void init()
- {
- // Timer initialized twice?
- ASSERT(!initialized);
-
- // Record initial time
- system_time.start();
-
- // Activate timer interrupt
- timer.connect(&timer, SIGNAL(timeout()), this, SLOT(timerInterrupt()));
- timer.start(1000 / TIMER_TICKS_PER_SEC);
-
- initialized = true;
- }
-
- /// Return current time in high-precision format.
- hptime_t hpread()
- {
- ASSERT(initialized);
- return system_time.elapsed();
- }
-
-public slots:
- void timerInterrupt(void)
- {
- // Just call user interrupt server, timer restarts automatically.
- timer_isr();
- }
-
-};
-
-#include "timer_qt_moc.cpp"
-
-
-/// HW dependent timer initialization.
-static void timer_hw_init(void)
-{
- // Kick EmulTimer initialization
- EmulTimer::instance().init();
-}
-
-INLINE hptime_t timer_hw_hpread(void)
-{
- return EmulTimer::instance().hpread();
-}
-
-/** Not needed, timer IRQ handler called only for timer source */
-#define timer_hw_triggered() (true)
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Low-level timer module for Qt emulator (interface).
- */
-#ifndef DRV_TIMER_QT_H
-#define DRV_TIMER_QT_H
-
-// HW dependent timer initialization
-
-#define DEFINE_TIMER_ISR void timer_isr(void)
-#define TIMER_TICKS_PER_SEC 250
-#define TIMER_HW_CNT (1<<31) /* We assume 32bit integers here */
-
-/// Type of time expressed in ticks of the hardware high-precision timer.
-typedef unsigned int hptime_t;
-
-/// Frequency of the hardware high-precision timer.
-#define TIMER_HW_HPTICKS_PER_SEC 1000
-
-/// Not needed.
-#define timer_hw_irq() do {} while (0)
-
-#endif /* DRV_TIMER_QT_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Hardware independent timer driver (implementation)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "timer.c"
-#include "mware/event.c"
-#include "os/hptime.c"
-
-static void timer_test_constants(void)
-{
- kprintf("TIMER_HW_HPTICKS_PER_SEC=%lu\n", TIMER_HW_HPTICKS_PER_SEC);
- #ifdef TIMER_PRESCALER
- kprintf("TIMER_PRESCALER=%d\n", TIMER_PRESCALER);
- #endif
- #ifdef TIMER1_OVF_COUNT
- kprintf("TIMER1_OVF_COUNT=%d\n", (int)TIMER1_OVF_COUNT);
- #endif
- kprintf("TIMER_TICKS_PER_SEC=%d\n", (int)TIMER_TICKS_PER_SEC);
- kprintf("\n");
- kprintf("ms_to_ticks(100)=%lu\n", ms_to_ticks(100));
- kprintf("ms_to_ticks(10000)=%lu\n", ms_to_ticks(10000));
- kprintf("us_to_ticks(100)=%lu\n", us_to_ticks(100));
- kprintf("us_to_ticks(10000)=%lu\n", us_to_ticks(10000));
- kprintf("\n");
- kprintf("ticks_to_ms(100)=%lu\n", ticks_to_ms(100));
- kprintf("ticks_to_ms(10000)=%lu\n", ticks_to_ms(10000));
- kprintf("ticks_to_us(100)=%lu\n", ticks_to_us(100));
- kprintf("ticks_to_us(10000)=%lu\n", ticks_to_us(10000));
- kprintf("\n");
- kprintf("hptime_to_us(100)=%lu\n", hptime_to_us(100));
- kprintf("hptime_to_us(10000)=%lu\n", hptime_to_us(10000));
- kprintf("us_to_hptime(100)=%lu\n", us_to_hptime(100));
- kprintf("us_to_hptime(10000)=%lu\n", us_to_hptime(10000));
-}
-
-static void timer_test_delay(void)
-{
- int i;
-
- kputs("Delay test\n");
- for (i = 0; i < 1000; i += 100)
- {
- kprintf("delay %d...", i);
- timer_delay(i);
- kputs("done\n");
- }
-}
-
-static void timer_test_hook(iptr_t _timer)
-{
- Timer *timer = (Timer *)(void *)_timer;
-
- kprintf("Timer %ld expired\n", ticks_to_ms(timer->_delay));
- timer_add(timer);
-}
-
-static void timer_test_async(void)
-{
- static Timer test_timers[5];
- static const mtime_t test_delays[5] = { 170, 50, 310, 1500, 310 };
- size_t i;
-
- for (i = 0; i < countof(test_timers); ++i)
- {
- Timer *timer = &test_timers[i];
- timer_setDelay(timer, ms_to_ticks(test_delays[i]));
- timer_set_event_softint(timer, timer_test_hook, (iptr_t)timer);
- timer_add(timer);
- }
-}
-
-static void timer_test_poll(void)
-{
- int secs = 0;
- mtime_t start_time = ticks_to_ms(timer_clock());
- mtime_t now;
-
- while (secs <= 10)
- {
- now = ticks_to_ms(timer_clock());
- if (now - start_time >= 1000)
- {
- ++secs;
- start_time += 1000;
- kprintf("seconds = %d, ticks=%ld\n", secs, now);
- }
- wdt_reset();
- }
-}
-
-int main(void)
-{
- wdt_init(7);
- timer_init();
- timer_test_constants();
- timer_test_delay();
- timer_test_async();
- timer_test_poll();
- return 0;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Watchdog interface
- */
-
-#ifndef DRV_WDT_H
-#define DRV_WDT_H
-
-#include <appconfig.h>
-#include <cfg/compiler.h> // INLINE
-#include <cfg/arch_config.h>
-
-/* Configury sanity check */
-#if !defined(CONFIG_WATCHDOG) || (CONFIG_WATCHDOG != 0 && CONFIG_WATCHDOG != 1)
- #error CONFIG_WATCHDOG must be defined to either 0 or 1
-#endif
-
-#if CONFIG_WATCHDOG
- #include <cpu/detect.h>
- #include <cfg/os.h>
-
- #if OS_QT
- #if _QT < 4
- #include <qapplication.h>
- #else
- #include <QtGui/QApplication>
- #endif
- #elif OS_POSIX
- #include <sys/select.h>
- #elif CPU_AVR
- #include <avr/io.h>
- #include <cfg/macros.h> // BV()
- #if CPU_AVR_ATMEGA1281 // Name is different in atmega1281
- #define WDTCR WDTCSR
- #endif
- #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
- #include <task.h> /* taskYIELD() */
- #else
- #error unknown CPU
- #endif
-#endif /* CONFIG_WATCHDOG */
-
-/**
- * Reset the watchdog timer.
- */
-INLINE void wdt_reset(void)
-{
-#if CONFIG_WATCHDOG
- #if OS_QT
- // Let Qt handle events
- ASSERT(qApp);
- qApp->processEvents();
- #elif OS_POSIX
- static struct timeval tv = { 0, 0 };
- select(0, NULL, NULL, NULL, &tv);
- #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
- vTaskDelay(1);
- #elif CPU_AVR
- __asm__ __volatile__ ("wdr");
- #else
- #error unknown CPU
- #endif
-#endif /* CONFIG_WATCHDOG */
-}
-
-/**
- * Set watchdog timer timeout.
- *
- * \param timeout 0: 16.3ms, 7: 2.1s
- */
-INLINE void wdt_init(uint8_t timeout)
-{
-#if CONFIG_WATCHDOG
- #if OS_QT
- // Create a dummy QApplication object
- if (!qApp)
- {
- int argc;
- new QApplication(argc, (char **)NULL);
- }
- (void)timeout;
- #elif OS_POSIX
- (void)timeout; // NOP
- #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
- /* nop */
- #elif CPU_AVR
- WDTCR |= BV(WDCE) | BV(WDE);
- WDTCR = timeout;
- #else
- #error unknown CPU
- #endif
-#else
- (void)timeout;
-#endif /* CONFIG_WATCHDOG */
-}
-
-INLINE void wdt_start(void)
-{
-#if CONFIG_WATCHDOG
- #if OS_QT
- // NOP
- #elif OS_POSIX
- // NOP
- #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
- /* nop */
- #elif CPU_AVR
- WDTCR |= BV(WDE);
- #else
- #error unknown CPU
- #endif
-#endif /* CONFIG_WATCHDOG */
-}
-
-INLINE void wdt_stop(void)
-{
-#if CONFIG_WATCHDOG
- #if OS_QT
- // NOP
- #elif OS_POSIX
- // NOP
- #elif defined(ARCH_FREERTOS) && (ARCH & ARCH_FREERTOS)
- /* nop */
- #elif CPU_AVR
- WDTCR |= BV(WDCE) | BV(WDE);
- WDTCR &= ~BV(WDE);
- #else
- #error unknown CPU
- #endif
-#endif /* CONFIG_WATCHDOG */
-}
-
-#endif /* DRV_WDT_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Notifier obj (implementation).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.5 2005/06/09 13:49:22 batt
- *#* Reformat; correct some comments.
- *#*
- *#* Revision 1.4 2005/06/09 13:23:58 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.3 2005/06/08 17:32:33 batt
- *#* Switch to new messaging system.
- *#*
- *#* Revision 1.2 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-
-#include <cfg/debug.h>
-
-#include <dt/dtag.h>
-#include <dt/dnotifier.h>
-#include <mware/list.h>
-
-/**
- * Default update used to notify target: notify all trasparently all
- * targets in the list.
- */
-static void notifier_update(DNotifier *n, dtag_t tag, dval_t val)
-{
- dnotify_targets(n, tag, val);
-}
-
-/**
- * Init.
- */
-void notifier_init(DNotifier *n)
-{
- // Init instance
- n->update = notifier_update;
- LIST_INIT(&n->targets);
-}
-
-/**
- * Search in the map a tag and a val corresponding to the ones supplied.
- * If a match is found change them to the corresponding ones in the map.
- * If map is NULL the filter is trasparent and all messages sent to filter
- * will be forwarded to its target.
- */
-void filter_update(DFilter *f, dtag_t tag, dval_t val)
-{
-
- const DFilterMap *map = f->map;
-
- if (map)
- {
- while (map->src.tag != TAG_END)
- {
- if ((map->src.tag == tag) && (map->src.val == val))
- {
- tag = map->dst.tag;
- val = map->dst.val;
- break;
- }
- /* TAG_ANY matches anything */
- if (map->src.tag == TAG_ANY)
- break;
- map++;
- }
-
- if (map->src.tag != TAG_END)
- dnotify(f->target, tag, val);
- }
- else
- dnotify(f->target, tag, val);
-}
-
-
-/**
- * Search in the table a tag corresponding to the one supplied and a val
- * that has at least the mask map supplied bits to one.
- * If a match is found change them to the corresponding ones in the map.
- * If map is NULL the filter is trasparent and all messages sent to filter
- * will be forwarded to its target.
- */
-void filter_mask_update(DFilter *f, dtag_t tag, dval_t val)
-{
-
- const DFilterMap *map = f->map;
- dfilter_mask_t mask;
-
- if (map)
- {
- while (map->src.tag != TAG_END)
- {
- mask = (dfilter_mask_t) map->src.val;
- if ((map->src.tag == tag) && ((mask & (dfilter_mask_t)val) == mask))
- {
- tag = map->dst.tag;
- val = map->dst.val;
- break;
- }
- /* TAG_ANY matches anything */
- if (map->src.tag == TAG_ANY)
- break;
- map++;
- }
-
-
- if (map->src.tag != TAG_END)
- dnotify(f->target, tag, val);
- }
- else
- dnotify(f->target, tag, val);
-}
-
-
-#define FILTER_MAGIC_ACTIVE 0xAA
-/**
- * Init filter.
- * If \a masked is true, all the fields value in \a map must be interpreted as a mask of bits.
- */
-void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target)
-{
- // Init instance
- if (masked)
- f->update = (update_filter_ptr)filter_mask_update;
- else
- f->update = (update_filter_ptr)filter_update;
-
- /* set filter map and target */
- f->map = map;
- f->target = target;
-
- /* these ensure that the filter is not inserted in more than one list */
- ASSERT(f->magic != FILTER_MAGIC_ACTIVE);
- DB(f->magic = FILTER_MAGIC_ACTIVE;)
-
- /* Add the filter to source filter list */
- ADDTAIL(&source->targets, &f->link);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Notifier obj (interface).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.4 2005/06/09 13:23:58 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.3 2005/06/08 17:32:33 batt
- *#* Switch to new messaging system.
- *#*
- *#* Revision 1.2 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-#ifndef DT_DNOTIFIER_H
-#define DT_DNOTIFIER_H
-
-#include <cfg/debug.h>
-#include <dt/dtag.h>
-#include <mware/list.h>
-
-//Fwd declaretion.
-struct DNotifier;
-struct DFilter;
-
-typedef void (* update_func_ptr)(struct DNotifier *, dtag_t, dval_t);
-typedef void (* update_filter_ptr)(struct DFilter *, dtag_t, dval_t);
-
-/**
- * Base object for receive and forward messages.
- * It contains an update function used to update itslef and a list to
- * notify other DNotifer eventually connected.
- */
-typedef struct DNotifier
-{
- /// Receive new attributes from other notifiers.
- update_func_ptr update;
-
- /// List of target notifiers to set new attributes to.
- List targets;
-} DNotifier;
-
-/**
- * Map for messages.
- * Used to translate src message to dst message.
- */
-typedef struct DFilterMap
-{
- DTagItem src;
- DTagItem dst;
-} DFilterMap;
-
-
-/**
- * A filter is an interface between two notifier.
- * It can translate messages between them through a map (if it is not null).
- */
-typedef struct DFilter
-{
- /// Allow creating a list of dfilter objects.
- Node link;
-
- /// Target of the filter
- DNotifier *target;
-
- /// Update function called by the source dnotifier
- update_filter_ptr update;
-
- ///Map for translating messages for target
- const DFilterMap *map;
-
- ///Used in debug to prevent inserting this filter in more than one list
- DB(uint8_t magic;)
-} DFilter;
-
-/// Type for filter-mask checking
-typedef uint16_t dfilter_mask_t;
-
-/// Filter init
-void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target);
-
-/// Filter update function without masking capabilities.
-void filter_update(DFilter *f, dtag_t tag, dval_t val);
-
-/// Filter update function with masking capabilities.
-void filter_mask_update(DFilter *f, dtag_t tag, dval_t val);
-
-/// Notifier init
-void notifier_init(DNotifier *n);
-
-
-/**
- * Macro to notify the target object.
- */
-INLINE void dnotify(DNotifier *target, dtag_t tag, dval_t val)
-{
- if (target)
- target->update(target, tag, val);
-}
-
-/**
- * Macro to notify all the targets of \a target object.
- */
-INLINE void dnotify_targets(DNotifier *target, dtag_t tag, dval_t val)
-{
- DFilter *f;
- if (!ISLISTEMPTY(&target->targets))
- FOREACHNODE(f, &target->targets)
- f->update(f, tag, val);
-}
-
-
-/**
- * Macro that connect \a src notifier to \a tgt using \a map and passing \a opt for filtering option.
- * It declares a static filter to achieve connection and messages translation.
- * \note Due its static filter declaration, DCONNECT MUST NOT be used inside loops or in functions called multiple times.
- * Failing to do so will lead to unpredictable connections between notifiers.
- */
-#define DCONNECT(src, tgt, map, opt) \
- do { \
- static DFilter _filter_; /* Declare a filter */ \
- filter_init(&(_filter_), map, opt, src, tgt); /* Init it. */ \
- } while (0)
-
-
-#endif /* DT_DNOTIFIER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Tags interface.
- * This module contains the base message definitions and the list of all available tags.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.8 2005/06/07 15:22:29 batt
- *#* Add const_dval_t.
- *#*
- *#* Revision 1.7 2005/06/06 17:42:23 batt
- *#* Add error tag TAG_ERROR.
- *#*
- *#* Revision 1.6 2005/06/06 12:45:33 batt
- *#* Add TAG_NONE tag.
- *#*
- *#* Revision 1.5 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.4 2005/05/31 11:09:52 batt
- *#* Add some tags.
- *#*
- *#* Revision 1.3 2005/05/26 14:55:12 batt
- *#* Add form_processTime; change form_kbdProcess to form_processKey.
- *#*
- *#* Revision 1.2 2005/05/26 14:43:33 batt
- *#* Add new message filter interface.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-
-#ifndef DT_DTAG_H
-#define DT_DTAG_H
-
-#include <cfg/macros.h>
-
-/** Type for values associated with tags. */
-typedef iptr_t dval_t;
-
-/** Type for constant values associated with tags. */
-typedef const_iptr_t const_dval_t;
-
-/** Type for tag */
-typedef enum dtag_t
-{
- TAG_END = 0,
- TAG_NONE,
- TAG_ANY,
- TAG_SETVALUE,
- TAG_UP,
- TAG_DOWN,
- TAG_START,
- TAG_STOP,
- TAG_TOGGLE,
- TAG_KEY,
- TAG_TIME,
- TAG_ERROR,
-} dtag_t;
-
-/** This is the basic message structure used by all dnotifiers. */
-typedef struct DTagItem
-{
- dtag_t tag;
- dval_t val;
-} DTagItem;
-
-/** Marker to indicate the end of a map for message filtering/translating */
-#define TAG_END_MARKER {{TAG_END, 0}, {TAG_END, 0}}
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Widget (implementation).
- * A widget is typically a graphic object on a device.
- * Its proproperties are the position, the size and a context on which the widget is drawn.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@ðeveler.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.3 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.2 2005/05/26 14:44:10 batt
- *#* Abstract widget from layer: use context.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-
-#include <dt/dwidget.h>
-#include <dt/dnotifier.h>
-
-/**
- * Init the widget of \a pos and \a size on the drawing \a context.
- */
-void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context)
-{
- // Init superclass
- notifier_init(&w->notifier);
-
- // Init instance
- w->pos = pos;
- w->size = size;
- w->context = context;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Widget (interface).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.3 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.2 2005/05/26 14:44:10 batt
- *#* Abstract widget from layer: use context.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-
-#ifndef DT_DWIDGET_H
-#define DT_DWIDGET_H
-
-#include <dt/dnotifier.h>
-#include <cfg/compiler.h>
-
-/** Widget position. */
-typedef uint8_t dpos_t;
-
-/** Widget drawing context. */
-typedef iptr_t dcontext_t;
-
-/** Widget definition. */
-typedef struct DWidget
-{
- DNotifier notifier;
-
- dpos_t pos;
- dpos_t size;
- dcontext_t *context;
-} DWidget;
-
-
-void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context);
-
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Edit bool widget (implementation).
- * This widget handles boolean editing.
- * The boolean value will be displayed using two strings:
- * one when the bool is false and one when it's true.
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@ðeveler.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.3 2005/06/08 17:32:33 batt
- *#* Switch to new messaging system.
- *#*
- *#* Revision 1.2 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.1 2005/05/31 11:11:37 batt
- *#* Edit bool: first release.
- *#*
- *#*/
-
-#include <mware/editbool.h>
-#include <dt/dtag.h>
-
-#include <drv/lcd_text.h>
-
-/**
- * Init widget.
- */
-void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *value, const char *true_string, const char *false_string)
-{
- // Initialize superclass
- widget_init(&e->widget, pos, size, context);
-
- // Override superclass methods
- e->widget.notifier.update = (update_func_ptr)editbool_update;
-
- // Init instance
- e->value = value;
- e->true_string = true_string;
- e->false_string = false_string;
- e->draw = editbool_draw;
-}
-
-/**
- * Handle the messages (edit the bool).
- */
-void editbool_update(DEditBool *e, dtag_t tag, dval_t _val)
-{
- bool changed = false;
-
- switch (tag)
- {
- case TAG_SETVALUE:
- *e->value = (bool)_val;
- changed = true;
- break;
-
- case TAG_TOGGLE:
- *e->value = !*e->value;
- changed = true;
- break;
- default:
- break;
- }
-
- if (changed)
- {
- e->draw(e);
- dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value);
- }
-}
-
-/**
- * Draw the string on the context.
- */
-void editbool_draw(DEditBool *e)
-{
- lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL, "%*s", (int)e->widget.size , *e->value? e->true_string: e->false_string);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Edit bool widget (interface).
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.2 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.1 2005/05/31 11:11:37 batt
- *#* Edit bool: first release.
- *#*
- *#*/
-
-#ifndef DT_EDITBOOL_H
-#define DT_EDITBOOL_H
-
-#include <dt/dwidget.h>
-#include <dt/dtag.h>
-
-typedef struct DEditBool
-{
- DWidget widget;
- bool *value;
- const char *true_string;
- const char *false_string;
- void (*draw)(struct DEditBool *);
-} DEditBool;
-
-void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *val, const char *true_str, const char *false_str);
-void editbool_update(DEditBool *e, dtag_t tag, dval_t val);
-void editbool_draw(DEditBool *e);
-
-
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Integer edit widget (implementation).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.7 2005/06/10 15:46:09 batt
- *#* Add EDIS_WRAP style that wrap around min and max.
- *#*
- *#* Revision 1.6 2005/06/08 17:32:33 batt
- *#* Switch to new messaging system.
- *#*
- *#* Revision 1.5 2005/06/06 11:04:12 batt
- *#* Add some comments.
- *#*
- *#* Revision 1.4 2005/05/31 11:09:34 batt
- *#* Fix sending pointer instead of value bug.
- *#*
- *#* Revision 1.3 2005/05/26 14:46:20 batt
- *#* Use correct tag; remove warning.
- *#*
- *#* Revision 1.2 2005/05/26 14:44:10 batt
- *#* Abstract widget from layer: use context.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-
-#include <mware/editint.h>
-#include <dt/dwidget.h>
-#include <dt/dtag.h>
-#include <dt/dnotifier.h>
-
-#include <cfg/macros.h>
-
-#include <drv/lcd_text.h>
-
-/**
- * Init.
- */
-void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max)
-{
- // Initialize superclass
- widget_init(&e->widget, pos, size, context);
-
- // Override superclass methods
- e->widget.notifier.update = (update_func_ptr)editint_update;
-
- // Init instance
- e->value = value;
- e->min = min;
- e->max = max;
- e->style = EDIS_DEFAULT;
- e->draw = editint_draw;
-}
-
-/**
- * Handle the messages (edit the int).
- */
-void editint_update(DEditInt *e, dtag_t tag, dval_t _val)
-{
- bool changed = false;
- int val = (int)_val;
-
- switch (tag)
- {
- case TAG_SETVALUE:
- *e->value = MINMAX(e->min, val, e->max);
- changed = true;
- break;
-
- /* Increments the integer by val */
- case TAG_UP:
- if (e->style & EDIS_WRAP)
- {
- if (*e->value + val > e->max)
- *e->value = (*e->value + val - e->min) % (e->max - e->min + 1) + e->min;
- else
- *e->value += val;
- }
- else
- *e->value = MIN(*e->value + val, e->max);
- changed = true;
- break;
- /* Decrements the integer by val */
- case TAG_DOWN:
- if (e->style & EDIS_WRAP)
- {
- if (*e->value - val < e->min)
- *e->value = e->max - (e->max - (*e->value - val)) % (e->max - e->min + 1);
- else
- *e->value -= val;
- }
- else
- *e->value = MAX(*e->value - val, e->min);
- changed = true;
- break;
-
- default:
- break;
- }
-
- if (changed)
- {
- e->draw(e);
- dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value);
- }
-}
-
-/**
- * Draw the integer on the context.
- */
-void editint_draw(DEditInt *e)
-{
- lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL,"%*d", (int)e->widget.size, *e->value);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief Integer edit (interface).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/11/04 18:26:38 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.3 2005/06/10 15:46:09 batt
- *#* Add EDIS_WRAP style that wrap around min and max.
- *#*
- *#* Revision 1.2 2005/05/26 14:44:10 batt
- *#* Abstract widget from layer: use context.
- *#*
- *#* Revision 1.1 2005/05/26 08:32:53 batt
- *#* Add new Develer widget system :)
- *#*
- *#*/
-
-#ifndef DT_EDITINT_H
-#define DT_EDITINT_H
-
-#include <dt/dwidget.h>
-#include <dt/dtag.h>
-#include <drv/lcd_text.h>
-
-#include <cfg/compiler.h>
-#include <cfg/macros.h>
-
-
-#define EDIS_DEFAULT 0
-#define EDIS_CURSORLEFT BV(0)
-#define EDIS_WRAP BV(1)
-
-/** Type for edit style */
-typedef uint16_t dstyle_t;
-
-typedef struct DEditInt
-{
- DWidget widget;
-
- int *value;
- int min;
- int max;
- dstyle_t style;
- void (*draw)(struct DEditInt *);
-
-} DEditInt;
-
-void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max);
-void editint_update(DEditInt *e, dtag_t tag, dval_t val);
-void editint_draw(DEditInt *e);
-
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Qt-based emulator framework for embedded applications (implementation)
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.6 2006/05/28 12:17:57 bernie
- *#* Drop almost all the Qt3 cruft.
- *#*
- *#* Revision 1.5 2006/05/27 22:30:56 bernie
- *#* Add some delay to slow things down.
- *#*
- *#* Revision 1.4 2006/02/24 01:35:40 bernie
- *#* Update for new emulator.
- *#*
- *#* Revision 1.3 2006/02/20 02:00:40 bernie
- *#* Port to Qt 4.1.
- *#*
- *#* Revision 1.2 2006/01/16 03:51:51 bernie
- *#* Fix boilerplate.
- *#*
- *#* Revision 1.1 2006/01/16 03:37:12 bernie
- *#* Add emulator skeleton.
- *#*
- *#*/
-
-#include "emul.h"
-#include "emulwin.h"
-#include <cfg/module.h>
-
-#include <appconfig.h>
-#if CONFIG_KERNEL
- #include <config_kern.h>
-#endif
-
-
-#include <cstdlib> // std::exit()
-
-#include <QtGui/qapplication.h>
-
-
-/// The global emulator instance.
-Emulator *emul;
-
-#if CONFIG_KERNEL
- #include <mware/list.h>
-
- /// List of process stacks
- List StackFreeList;
-
- // HACK: Reserve 64KB of stack space for kernel processes
- const int NPROC = 8;
- int stacks[NPROC][(64 * 1024) / sizeof(int)];
-#endif
-
-Emulator::Emulator(int &argc, char **argv) :
- emulApp(new QApplication(argc, argv)),
- emulWin(new EmulWin(this))
-{
- emulWin->show();
-}
-
-
-Emulator::~Emulator()
-{
- // we don't delete emulWin because it automatically
- // deletes itself when closed
- delete emulApp;
-}
-
-
-NORETURN void Emulator::quit()
-{
- // WHAT A KLUDGE!
- this->~Emulator();
- emul = NULL;
-
- // do we have a better way to shut down the emulation?
- exit(0);
-}
-
-MOD_DEFINE(emul)
-
-/// Main emulator entry point.
-extern "C" void emul_init(int *argc, char *argv[])
-{
- // setup global emulator pointer
- emul = new Emulator(*argc, argv);
-
-#if CONFIG_KERNEL
- LIST_INIT(&StackFreeList);
- for (int i = 0; i < NPROC; i++)
- ADDTAIL(&StackFreeList, (Node *)stacks[i]);
-#endif
-
- MOD_INIT(emul);
-}
-
-extern "C" void emul_cleanup()
-{
- MOD_CLEANUP(emul);
-
- delete emul;
- emul = NULL;
-}
-
-extern "C" void emul_idle()
-{
- // We process GUI events when the application is idle.
- emul->emulApp->processEvents();
- usleep(1000);
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Qt-based emulator framework for embedded applications (interface)
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/02/15 09:11:17 bernie
- *#* Add keyboard emulator.
- *#*
- *#* Revision 1.3 2006/01/23 23:12:08 bernie
- *#* Let Doxygen see through C++ protected section.
- *#*
- *#* Revision 1.2 2006/01/16 03:51:51 bernie
- *#* Fix boilerplate.
- *#*
- *#* Revision 1.1 2006/01/16 03:37:12 bernie
- *#* Add emulator skeleton.
- *#*
- *#*/
-
-#ifndef EMUL_EMUL_H
-#define EMUL_EMUL_H
-
-#include <cfg/compiler.h>
-
-#if defined(__cplusplus) || defined(__doxygen__)
-
-// fwd decls
-class QApplication;
-class EmulWin;
-class EmulPRT;
-class EmulLCD;
-class EmulKbd;
-class QCheckBox;
-class QSlider;
-class QLabel;
-
-class Emulator
-{
-// data members
-public:
- QApplication *emulApp; ///< QT Application.
- EmulWin *emulWin; ///< Main window.
-
- EmulLCD *emulLCD; ///< Display emulator.
- EmulKbd *emulKbd; ///< Keyboard emulator.
-
-// construction
- Emulator(int &argc, char **argv);
- ~Emulator();
-
-// public methods
- void quit();
-};
-
-extern Emulator *emul;
-
-#endif /* __cplusplus */
-
-EXTERN_C void emul_init(int *argc, char *argv[]);
-EXTERN_C void emul_cleanup();
-EXTERN_C void emul_idle();
-
-#endif /* EMUL_EMUL_H */
-
+++ /dev/null
-#
-# Copyright 2007 Bernardo Innocenti (http://www.codewiz.org/)
-# All rights reserved.
-#
-# Author: Bernardo Innocenti <bernie@develer.com>
-#
-# Qt configuration for devlib emulator demo. Include it from
-# your app Makefile fragment
-
-EMUL_CFLAGS = $(shell pkg-config QtCore QtGui --cflags) -DQT_CLEAN_NAMESPACE -DQT3_SUPPORT
-EMUL_LDFLAGS = $(shell pkg-config QtCore QtGui --libs)
-QT_MOC = $(shell pkg-config QtCore --variable=moc_location)
-#QT_UIC = $(shell pkg-config QtCore --variable=uic_location)
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief QT-based widget for keyboard emulation (implementation)
- */
-
-#include "emulkbd.h"
-#include "emul.h"
-
-#include <QtGui/QPainter>
-#include <QtGui/QPixmap>
-#include <QtGui/QSizePolicy>
-#include <QtGui/QLayout>
-#include <QtGui/QKeyEvent>
-#include <QtCore/QEvent>
-#include <QtCore/QSize>
-#include <QtCore/QRect>
-
-
-EmulKey::EmulKey(EmulKbd *kbd, const char *label, int _keycode, int _row, int _col) :
- QPushButton(label, kbd),
- row(_row), col(_col),
- keycode(_keycode)
-{
- // don't let the widget get focus
- setFocusPolicy(Qt::NoFocus);
-
- // unused
- connect(this, SIGNAL(pressed()), this, SLOT(keyPressed()));
- connect(this, SIGNAL(released()), this, SLOT(keyReleased()));
-}
-
-
-EmulKey::~EmulKey()
-{
- // nop
-}
-
-
-/**
- * Override standad QButton behaviour: we must also emit the signals.
- */
-// unused
-void EmulKey::setDown(bool enable)
-{
- // let our superclass do everything else
- QPushButton::setDown(enable);
-
- if (enable)
- emit pressed();
- else
- emit released();
-}
-
-
-// unused
-void EmulKey::keyPressed(void)
-{
- static_cast<EmulKbd *>(parent())->setKey(row, col, true);
-}
-
-
-// unused
-void EmulKey::keyReleased(void)
-{
- static_cast<EmulKbd *>(parent())->setKey(row, col, false);
-}
-
-
-EmulKbd::EmulKbd(QWidget *parent, Qt::WFlags f) :
- QFrame(parent, f),
- layout(new QGridLayout(this)),
- active_row(0)
-{
- setFrameStyle(QFrame::Box | QFrame::Sunken);
- setLineWidth(1);
- setFocusPolicy(Qt::StrongFocus);
- frame_width = frameWidth();
-}
-
-
-EmulKbd::~EmulKbd()
-{
- delete layout;
-}
-
-
-QSizePolicy EmulKbd::sizePolicy() const
-{
- return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-}
-
-
-void EmulKbd::resizeEvent(QResizeEvent *event)
-{
- // Let our superclass process the event first
- QFrame::resizeEvent(event);
-}
-
-
-// handle key presses for all keys in keyboard
-bool EmulKbd::event(QEvent *_e)
-{
- switch (_e->type())
- {
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- {
- QKeyEvent *e = static_cast<QKeyEvent *>(_e);
- int keycode = e->key();
- EmulKey *key;
-
- // ignore repeated keys
- if (!e->isAutoRepeat())
- {
- // scan all children
- for (QObjectList::const_iterator it(children().begin()); it != children().end(); ++it)
- {
- // only keys, not other children!
- if ((*it)->metaObject() == &EmulKey::staticMetaObject)
- // if ((key = dynamic_cast<EmulKey *>(*it)))
- {
- key = static_cast<EmulKey *>(*it);
-
- // same key?
- if (key->keycode == keycode)
- {
- // yes, tell key to go down (or up)
- key->setDown(_e->type() == QEvent::KeyPress);
- break;
- }
- }
- }
- }
- return true;
- }
-
- default:
- // let superclass process this event
- return QFrame::event(_e);
-
- } // end switch(_e->type())
-}
-
-
-void EmulKbd::addKey(const char *label, int keycode, int row, int col, int matrix_row, int matrix_col)
-{
- if (matrix_row == -1)
- matrix_row = row;
- if (matrix_col == -1)
- matrix_col = col;
-
- layout->addWidget(new EmulKey(this, label, keycode, matrix_row, matrix_col), row, col);
-}
-
-
-// unused
-void EmulKbd::setKey(int /*row*/, int /*col*/, bool /*on*/)
-{
-}
-
-
-void EmulKbd::setRow(int r)
-{
- active_row = r;
-}
-
-int EmulKbd::readCols(void)
-{
- QLayoutItem *item;
- EmulKey *key;
- int cols = 0;
-
- // FIXME: QLayoutIterator is obsolete in Qt4
- for(QLayoutIterator it(layout->iterator()); (item = it.current()); ++it)
- {
- key = static_cast<EmulKey *>(item->widget());
- if (key->row == active_row)
- {
- if (key->isDown())
- cols |= (1<<key->col);
- }
- }
- return cols;
-}
-
-extern "C" void emul_kbdSetRows(int r)
-{
- emul->emulKbd->setRow(r);
-}
-
-
-extern "C" int emul_kbdReadCols(void)
-{
- return emul->emulKbd->readCols();
-}
-
-#include "emulkbd_moc.cpp"
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief QT-based widget for leyboard emulation (interface)
- */
-
-#if !defined(EMULKBD_H)
-#define EMULKBD_H
-
-#if defined (_MSC_VER) && (_MSC_VER > 1000)
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include <QtGui/QFrame>
-
-// fwd decl
-class QGridLayout;
-class EmulKey;
-
-class EmulKbd : public QFrame
-{
- Q_OBJECT
-
-// Data members
-protected:
- QGridLayout *layout;
- int frame_width;
- int active_row;
-
-// Construction
-public:
- EmulKbd(QWidget *parent = 0, Qt::WFlags f = 0);
- virtual ~EmulKbd();
-
-// Public methods
- void addKey(const char *label, int keycode, int row, int col, int matrix_row = -1, int matrix_col = -1);
- void setRow(int row);
- int readCols(void);
-
-// Protected methods
-protected:
- void setKey(int row, int col, bool on);
-
-// Base class overrides
-protected:
- virtual QSizePolicy sizePolicy() const;
- virtual void resizeEvent(QResizeEvent *e);
- virtual bool event(QEvent *e);
-
-// Friends
- friend class EmulKey;
-};
-
-
-// Private helper class for EmulKbd
-// NOTE: with protected inheritance, dynamic_cast<> does not work (gcc 2.96)
-#include <QtGui/qpushbutton.h>
-class EmulKey : public QPushButton
-{
- Q_OBJECT
-
-// Data members
-protected:
- int row, col;
- int keycode;
-
-// Construction
-public:
- EmulKey(EmulKbd *parent, const char *label, int keycode, int _row, int _col);
- virtual ~EmulKey();
-
-// superclass overrides
- void setDown(bool enable);
-
-protected slots:
- void keyPressed(void);
- void keyReleased(void);
-
-// Friends
-public:
- friend class EmulKbd;
-};
-
-#endif // !defined(EMULKBD_H)
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Main Qt window for embedded applications emulator (implementation)
- */
-
-#include "emulwin.h"
-
-#include <drv/lcd_gfx_qt.h>
-#include <emul/emul.h>
-#include <emul/emulkbd.h>
-
-#include <cassert>
-
-#include <QtGui/QLayout>
-#include <QtGui/QLabel>
-#include <QtGui/QSlider>
-#include <QtGui/QCheckBox>
-#include <QtGui/QMenuBar>
-#include <QtGui/QMessageBox>
-#include <QtCore/QDateTime>
-#include <QtCore/QTimer>
-#include <QtGui/QApplication>
-#include <QtGui/QCloseEvent>
-using namespace Qt;
-
-EmulWin::EmulWin(Emulator *e)
-{
- setWindowTitle(tr("BeRTOS Emul Demo"));
- setAttribute(Qt::WA_DeleteOnClose);
-
- // Create the menu bar
- QMenu *file_menu = menuBar()->addMenu(tr("&File"));
- file_menu->addAction(tr("&Quit"),
- e->emulApp, SLOT(closeAllWindows()), CTRL+Key_Q);
-
- menuBar()->addSeparator();
-
- QMenu *help_menu = menuBar()->addMenu(tr("&Help"));
- help_menu->addAction(tr("&About"),
- this, SLOT(about()), Key_F1);
-
- // Make a central widget to contain the other widgets
- QWidget *central = new QWidget(this);
- setCentralWidget(central);
-
- // Create a layout to position the widgets
- QHBoxLayout *box_main = new QHBoxLayout(central);
-
- // Main layout
- QVBoxLayout *box_right = new QVBoxLayout();
- box_main->addLayout(box_right);
-
- // LCD
- QHBoxLayout *lay_lcd = new QHBoxLayout();
- box_right->addLayout(lay_lcd);
- lay_lcd->addStretch();
- lay_lcd->addWidget(e->emulLCD = new EmulLCD(central));
- lay_lcd->addStretch();
-
- // Keyboard
- box_right->addWidget(e->emulKbd = new EmulKbd(central));
-
- // Setup keyboard: Label Keycode Row Col MRow MCol
- e->emulKbd->addKey("^", Key_Up, 0, 0, 0, 0);
- e->emulKbd->addKey("v", Key_Down, 1, 0, 0, 1);
- e->emulKbd->addKey("OK", Key_Return, 0, 1, 0, 2);
- e->emulKbd->addKey("ESC", Key_Escape, 1, 1, 0, 3);
-}
-
-
-EmulWin::~EmulWin()
-{
- emul->quit();
-}
-
-
-void EmulWin::closeEvent(QCloseEvent *ce)
-{
- emul->quit();
- ce->accept();
-}
-
-
-void EmulWin::about()
-{
- QMessageBox::about(this,
- "BeRTOS Embedded Application Emulator",
- "Version 0.1\n"
- "Copyright 2006, 2008 Develer S.r.l. (http://www.develer.com/)\n"
- "Copyright 2001, 2002, 2003, 2005 Bernardo Innocenti <bernie@codewiz.org>\n"
- "All rights reserved."
- );
-}
-
-#include "emulwin_moc.cpp"
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000, 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Main Qt window for embedded applications emulator (interface)
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/05/28 12:17:56 bernie
- *#* Drop almost all the Qt3 cruft.
- *#*
- *#* Revision 1.3 2006/02/20 02:00:39 bernie
- *#* Port to Qt 4.1.
- *#*
- *#* Revision 1.2 2006/01/16 03:51:51 bernie
- *#* Fix boilerplate.
- *#*
- *#* Revision 1.1 2006/01/16 03:37:12 bernie
- *#* Add emulator skeleton.
- *#*
- *#*/
-
-#ifndef EMUL_EMULWIN_H
-#define EMUL_EMULWIN_H
-
-#include <QtGui/QMainWindow>
-
-// fwd decls
-class Emulator;
-
-class EmulWin : public QMainWindow
-{
- Q_OBJECT
-
-// construction
-public:
- EmulWin(Emulator *emul);
- ~EmulWin();
-
-protected:
- void closeEvent(QCloseEvent *);
-
-private slots:
- void about();
-};
-
-#endif // EMUL_EMULWIN_H
-
+++ /dev/null
-#! /usr/bin/perl -w
-#
-# Convert BDF files to nano-X font files
-# modified by G Haerr from bdftobogl for 16 bit MWIMAGEBITS
-# modified on 2/10/00 by K Harris to accept any size input character
-# modified on 3/26/00 by G Haerr added ascent field, fixed $IMAGE_BITS
-# modified on 2/15/06 by <bernie@develer.com> for DevLib.
-# originally from BOGL - Ben's Own Graphics Library <pfaffben@debian.org>.
-#
-
-use POSIX;
-
-if ($#ARGV < 0) {
- print "Usage: convbdf font.bdf > font.c\n";
- exit -1;
-}
-
-$LAST_CHAR = 0xff;
-$IMAGE_BITS = 8;
-$IMAGE_NIBBLES = $IMAGE_BITS/4;
-$IMAGE_MASK = 0xff;
-$IMAGE_VERTICAL = 1;
-
-$file = $ARGV[0];
-
-$font = $file;
-$font =~ s#.*/##; # remove path name
-$font =~ s/\.bdf//;
-$font =~ tr/a-zA-Z0-9_/_/cs;
-
-print "/* Generated by convbdf on ", substr(`date`, 0, -1), ". */\n";
-print "#include <gfx/font.h>\n\n";
-
-open BDF, "<$file" || die;
-while (<BDF>) {
- chop;
- $pixel_size = $1 if /^PIXEL_SIZE (\d+)$/;
- $font_ascent = $1 if /^FONT_ASCENT (\d+)$/;
- $font_descent = $1 if /^FONT_DESCENT (\d+)$/;
- $font_name = $1 if /^FONT (.*)$/;
- $default_char = $1 if /^DEFAULT_CHAR (\d+)$/;
-
- last if /^CHARS /;
-}
-
-print "/* Font information:\n\n";
-print " name: $font_name\n";
-print " pixel size: $pixel_size\n";
-print " ascent: $font_ascent\n";
-print " descent: $font_descent\n";
-print "*/\n\n";
-
-print "/* Font character bitmap data. */\n";
-print "static const PROGMEM uint8_t font_${font}_glyphs[] = {\n";
-
-$ch_height = $font_ascent + $font_descent;
-$ofs = 0;
-$maxwidth = 0;
-$proportional = 0;
-$firstchar = -1;
-while (<BDF>) {
- chop;
- undef $encoding, undef $width, undef $bbx, undef $bby, undef $bbw, undef $bbh if /^STARTCHAR /;
- $encoding = $1 if /^ENCODING (\d+)/;
- last if defined $encoding && $encoding > $LAST_CHAR;
- $width = $1 if /^DWIDTH (-?\d+)/;
- ($bbw, $bbh, $bbx, $bby) = ($1, $2, $3, $4) if /^BBX (-?\d+) (-?\d+) (-?\d+) (-?\d+)/;
-
- if (/^BITMAP$/) {
- next if !defined $encoding;
- $firstchar = $encoding if $firstchar < 0;
- $encoding_tab[$encoding] = $ofs;
- $width -= $bbx, $bbx = 0 if $bbx < 0;
- $width[$encoding] = $width;
- $maxwidth != 0 and $width != $maxwidth and $proportional = 1;
- $maxwidth = $width if $width > $maxwidth;
- $ch_words = int (($width+$IMAGE_BITS-1)/$IMAGE_BITS);
- $ch_bits = $ch_words*$IMAGE_BITS;
- for (my $i = 0; $i < $ch_height; $i++) {
- for (my $k = 0; $k < $ch_words; $k++) {
- $bm[$i][$k] = 0;
- }
- }
- for (my $i = 0; ; $i++) {
- $_ = <BDF>;
- chop;
- last if /^ENDCHAR$/;
-
- @hexnibbles = split //,$_;
- for (my $k=0; $k<$ch_words; $k++) {
- $ndx = $k*$IMAGE_NIBBLES;
- $padnibbles = @hexnibbles - $ndx;
- # if bbx pushes bits into next word
- # and no more bits from bdf file
- last if $padnibbles <= 0;
- $padnibbles = 0 if $padnibbles >= $IMAGE_NIBBLES;
- $value = hex join '',@hexnibbles[$ndx..($ndx+$IMAGE_NIBBLES-1-$padnibbles)];
- $value = $value << ($padnibbles*$IMAGE_NIBBLES);
- $bm[$ch_height - $font_descent - $bby - $bbh + $i][$k] |=
- $value >> ($bbx);
- if ($bbx) { # handle overflow into next image_word
- $bm[$ch_height - $font_descent - $bby - $bbh + $i][$k+1] =
- ($value << ($IMAGE_BITS - $bbx)) & $IMAGE_MASK;
- }
- }
- }
-
- # GLYPH PREVIEW
-### printf "\n/* Character %c (0x%02x): ", $encoding, $encoding;
- printf "\n/* Character (0x%02x): ", $encoding;
- print "bbw=$bbw, bbh=$bbh, bbx=$bbx, bby=$bby, width=$width */\n";
-
- # GLYPH DATA
- if ($IMAGE_VERTICAL) {
- my $bitstring = "";
- for (my $k = 0; $k < int(($ch_height + $IMAGE_BITS - 1) / $IMAGE_BITS); $k++) {
- for (my $x = 0; $x < $width; $x++) {
- my $v = 0;
- for (my $y = 0; $y < $IMAGE_BITS && ($y + $k * $IMAGE_BITS < $ch_height); ++$y) {
- my $bit = ($bm[$k * $IMAGE_BITS + $y][int($x / $IMAGE_BITS)] & (1 << ($IMAGE_BITS - ($x % $IMAGE_BITS) - 1))) ? 1 : 0;
- $bitstring .= $bit ? '*' : ' ';
- $v |= $bit << $y;
- }
- $ofs++;
- printf "0x%02x, ", $v;
- }
- # Preview
- printf "/* $bitstring */\n";
- }
-
- }
- else { # IMAGE_HORIZONTAL
-
- # Preview
- print " +", ("-" x $ch_bits), "+\n";
- for (my $i = 0; $i < $ch_height; $i++) {
- print " |";
- for (my $k = 0; $k < $ch_words; $k++) {
- for (my $j = $IMAGE_BITS - 1; $j >= 0; $j--) {
- print $bm[$i][$k] & (1 << $j) ? "*" : " ";
- }
- }
- print "|\n";
- }
- print " +", ("-" x $ch_bits), "+ */\n";
-
- for (my $i = 0; $i < $ch_height; $i++) {
- for (my $k=0; $k<$ch_words; $k++) {
- $ofs++;
- printf "0x%02x, ", $bm[$i][$k];
- }
- printf "\n";
- }
- }
- }
-}
-
-print "};\n\n";
-
-#print STDERR "Maximum character width=$maxwidth\n";
-
-if ($proportional) {
- print "/* Character->glyph data. */\n";
- print "static const PROGMEM uint16_t ${font}_offset[] = {\n";
- for (my $i = $firstchar; $i <= $LAST_CHAR; $i++) {
- my $char = $i;
- my $ofs = $encoding_tab[$i];
- $ofs = $encoding_tab[$default_char], $char = $default_char if !defined $ofs;
- ### printf " $ofs,\t/* %c (0x%02x) */\n", $char, $i;
- printf " $ofs,\t/* (0x%02x) */\n", $i;
- }
- print "};\n\n";
-
- print "/* Character width data. */\n";
- print "static const PROGMEM uint8_t ${font}_width[] = {\n";
- for (my $i = $firstchar; $i <= $LAST_CHAR; $i++) {
- my $char = $i;
- my $width = $width[$i];
- $width = $width[$default_char], $char = $default_char if !defined $encoding_tab[$i];
- ### printf " $width,\t/* %c (0x%02x) */\n", $char, $i;
- printf " $width,\t/* (0x%02x) */\n", $i;
- }
- print "};\n\n";
-
- $font_offset = "${font}_offset";
- $font_width = "${font}_width";
-} else {
- $font_offset = "NULL";
- $font_width = "NULL";
-}
-
-$lastchar = $LAST_CHAR;
-#$size = $lastchar - $firstchar + 1;
-
-print <<EOF
-/* Font structure definition. */
-EXTERN_CONST Font font_${font} =
-{
- /* .glyph = */ font_${font}_glyphs,
- /* .name = "$font", */
- /* .width = */ $maxwidth,
- /* .height = */ $ch_height,
- /* .ascent = $font_ascent, */
- /* .first = */ $firstchar,
- /* .last = */ $lastchar,
- /* .offset = */ $font_offset,
- /* .width = */ $font_width,
-};
-EOF
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Font 8x6 IBM-PC 8bit
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2006/05/27 22:30:22 bernie
- *#* Move 6x8 font to fonts/.
- *#*
- *#* Revision 1.3 2006/02/10 12:29:05 bernie
- *#* Add multiple font support in bitmaps.
- *#*
- *#* Revision 1.2 2005/11/04 18:17:45 bernie
- *#* Fix header guards and includes for new location of gfx module.
- *#*
- *#* Revision 1.1 2005/11/04 18:11:35 bernie
- *#* Move graphics stuff from mware/ to gfx/.
- *#*
- *#* Revision 1.6 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.5 2005/01/08 09:20:38 bernie
- *#* Add missing type in declaration.
- *#*
- *#* Revision 1.4 2004/12/31 16:42:55 bernie
- *#* Sanitize for non-Harvard processors.
- *#*
- *#* Revision 1.3 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 15:43:16 bernie
- *#* Import mware modules.
- *#*/
-
-#include "font.h"
-
-static const PROGMEM uint8_t default_font_glyphs[256 * 6] =
-{
-/* 0x00 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
- 0x3E, 0x45, 0x51, 0x45, 0x3E, 0x00, /* */
- 0x3E, 0x7B, 0x6F, 0x7B, 0x3E, 0x00, /* */
- 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, /* */
- 0x08, 0x1C, 0x3E, 0x1C, 0x08, 0x00, /* */
- 0x18, 0x5A, 0x67, 0x5A, 0x18, 0x00, /* */
- 0x0C, 0x5E, 0x6F, 0x5E, 0x0C, 0x00, /* */
- 0x08, 0x1C, 0x3E, 0x1C, 0x08, 0x00, /* */
-/* 0x08 */
- 0x77, 0x63, 0x41, 0x63, 0x77, 0x00, /* */
- 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00, /* */
- 0x77, 0x63, 0x41, 0x63, 0x77, 0x00, /* */
- 0x20, 0x50, 0x5A, 0x56, 0x2E, 0x00, /* */
- 0x06, 0x29, 0x79, 0x29, 0x06, 0x00, /* */
- 0x60, 0x60, 0x7F, 0x05, 0x07, 0x00, /* */
- 0x18, 0x1F, 0x01, 0x61, 0x7F, 0x00, /* */
- 0x15, 0x0E, 0x1B, 0x0E, 0x15, 0x00, /* */
-/* 0x10 */
- 0x00, 0x08, 0x1C, 0x3E, 0x08, 0x08, /* */
- 0x7F, 0x3E, 0x1C, 0x08, 0x00, 0x00, /* */
- 0x14, 0x36, 0x7F, 0x36, 0x14, 0x00, /* */
- 0x00, 0x5F, 0x00, 0x5F, 0x00, 0x00, /* */
- 0x02, 0x05, 0x7F, 0x01, 0x7F, 0x00, /* */
- 0x20, 0x4A, 0x55, 0x29, 0x02, 0x00, /* */
- 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, /* */
- 0x54, 0x76, 0x7F, 0x76, 0x54, 0x00, /* */
-/* 0x18 */
- 0x08, 0x0C, 0x7E, 0x0C, 0x08, 0x00, /* */
- 0x10, 0x30, 0x7E, 0x30, 0x10, 0x00, /* */
- 0x08, 0x08, 0x3E, 0x1C, 0x08, 0x00, /* */
- 0x08, 0x1C, 0x3E, 0x08, 0x08, 0x00, /* */
- 0x1C, 0x10, 0x10, 0x10, 0x10, 0x00, /* */
- 0x08, 0x1C, 0x08, 0x1C, 0x08, 0x00, /* */
- 0x18, 0x1C, 0x1E, 0x1C, 0x18, 0x00, /* */
- 0x0C, 0x1C, 0x3C, 0x1C, 0x0C, 0x00, /* */
-/* 0x20 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
- 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, /* ! */
- 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, /* " */
- 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, /* # */
- 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, /* $ */
- 0x63, 0x13, 0x08, 0x64, 0x63, 0x00, /* % */
- 0x36, 0x49, 0x55, 0x22, 0x50, 0x00, /* & */
- 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, /* ' */
-/* 0x28 */
- 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, /* ( */
- 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, /* ) */
- 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00, /* * */
- 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, /* + */
- 0x00, 0x50, 0x30, 0x00, 0x00, 0x00, /* , */
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /* - */
- 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, /* . */
- 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, /* / */
-/* 0x30 */
- 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, /* 0 */
- 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, /* 1 */
- 0x62, 0x51, 0x49, 0x49, 0x46, 0x00, /* 2 */
- 0x21, 0x41, 0x45, 0x4B, 0x31, 0x00, /* 3 */
- 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, /* 4 */
- 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, /* 5 */
- 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00, /* 6 */
- 0x01, 0x71, 0x09, 0x05, 0x03, 0x00, /* 7 */
-/* 0x38 */
- 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, /* 8 */
- 0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, /* 9 */
- 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, /* : */
- 0x00, 0x56, 0x36, 0x00, 0x00, 0x00, /* ; */
- 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, /* < */
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, /* = */
- 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, /* > */
- 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, /* ? */
-/* 0x40 */
- 0x32, 0x49, 0x79, 0x41, 0x3E, 0x00, /* @ */
- 0x7E, 0x09, 0x09, 0x09, 0x7E, 0x00, /* A */
- 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, /* B */
- 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, /* C */
- 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00, /* D */
- 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, /* E */
- 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, /* F */
- 0x3E, 0x41, 0x49, 0x49, 0x7A, 0x00, /* G */
-/* 0x48 */
- 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, /* H */
- 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, /* I */
- 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, /* J */
- 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, /* K */
- 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, /* L */
- 0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x00, /* M */
- 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, /* N */
- 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, /* O */
-/* 0x50 */
- 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, /* P */
- 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, /* Q */
- 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, /* R */
- 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, /* S */
- 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, /* T */
- 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, /* U */
- 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, /* V */
- 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, /* W */
-/* 0x58 */
- 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, /* X */
- 0x07, 0x08, 0x70, 0x08, 0x07, 0x00, /* Y */
- 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, /* Z */
- 0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, /* [ */
- 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, /* \ */
- 0x00, 0x41, 0x41, 0x7F, 0x00, 0x00, /* ] */
- 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, /* ^ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, /* _ */
-/* 0x60 */
- 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, /* ` */
- 0x00, 0x74, 0x54, 0x54, 0x78, 0x00, /* a */
- 0x7F, 0x44, 0x44, 0x44, 0x38, 0x00, /* b */
- 0x38, 0x44, 0x44, 0x44, 0x28, 0x00, /* c */
- 0x38, 0x44, 0x44, 0x44, 0x7F, 0x00, /* d */
- 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, /* e */
- 0x08, 0x7E, 0x09, 0x01, 0x02, 0x00, /* f */
- 0x08, 0x54, 0x54, 0x54, 0x3C, 0x00, /* g */
-/* 0x68 */
- 0x7F, 0x04, 0x04, 0x04, 0x78, 0x00, /* h */
- 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, /* i */
- 0x20, 0x40, 0x44, 0x3D, 0x00, 0x00, /* j */
- 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, /* k */
- 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, /* l */
- 0x7C, 0x04, 0x18, 0x04, 0x78, 0x00, /* m */
- 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, /* n */
- 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, /* o */
-/* 0x70 */
- 0x7C, 0x14, 0x14, 0x14, 0x08, 0x00, /* p */
- 0x08, 0x14, 0x14, 0x14, 0x7C, 0x00, /* q */
- 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, /* r */
- 0x48, 0x54, 0x54, 0x54, 0x24, 0x00, /* s */
- 0x04, 0x3F, 0x44, 0x40, 0x20, 0x00, /* t */
- 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, /* u */
- 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, /* v */
- 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, /* w */
-/* 0x78 */
- 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, /* x */
- 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00, /* y */
- 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, /* z */
- 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, /* { */
- 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, /* | */
- 0x00, 0x41, 0x36, 0x08, 0x00, 0x00, /* } */
- 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, /* ~ */
- 0x70, 0x48, 0x44, 0x48, 0x70, 0x00, /* \7f */
-/* 0x80 */
- 0x38, 0xC4, 0xC4, 0x44, 0x28, 0x00, /* \80 */
- 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x00, /* \81 */
- 0x38, 0x54, 0x54, 0x55, 0x19, 0x00, /* \82 */
- 0x22, 0x55, 0x55, 0x55, 0x78, 0x00, /* \83 */
- 0x20, 0x55, 0x54, 0x54, 0x79, 0x00, /* \84 */
- 0x21, 0x75, 0x55, 0x54, 0x78, 0x00, /* \85 */
- 0x20, 0x74, 0x57, 0x54, 0x78, 0x00, /* \86 */
- 0x08, 0x54, 0x54, 0x74, 0x14, 0x00, /* \87 */
-/* 0x88 */
- 0x3A, 0x55, 0x55, 0x55, 0x1A, 0x00, /* \88 */
- 0x39, 0x54, 0x54, 0x55, 0x18, 0x00, /* \89 */
- 0x39, 0x55, 0x55, 0x54, 0x18, 0x00, /* \8a */
- 0x00, 0x45, 0x7C, 0x41, 0x00, 0x00, /* \8b */
- 0x02, 0x45, 0x7D, 0x42, 0x00, 0x00, /* \8c */
- 0x01, 0x45, 0x7D, 0x40, 0x00, 0x00, /* \8d */
- 0x79, 0x14, 0x12, 0x14, 0x79, 0x00, /* \8e */
- 0x70, 0x2B, 0x2B, 0x2B, 0x70, 0x00, /* \8f */
-/* 0x90 */
- 0x7C, 0x54, 0x55, 0x55, 0x45, 0x00, /* \90 */
- 0x20, 0x54, 0x38, 0x54, 0x48, 0x00, /* \91 */
- 0x7E, 0x09, 0x7F, 0x49, 0x49, 0x00, /* \92 */
- 0x32, 0x49, 0x49, 0x49, 0x32, 0x00, /* \93 */
- 0x32, 0x48, 0x48, 0x48, 0x32, 0x00, /* \94 */
- 0x32, 0x4A, 0x4A, 0x48, 0x30, 0x00, /* \95 */
- 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x00, /* \96 */
- 0x3A, 0x42, 0x42, 0x20, 0x78, 0x00, /* \97 */
-/* 0x98 */
- 0x0D, 0x50, 0x50, 0x50, 0x3D, 0x00, /* \98 */
- 0x19, 0x24, 0x42, 0x24, 0x19, 0x00, /* \99 */
- 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x00, /* \9a */
- 0x18, 0x24, 0x7E, 0x24, 0x24, 0x00, /* \9b */
- 0x28, 0x5E, 0x29, 0x42, 0x20, 0x00, /* \9c */
- 0x09, 0x2A, 0x7C, 0x2A, 0x09, 0x00, /* \9d */
- 0x7F, 0x05, 0x15, 0x3D, 0x52, 0x00, /* \9e */
- 0x20, 0x48, 0x3E, 0x09, 0x02, 0x00, /* \9f */
-/* 0xa0 */
- 0x20, 0x74, 0x55, 0x55, 0x79, 0x00, /* */
- 0x01, 0x45, 0x7D, 0x40, 0x00, 0x00, /* ¡ */
- 0x30, 0x48, 0x4A, 0x4A, 0x32, 0x00, /* ¢ */
- 0x38, 0x40, 0x42, 0x22, 0x7A, 0x00, /* £ */
- 0x7A, 0x12, 0x0A, 0x0A, 0x72, 0x00, /* ¤ */
- 0x7D, 0x09, 0x11, 0x21, 0x7D, 0x00, /* ¥ */
- 0x02, 0x15, 0x15, 0x12, 0x04, 0x00, /* ¦ */
- 0x02, 0x15, 0x15, 0x15, 0x02, 0x00, /* § */
-/* 0xa8 */
- 0x30, 0x48, 0x45, 0x40, 0x20, 0x00, /* ¨ */
- 0x00, 0x38, 0x08, 0x08, 0x08, 0x00, /* © */
- 0x00, 0x08, 0x08, 0x08, 0x38, 0x00, /* ª */
- 0x0B, 0x04, 0x6A, 0x55, 0x48, 0x00, /* « */
- 0x0B, 0x24, 0x32, 0x79, 0x20, 0x00, /* ¬ */
- 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, /* */
- 0x08, 0x14, 0x2A, 0x14, 0x22, 0x00, /* ® */
- 0x22, 0x14, 0x2A, 0x14, 0x08, 0x00, /* ¯ */
-/* 0xb0 */
- 0x2A, 0x55, 0x00, 0x2A, 0x55, 0x00, /* ° */
- 0x2A, 0x55, 0x2A, 0x55, 0x2A, 0x55, /* ± */
- 0x55, 0x2A, 0x7F, 0x55, 0x2A, 0x7F, /* ² */
- 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, /* ³ */
- 0x08, 0x08, 0xFF, 0x00, 0x00, 0x00, /* ´ */
- 0x14, 0x14, 0xFF, 0x00, 0x00, 0x00, /* µ */
- 0x08, 0xFF, 0x00, 0xFF, 0x00, 0x00, /* ¶ */
- 0x08, 0xF8, 0x08, 0xF8, 0x00, 0x00, /* · */
-/* 0xb8 */
- 0x14, 0x14, 0xFC, 0x00, 0x00, 0x00, /* ¸ */
- 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, /* ¹ */
- 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, /* º */
- 0x14, 0xF4, 0x04, 0xFC, 0x00, 0x00, /* » */
- 0x14, 0x17, 0x10, 0x1F, 0x00, 0x00, /* ¼ */
- 0x08, 0x0F, 0x08, 0x0F, 0x00, 0x00, /* ½ */
- 0x14, 0x14, 0x1F, 0x00, 0x00, 0x00, /* ¾ */
- 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, /* ¿ */
-/* 0xc0 */
- 0x00, 0x00, 0x0F, 0x08, 0x08, 0x08, /* À */
- 0x08, 0x08, 0x0F, 0x08, 0x08, 0x08, /* Á */
- 0x08, 0x08, 0xF8, 0x08, 0x08, 0x08, /* Â */
- 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, /* Ã */
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* Ä */
- 0x08, 0x08, 0xFF, 0x08, 0x08, 0x08, /* Å */
- 0x00, 0x00, 0xFF, 0x14, 0x14, 0x14, /* Æ */
- 0x00, 0xFF, 0x00, 0xFF, 0x08, 0x08, /* Ç */
-/* 0xc8 */
- 0x00, 0x1F, 0x10, 0x17, 0x14, 0x14, /* È */
- 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, /* É */
- 0x28, 0x2F, 0x20, 0x2F, 0x28, 0x28, /* Ê */
- 0x14, 0xF4, 0x04, 0xF4, 0x14, 0x14, /* Ë */
- 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, /* Ì */
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, /* Í */
- 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, /* Î */
- 0x14, 0x14, 0xF7, 0x14, 0x14, 0x14, /* Ï */
-/* 0xd0 */
- 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08, /* Ð */
- 0x14, 0x14, 0xF4, 0x14, 0x14, 0x14, /* Ñ */
- 0x08, 0x08, 0xF8, 0x08, 0x08, 0x08, /* Ò */
- 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08, /* Ó */
- 0x00, 0x00, 0x1F, 0x14, 0x14, 0x14, /* Ô */
- 0x00, 0x00, 0xFC, 0x14, 0x14, 0x14, /* Õ */
- 0x00, 0xF8, 0x08, 0xF8, 0x08, 0x08, /* Ö */
- 0x08, 0xFF, 0x08, 0xFF, 0x08, 0x08, /* × */
-/* 0xd8 */
- 0x14, 0x14, 0xFF, 0x14, 0x14, 0x14, /* Ø */
- 0x08, 0x08, 0x0F, 0x00, 0x00, 0x00, /* Ù */
- 0x00, 0x00, 0xF8, 0x08, 0x08, 0x08, /* Ú */
- 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, /* Û */
- 0x70, 0x70, 0x70, 0x70, 0x70, 0x00, /* Ü */
- 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, /* Ý */
- 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x00, /* Þ */
- 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, /* ß */
-/* 0xe0 */
- 0x30, 0x48, 0x48, 0x30, 0x48, 0x00, /* à */
- 0x7E, 0x11, 0x25, 0x25, 0x1A, 0x00, /* á */
- 0x7E, 0x02, 0x02, 0x02, 0x06, 0x00, /* â */
- 0x04, 0x7C, 0x04, 0x7C, 0x04, 0x00, /* ã */
- 0x41, 0x63, 0x55, 0x49, 0x63, 0x00, /* ä */
- 0x3C, 0x42, 0x4A, 0x4A, 0x31, 0x00, /* å */
- 0x40, 0x7C, 0x20, 0x20, 0x1C, 0x00, /* æ */
- 0x08, 0x04, 0x7C, 0x08, 0x04, 0x00, /* ç */
-/* 0xe8 */
- 0x49, 0x55, 0x77, 0x55, 0x49, 0x00, /* è */
- 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x00, /* é */
- 0x4C, 0x72, 0x02, 0x72, 0x4C, 0x00, /* ê */
- 0x30, 0x4A, 0x45, 0x49, 0x31, 0x00, /* ë */
- 0x18, 0x24, 0x18, 0x24, 0x18, 0x00, /* ì */
- 0x5C, 0x72, 0x2A, 0x27, 0x1D, 0x00, /* í */
- 0x1C, 0x2A, 0x49, 0x49, 0x00, 0x00, /* î */
- 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x00, /* ï */
-/* 0xf0 */
- 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, /* ð */
- 0x24, 0x24, 0x2E, 0x24, 0x24, 0x00, /* ñ */
- 0x40, 0x51, 0x4A, 0x44, 0x00, 0x00, /* ò */
- 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, /* ó */
- 0x00, 0x00, 0xFE, 0x01, 0x02, 0x00, /* ô */
- 0x20, 0x40, 0x3F, 0x00, 0x00, 0x00, /* õ */
- 0x08, 0x08, 0x2A, 0x08, 0x08, 0x00, /* ö */
- 0x24, 0x12, 0x24, 0x12, 0x00, 0x00, /* ÷ */
-/* 0xf8 */
- 0x06, 0x09, 0x09, 0x09, 0x06, 0x00, /* ø */
- 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /* ù */
- 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, /* ú */
- 0x10, 0x30, 0x7F, 0x01, 0x01, 0x00, /* û */
- 0x01, 0x0E, 0x01, 0x01, 0x0E, 0x00, /* ü */
- 0x0A, 0x09, 0x0D, 0x0A, 0x00, 0x00, /* ý */
- 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x00, /* þ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ÿ */
-};
-
-struct Font default_font =
-{
- /* .glyph = */ default_font_glyphs,
- /* .width = */ 6,
- /* .height = */ 8
-};
-
+++ /dev/null
-#
-# $Id$
-# Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
-# All rights reserved.
-#
-# Makefile fragment for DevLib demo application.
-#
-# Author: Bernardo Innocenti <bernie@develer.com>
-#
-
-%.c: %.bdf
- fonts/convbdf $< > $@
+++ /dev/null
-STARTFONT 2.1
-FONT -Adobe-Helvetica-Bold-R-Normal--10-100-75-75-P-60-ISO8859-1
-SIZE 10 75 75
-FONTBOUNDINGBOX 11 13 -1 -2
-COMMENT $XConsortium: helvB10.bdf,v 1.13 95/01/26 18:01:30 gildea Exp $
-COMMENT
-COMMENT +
-COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated.
-COMMENT Copyright 1988, 1994 Digital Equipment Corporation.
-COMMENT
-COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be
-COMMENT registered in certain jurisdictions.
-COMMENT Permission to use these trademarks is hereby granted only in
-COMMENT association with the images described in this file.
-COMMENT
-COMMENT Permission to use, copy, modify, distribute and sell this software
-COMMENT and its documentation for any purpose and without fee is hereby
-COMMENT granted, provided that the above copyright notices appear in all
-COMMENT copies and that both those copyright notices and this permission
-COMMENT notice appear in supporting documentation, and that the names of
-COMMENT Adobe Systems and Digital Equipment Corporation not be used in
-COMMENT advertising or publicity pertaining to distribution of the software
-COMMENT without specific, written prior permission. Adobe Systems and
-COMMENT Digital Equipment Corporation make no representations about the
-COMMENT suitability of this software for any purpose. It is provided "as
-COMMENT is" without express or implied warranty.
-COMMENT -
-STARTPROPERTIES 28
-FOUNDRY "Adobe"
-FAMILY_NAME "Helvetica"
-WEIGHT_NAME "Bold"
-SLANT "R"
-SETWIDTH_NAME "Normal"
-ADD_STYLE_NAME ""
-PIXEL_SIZE 10
-POINT_SIZE 100
-RESOLUTION_X 75
-RESOLUTION_Y 75
-SPACING "P"
-AVERAGE_WIDTH 60
-CHARSET_REGISTRY "ISO8859"
-CHARSET_ENCODING "1"
-CAP_HEIGHT 8
-X_HEIGHT 6
-FONT_ASCENT 10
-FONT_DESCENT 2
-FACE_NAME "Helvetica Bold"
-COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
-NOTICE "Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. "
-_DEC_DEVICE_FONTNAMES "PS=Helvetica-Bold"
-_DEC_PRODUCTINFO "DECwindows Fonts V2.2, 07-Nov-1991"
-DEFAULT_CHAR 32
-RELATIVE_SETWIDTH 50
-RELATIVE_WEIGHT 70
-CHARSET_COLLECTIONS "ASCII ISO8859-1 ADOBE-STANDARD"
-FULL_NAME "Helvetica Bold"
-ENDPROPERTIES
-CHARS 229
-STARTCHAR space
-ENCODING 32
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR exclam
-ENCODING 33
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 2 8 1 0
-BITMAP
-C0
-C0
-C0
-C0
-80
-80
-00
-C0
-ENDCHAR
-STARTCHAR quotedbl
-ENCODING 34
-SWIDTH 474 0
-DWIDTH 5 0
-BBX 3 3 1 5
-BITMAP
-A0
-A0
-A0
-ENDCHAR
-STARTCHAR numbersign
-ENCODING 35
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 7 0 0
-BITMAP
-50
-50
-FC
-50
-F8
-A0
-A0
-ENDCHAR
-STARTCHAR dollar
-ENCODING 36
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 -1
-BITMAP
-20
-70
-A8
-E0
-70
-38
-A8
-70
-20
-ENDCHAR
-STARTCHAR percent
-ENCODING 37
-SWIDTH 889 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-62
-B4
-68
-10
-10
-2C
-56
-8C
-ENDCHAR
-STARTCHAR ampersand
-ENCODING 38
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-70
-D8
-D8
-70
-DE
-CC
-DC
-76
-ENDCHAR
-STARTCHAR quoteright
-ENCODING 39
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 3 0 5
-BITMAP
-C0
-40
-80
-ENDCHAR
-STARTCHAR parenleft
-ENCODING 40
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 10 0 -2
-BITMAP
-20
-60
-40
-C0
-C0
-C0
-C0
-40
-60
-20
-ENDCHAR
-STARTCHAR parenright
-ENCODING 41
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 10 0 -2
-BITMAP
-80
-C0
-40
-60
-60
-60
-60
-40
-C0
-80
-ENDCHAR
-STARTCHAR asterisk
-ENCODING 42
-SWIDTH 389 0
-DWIDTH 4 0
-BBX 3 3 0 5
-BITMAP
-A0
-40
-A0
-ENDCHAR
-STARTCHAR plus
-ENCODING 43
-SWIDTH 584 0
-DWIDTH 6 0
-BBX 6 5 0 1
-BITMAP
-30
-30
-FC
-30
-30
-ENDCHAR
-STARTCHAR comma
-ENCODING 44
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 4 0 -2
-BITMAP
-40
-40
-40
-80
-ENDCHAR
-STARTCHAR minus
-ENCODING 45
-SWIDTH 584 0
-DWIDTH 7 0
-BBX 5 1 1 3
-BITMAP
-F8
-ENDCHAR
-STARTCHAR period
-ENCODING 46
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 1 2 1 0
-BITMAP
-80
-80
-ENDCHAR
-STARTCHAR slash
-ENCODING 47
-SWIDTH 278 0
-DWIDTH 4 0
-BBX 4 8 0 0
-BITMAP
-10
-10
-20
-20
-40
-40
-80
-80
-ENDCHAR
-STARTCHAR zero
-ENCODING 48
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-D8
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR one
-ENCODING 49
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 4 8 0 0
-BITMAP
-30
-F0
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR two
-ENCODING 50
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-18
-18
-30
-60
-C0
-F8
-ENDCHAR
-STARTCHAR three
-ENCODING 51
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-18
-30
-18
-18
-D8
-70
-ENDCHAR
-STARTCHAR four
-ENCODING 52
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 8 0 0
-BITMAP
-18
-38
-58
-58
-98
-FC
-18
-18
-ENDCHAR
-STARTCHAR five
-ENCODING 53
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-F8
-C0
-C0
-F0
-18
-98
-D8
-70
-ENDCHAR
-STARTCHAR six
-ENCODING 54
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-C0
-F0
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR seven
-ENCODING 55
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-F8
-18
-18
-30
-30
-30
-60
-60
-ENDCHAR
-STARTCHAR eight
-ENCODING 56
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-D8
-70
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR nine
-ENCODING 57
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-D8
-D8
-78
-18
-D8
-70
-ENDCHAR
-STARTCHAR colon
-ENCODING 58
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 1 6 1 0
-BITMAP
-80
-80
-00
-00
-80
-80
-ENDCHAR
-STARTCHAR semicolon
-ENCODING 59
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 2 8 0 -2
-BITMAP
-40
-40
-00
-00
-40
-40
-40
-80
-ENDCHAR
-STARTCHAR less
-ENCODING 60
-SWIDTH 584 0
-DWIDTH 5 0
-BBX 4 5 0 1
-BITMAP
-30
-60
-C0
-60
-30
-ENDCHAR
-STARTCHAR equal
-ENCODING 61
-SWIDTH 584 0
-DWIDTH 6 0
-BBX 5 3 0 2
-BITMAP
-F8
-00
-F8
-ENDCHAR
-STARTCHAR greater
-ENCODING 62
-SWIDTH 584 0
-DWIDTH 5 0
-BBX 4 5 0 1
-BITMAP
-C0
-60
-30
-60
-C0
-ENDCHAR
-STARTCHAR question
-ENCODING 63
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-D8
-18
-30
-60
-60
-00
-60
-ENDCHAR
-STARTCHAR at
-ENCODING 64
-SWIDTH 975 0
-DWIDTH 11 0
-BBX 10 9 0 -2
-BITMAP
-1F00
-6080
-4D40
-9240
-A240
-A480
-9B00
-4000
-3E00
-ENDCHAR
-STARTCHAR A
-ENCODING 65
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR B
-ENCODING 66
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-F8
-CC
-CC
-F8
-CC
-CC
-CC
-F8
-ENDCHAR
-STARTCHAR C
-ENCODING 67
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-3C
-66
-C2
-C0
-C0
-C2
-66
-3C
-ENDCHAR
-STARTCHAR D
-ENCODING 68
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-F0
-D8
-CC
-CC
-CC
-CC
-D8
-F0
-ENDCHAR
-STARTCHAR E
-ENCODING 69
-SWIDTH 667 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-F8
-C0
-C0
-F8
-C0
-C0
-C0
-F8
-ENDCHAR
-STARTCHAR F
-ENCODING 70
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-F8
-C0
-C0
-F0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR G
-ENCODING 71
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-3C
-66
-C2
-C0
-CE
-C6
-66
-3A
-ENDCHAR
-STARTCHAR H
-ENCODING 72
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-CC
-CC
-CC
-FC
-CC
-CC
-CC
-CC
-ENDCHAR
-STARTCHAR I
-ENCODING 73
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 8 0 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR J
-ENCODING 74
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-18
-18
-18
-18
-18
-18
-D8
-70
-ENDCHAR
-STARTCHAR K
-ENCODING 75
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 7 8 0 0
-BITMAP
-CC
-D8
-F0
-E0
-F0
-D8
-CC
-C6
-ENDCHAR
-STARTCHAR L
-ENCODING 76
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-F8
-ENDCHAR
-STARTCHAR M
-ENCODING 77
-SWIDTH 833 0
-DWIDTH 10 0
-BBX 9 8 0 0
-BITMAP
-C180
-E380
-E380
-F780
-D580
-DD80
-C980
-C980
-ENDCHAR
-STARTCHAR N
-ENCODING 78
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-C6
-E6
-E6
-D6
-D6
-CE
-CE
-C6
-ENDCHAR
-STARTCHAR O
-ENCODING 79
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-38
-6C
-C6
-C6
-C6
-C6
-6C
-38
-ENDCHAR
-STARTCHAR P
-ENCODING 80
-SWIDTH 667 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-F8
-CC
-CC
-CC
-F8
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Q
-ENCODING 81
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 9 0 -1
-BITMAP
-38
-6C
-C6
-C6
-C6
-D6
-6C
-3C
-02
-ENDCHAR
-STARTCHAR R
-ENCODING 82
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-F8
-CC
-CC
-CC
-F8
-CC
-CC
-CC
-ENDCHAR
-STARTCHAR S
-ENCODING 83
-SWIDTH 667 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-78
-CC
-E0
-78
-1C
-8C
-CC
-78
-ENDCHAR
-STARTCHAR T
-ENCODING 84
-SWIDTH 611 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-FC
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR U
-ENCODING 85
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-CC
-CC
-CC
-CC
-CC
-CC
-CC
-78
-ENDCHAR
-STARTCHAR V
-ENCODING 86
-SWIDTH 667 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-C6
-C6
-6C
-6C
-6C
-38
-38
-10
-ENDCHAR
-STARTCHAR W
-ENCODING 87
-SWIDTH 944 0
-DWIDTH 11 0
-BBX 10 8 0 0
-BITMAP
-CCC0
-CCC0
-CCC0
-6D80
-6D80
-7F80
-3300
-2100
-ENDCHAR
-STARTCHAR X
-ENCODING 88
-SWIDTH 667 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-C6
-C6
-6C
-38
-38
-6C
-C6
-C6
-ENDCHAR
-STARTCHAR Y
-ENCODING 89
-SWIDTH 667 0
-DWIDTH 9 0
-BBX 8 8 0 0
-BITMAP
-C3
-C3
-66
-66
-3C
-18
-18
-18
-ENDCHAR
-STARTCHAR Z
-ENCODING 90
-SWIDTH 611 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-FC
-0C
-18
-30
-70
-60
-C0
-FC
-ENDCHAR
-STARTCHAR bracketleft
-ENCODING 91
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 10 0 -2
-BITMAP
-E0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-E0
-ENDCHAR
-STARTCHAR backslash
-ENCODING 92
-SWIDTH 278 0
-DWIDTH 4 0
-BBX 4 8 0 0
-BITMAP
-80
-80
-40
-40
-20
-20
-10
-10
-ENDCHAR
-STARTCHAR bracketright
-ENCODING 93
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 10 0 -2
-BITMAP
-E0
-60
-60
-60
-60
-60
-60
-60
-60
-E0
-ENDCHAR
-STARTCHAR asciicircum
-ENCODING 94
-SWIDTH 584 0
-DWIDTH 5 0
-BBX 5 4 0 4
-BITMAP
-20
-70
-D8
-88
-ENDCHAR
-STARTCHAR underscore
-ENCODING 95
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 1 0 -2
-BITMAP
-FC
-ENDCHAR
-STARTCHAR quoteleft
-ENCODING 96
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 3 0 5
-BITMAP
-40
-80
-C0
-ENDCHAR
-STARTCHAR a
-ENCODING 97
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 6 0 0
-BITMAP
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR b
-ENCODING 98
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-C0
-C0
-F0
-D8
-C8
-C8
-D8
-F0
-ENDCHAR
-STARTCHAR c
-ENCODING 99
-SWIDTH 556 0
-DWIDTH 5 0
-BBX 4 6 0 0
-BITMAP
-70
-D0
-C0
-C0
-D0
-70
-ENDCHAR
-STARTCHAR d
-ENCODING 100
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-18
-18
-78
-D8
-98
-98
-D8
-78
-ENDCHAR
-STARTCHAR e
-ENCODING 101
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-70
-D8
-F8
-C0
-D8
-70
-ENDCHAR
-STARTCHAR f
-ENCODING 102
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 4 8 0 0
-BITMAP
-70
-C0
-E0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR g
-ENCODING 103
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 -2
-BITMAP
-68
-D8
-98
-98
-D8
-78
-18
-70
-ENDCHAR
-STARTCHAR h
-ENCODING 104
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-C0
-C0
-F0
-D8
-D8
-D8
-D8
-D8
-ENDCHAR
-STARTCHAR i
-ENCODING 105
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 8 0 0
-BITMAP
-C0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR j
-ENCODING 106
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 10 0 -2
-BITMAP
-C0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-80
-ENDCHAR
-STARTCHAR k
-ENCODING 107
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 8 0 0
-BITMAP
-C0
-C0
-D8
-F0
-E0
-F0
-D8
-CC
-ENDCHAR
-STARTCHAR l
-ENCODING 108
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 8 0 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR m
-ENCODING 109
-SWIDTH 889 0
-DWIDTH 9 0
-BBX 8 6 0 0
-BITMAP
-B6
-DB
-DB
-DB
-DB
-DB
-ENDCHAR
-STARTCHAR n
-ENCODING 110
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-B0
-D8
-D8
-D8
-D8
-D8
-ENDCHAR
-STARTCHAR o
-ENCODING 111
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR p
-ENCODING 112
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 -2
-BITMAP
-B0
-D8
-C8
-C8
-D8
-F0
-C0
-C0
-ENDCHAR
-STARTCHAR q
-ENCODING 113
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 -2
-BITMAP
-68
-D8
-98
-98
-D8
-78
-18
-18
-ENDCHAR
-STARTCHAR r
-ENCODING 114
-SWIDTH 389 0
-DWIDTH 4 0
-BBX 4 6 0 0
-BITMAP
-B0
-E0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR s
-ENCODING 115
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-70
-D8
-70
-18
-D8
-70
-ENDCHAR
-STARTCHAR t
-ENCODING 116
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 8 0 0
-BITMAP
-C0
-C0
-E0
-C0
-C0
-C0
-C0
-60
-ENDCHAR
-STARTCHAR u
-ENCODING 117
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-D8
-D8
-D8
-D8
-D8
-68
-ENDCHAR
-STARTCHAR v
-ENCODING 118
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-D8
-D8
-D8
-50
-70
-20
-ENDCHAR
-STARTCHAR w
-ENCODING 119
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 6 0 0
-BITMAP
-D6
-D6
-D6
-6C
-6C
-6C
-ENDCHAR
-STARTCHAR x
-ENCODING 120
-SWIDTH 556 0
-DWIDTH 7 0
-BBX 6 6 0 0
-BITMAP
-CC
-78
-30
-78
-CC
-CC
-ENDCHAR
-STARTCHAR y
-ENCODING 121
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 -2
-BITMAP
-D8
-D8
-D8
-D8
-78
-30
-30
-60
-ENDCHAR
-STARTCHAR z
-ENCODING 122
-SWIDTH 500 0
-DWIDTH 6 0
-BBX 5 6 0 0
-BITMAP
-F8
-18
-30
-60
-C0
-F8
-ENDCHAR
-STARTCHAR braceleft
-ENCODING 123
-SWIDTH 389 0
-DWIDTH 5 0
-BBX 4 10 0 -2
-BITMAP
-30
-60
-60
-60
-C0
-60
-60
-60
-60
-30
-ENDCHAR
-STARTCHAR bar
-ENCODING 124
-SWIDTH 280 0
-DWIDTH 3 0
-BBX 1 10 1 -2
-BITMAP
-80
-80
-80
-80
-80
-80
-80
-80
-80
-80
-ENDCHAR
-STARTCHAR braceright
-ENCODING 125
-SWIDTH 389 0
-DWIDTH 5 0
-BBX 4 10 0 -2
-BITMAP
-C0
-60
-60
-60
-30
-60
-60
-60
-60
-C0
-ENDCHAR
-STARTCHAR asciitilde
-ENCODING 126
-SWIDTH 584 0
-DWIDTH 6 0
-BBX 6 2 0 2
-BITMAP
-6C
-D8
-ENDCHAR
-STARTCHAR space
-ENCODING 160
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR exclamdown
-ENCODING 161
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 2 8 1 -2
-BITMAP
-C0
-00
-40
-40
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR cent
-ENCODING 162
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 -1
-BITMAP
-10
-70
-D8
-A0
-A0
-D8
-70
-40
-ENDCHAR
-STARTCHAR sterling
-ENCODING 163
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-38
-68
-60
-F0
-60
-60
-68
-D8
-ENDCHAR
-STARTCHAR currency
-ENCODING 164
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 6 0 1
-BITMAP
-D8
-70
-D8
-D8
-70
-D8
-ENDCHAR
-STARTCHAR yen
-ENCODING 165
-SWIDTH 556 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-84
-CC
-48
-78
-FC
-30
-FC
-30
-ENDCHAR
-STARTCHAR brokenbar
-ENCODING 166
-SWIDTH 280 0
-DWIDTH 3 0
-BBX 1 10 1 -2
-BITMAP
-80
-80
-80
-80
-00
-00
-80
-80
-80
-80
-ENDCHAR
-STARTCHAR section
-ENCODING 167
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 10 0 -2
-BITMAP
-70
-C8
-E0
-70
-98
-C8
-70
-38
-98
-70
-ENDCHAR
-STARTCHAR dieresis
-ENCODING 168
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 3 1 0 7
-BITMAP
-A0
-ENDCHAR
-STARTCHAR copyright
-ENCODING 169
-SWIDTH 737 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-3C
-42
-99
-A5
-A1
-9D
-42
-3C
-ENDCHAR
-STARTCHAR ordfeminine
-ENCODING 170
-SWIDTH 370 0
-DWIDTH 5 0
-BBX 3 5 1 3
-BITMAP
-E0
-20
-A0
-00
-E0
-ENDCHAR
-STARTCHAR guillemotleft
-ENCODING 171
-SWIDTH 556 0
-DWIDTH 7 0
-BBX 6 3 0 1
-BITMAP
-6C
-D8
-6C
-ENDCHAR
-STARTCHAR logicalnot
-ENCODING 172
-SWIDTH 584 0
-DWIDTH 7 0
-BBX 5 3 1 2
-BITMAP
-F8
-08
-08
-ENDCHAR
-STARTCHAR hyphen
-ENCODING 173
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 4 1 0 3
-BITMAP
-F0
-ENDCHAR
-STARTCHAR registered
-ENCODING 174
-SWIDTH 737 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-3C
-42
-BD
-A5
-B9
-A5
-42
-3C
-ENDCHAR
-STARTCHAR macron
-ENCODING 175
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 3 1 0 7
-BITMAP
-E0
-ENDCHAR
-STARTCHAR degree
-ENCODING 176
-SWIDTH 400 0
-DWIDTH 4 0
-BBX 3 3 1 4
-BITMAP
-60
-A0
-C0
-ENDCHAR
-STARTCHAR plusminus
-ENCODING 177
-SWIDTH 584 0
-DWIDTH 6 0
-BBX 6 7 0 0
-BITMAP
-30
-30
-FC
-30
-30
-00
-FC
-ENDCHAR
-STARTCHAR twosuperior
-ENCODING 178
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 3 4 0 3
-BITMAP
-60
-A0
-40
-E0
-ENDCHAR
-STARTCHAR threesuperior
-ENCODING 179
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 3 4 0 3
-BITMAP
-E0
-40
-20
-C0
-ENDCHAR
-STARTCHAR acute
-ENCODING 180
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 2 2 0 7
-BITMAP
-40
-80
-ENDCHAR
-STARTCHAR mu
-ENCODING 181
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 -2
-BITMAP
-D8
-D8
-D8
-D8
-D8
-E8
-C0
-C0
-ENDCHAR
-STARTCHAR paragraph
-ENCODING 182
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 10 0 -2
-BITMAP
-7C
-E8
-E8
-E8
-68
-28
-28
-28
-28
-28
-ENDCHAR
-STARTCHAR periodcentered
-ENCODING 183
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 1 0 3
-BITMAP
-C0
-ENDCHAR
-STARTCHAR cedilla
-ENCODING 184
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 2 2 0 -2
-BITMAP
-40
-C0
-ENDCHAR
-STARTCHAR onesuperior
-ENCODING 185
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 2 4 0 3
-BITMAP
-40
-C0
-40
-40
-ENDCHAR
-STARTCHAR ordmasculine
-ENCODING 186
-SWIDTH 365 0
-DWIDTH 5 0
-BBX 3 5 1 3
-BITMAP
-E0
-A0
-E0
-00
-E0
-ENDCHAR
-STARTCHAR guillemotright
-ENCODING 187
-SWIDTH 556 0
-DWIDTH 7 0
-BBX 6 3 0 1
-BITMAP
-D8
-6C
-D8
-ENDCHAR
-STARTCHAR onequarter
-ENCODING 188
-SWIDTH 834 0
-DWIDTH 9 0
-BBX 8 8 0 0
-BITMAP
-42
-C4
-48
-48
-12
-26
-2F
-42
-ENDCHAR
-STARTCHAR onehalf
-ENCODING 189
-SWIDTH 834 0
-DWIDTH 9 0
-BBX 7 8 0 0
-BITMAP
-42
-C4
-48
-48
-16
-2A
-24
-4E
-ENDCHAR
-STARTCHAR threequarters
-ENCODING 190
-SWIDTH 834 0
-DWIDTH 9 0
-BBX 8 8 0 0
-BITMAP
-E2
-44
-28
-C8
-12
-26
-2F
-42
-ENDCHAR
-STARTCHAR questiondown
-ENCODING 191
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 -2
-BITMAP
-30
-00
-30
-30
-60
-C0
-D8
-70
-ENDCHAR
-STARTCHAR Agrave
-ENCODING 192
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-20
-10
-00
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR Aacute
-ENCODING 193
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-08
-10
-00
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR Acircumflex
-ENCODING 194
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-10
-28
-00
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR Atilde
-ENCODING 195
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-14
-28
-00
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR Adieresis
-ENCODING 196
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 10 0 0
-BITMAP
-28
-00
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR Aring
-ENCODING 197
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-10
-28
-10
-38
-38
-6C
-6C
-6C
-FE
-C6
-C6
-ENDCHAR
-STARTCHAR AE
-ENCODING 198
-SWIDTH 1000 0
-DWIDTH 10 0
-BBX 9 8 0 0
-BITMAP
-3F80
-3C00
-6C00
-6F80
-6C00
-FC00
-CC00
-CF80
-ENDCHAR
-STARTCHAR Ccedilla
-ENCODING 199
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 10 0 -2
-BITMAP
-3C
-66
-C2
-C0
-C0
-C2
-66
-3C
-10
-30
-ENDCHAR
-STARTCHAR Egrave
-ENCODING 200
-SWIDTH 667 0
-DWIDTH 6 0
-BBX 5 11 0 0
-BITMAP
-40
-20
-00
-F8
-C0
-C0
-F8
-C0
-C0
-C0
-F8
-ENDCHAR
-STARTCHAR Eacute
-ENCODING 201
-SWIDTH 667 0
-DWIDTH 6 0
-BBX 5 11 0 0
-BITMAP
-10
-20
-00
-F8
-C0
-C0
-F8
-C0
-C0
-C0
-F8
-ENDCHAR
-STARTCHAR Ecircumflex
-ENCODING 202
-SWIDTH 667 0
-DWIDTH 6 0
-BBX 5 11 0 0
-BITMAP
-20
-50
-00
-F8
-C0
-C0
-F8
-C0
-C0
-C0
-F8
-ENDCHAR
-STARTCHAR Edieresis
-ENCODING 203
-SWIDTH 667 0
-DWIDTH 6 0
-BBX 5 10 0 0
-BITMAP
-50
-00
-F8
-C0
-C0
-F8
-C0
-C0
-C0
-F8
-ENDCHAR
-STARTCHAR Igrave
-ENCODING 204
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 11 0 0
-BITMAP
-80
-40
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Iacute
-ENCODING 205
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 11 0 0
-BITMAP
-40
-80
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Icircumflex
-ENCODING 206
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 3 11 0 0
-BITMAP
-40
-A0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Idieresis
-ENCODING 207
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 3 10 0 0
-BITMAP
-A0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Eth
-ENCODING 208
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-F0
-D8
-CC
-EC
-CC
-CC
-D8
-F0
-ENDCHAR
-STARTCHAR Ntilde
-ENCODING 209
-SWIDTH 722 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-14
-28
-00
-C6
-C6
-E6
-D6
-D6
-CE
-CE
-C6
-ENDCHAR
-STARTCHAR Ograve
-ENCODING 210
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-20
-10
-00
-38
-6C
-C6
-C6
-C6
-C6
-6C
-38
-ENDCHAR
-STARTCHAR Oacute
-ENCODING 211
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-04
-08
-00
-38
-6C
-C6
-C6
-C6
-C6
-6C
-38
-ENDCHAR
-STARTCHAR Ocircumflex
-ENCODING 212
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-10
-28
-00
-38
-6C
-C6
-C6
-C6
-C6
-6C
-38
-ENDCHAR
-STARTCHAR Otilde
-ENCODING 213
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 11 0 0
-BITMAP
-14
-28
-00
-38
-6C
-C6
-C6
-C6
-C6
-6C
-38
-ENDCHAR
-STARTCHAR Odieresis
-ENCODING 214
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 10 0 0
-BITMAP
-28
-00
-38
-6C
-C6
-C6
-C6
-C6
-6C
-38
-ENDCHAR
-STARTCHAR multiply
-ENCODING 215
-SWIDTH 584 0
-DWIDTH 6 0
-BBX 6 5 0 1
-BITMAP
-CC
-78
-30
-78
-CC
-ENDCHAR
-STARTCHAR Oslash
-ENCODING 216
-SWIDTH 778 0
-DWIDTH 8 0
-BBX 7 8 0 0
-BITMAP
-3A
-6C
-CE
-D6
-D6
-E6
-6C
-B8
-ENDCHAR
-STARTCHAR Ugrave
-ENCODING 217
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 11 0 0
-BITMAP
-20
-10
-00
-CC
-CC
-CC
-CC
-CC
-CC
-CC
-78
-ENDCHAR
-STARTCHAR Uacute
-ENCODING 218
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 11 0 0
-BITMAP
-08
-10
-00
-CC
-CC
-CC
-CC
-CC
-CC
-CC
-78
-ENDCHAR
-STARTCHAR Ucircumflex
-ENCODING 219
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 11 0 0
-BITMAP
-10
-28
-00
-CC
-CC
-CC
-CC
-CC
-CC
-CC
-78
-ENDCHAR
-STARTCHAR Udieresis
-ENCODING 220
-SWIDTH 722 0
-DWIDTH 7 0
-BBX 6 10 0 0
-BITMAP
-28
-00
-CC
-CC
-CC
-CC
-CC
-CC
-CC
-78
-ENDCHAR
-STARTCHAR Yacute
-ENCODING 221
-SWIDTH 667 0
-DWIDTH 9 0
-BBX 8 11 0 0
-BITMAP
-04
-08
-00
-C3
-C3
-66
-66
-3C
-18
-18
-18
-ENDCHAR
-STARTCHAR Thorn
-ENCODING 222
-SWIDTH 667 0
-DWIDTH 7 0
-BBX 6 8 0 0
-BITMAP
-C0
-F8
-CC
-CC
-CC
-F8
-C0
-C0
-ENDCHAR
-STARTCHAR germandbls
-ENCODING 223
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 8 0 0
-BITMAP
-70
-C8
-C8
-D0
-C8
-C8
-C8
-D0
-ENDCHAR
-STARTCHAR agrave
-ENCODING 224
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 9 0 0
-BITMAP
-40
-20
-00
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR aacute
-ENCODING 225
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 9 0 0
-BITMAP
-08
-10
-00
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR acircumflex
-ENCODING 226
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 9 0 0
-BITMAP
-30
-68
-00
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR atilde
-ENCODING 227
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 9 0 0
-BITMAP
-28
-50
-00
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR adieresis
-ENCODING 228
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 9 0 0
-BITMAP
-50
-50
-00
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR aring
-ENCODING 229
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 9 0 0
-BITMAP
-20
-50
-20
-70
-98
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR ae
-ENCODING 230
-SWIDTH 889 0
-DWIDTH 9 0
-BBX 8 6 0 0
-BITMAP
-7E
-9B
-7F
-D8
-DB
-6E
-ENDCHAR
-STARTCHAR ccedilla
-ENCODING 231
-SWIDTH 556 0
-DWIDTH 5 0
-BBX 4 8 0 -2
-BITMAP
-70
-D0
-C0
-C0
-D0
-70
-20
-60
-ENDCHAR
-STARTCHAR egrave
-ENCODING 232
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-40
-20
-00
-70
-D8
-F8
-C0
-D8
-70
-ENDCHAR
-STARTCHAR eacute
-ENCODING 233
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-10
-20
-00
-70
-D8
-F8
-C0
-D8
-70
-ENDCHAR
-STARTCHAR ecircumflex
-ENCODING 234
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-20
-50
-00
-70
-D8
-F8
-C0
-D8
-70
-ENDCHAR
-STARTCHAR edieresis
-ENCODING 235
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-50
-50
-00
-70
-D8
-F8
-C0
-D8
-70
-ENDCHAR
-STARTCHAR igrave
-ENCODING 236
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 9 0 0
-BITMAP
-80
-40
-00
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR iacute
-ENCODING 237
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 3 9 0 0
-BITMAP
-20
-40
-00
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR icircumflex
-ENCODING 238
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 3 9 -1 0
-BITMAP
-40
-A0
-00
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR idieresis
-ENCODING 239
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 3 9 0 0
-BITMAP
-A0
-A0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR eth
-ENCODING 240
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-50
-60
-A0
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR ntilde
-ENCODING 241
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-28
-50
-00
-B0
-D8
-D8
-D8
-D8
-D8
-ENDCHAR
-STARTCHAR ograve
-ENCODING 242
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-40
-20
-00
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR oacute
-ENCODING 243
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-10
-20
-00
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR ocircumflex
-ENCODING 244
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-20
-50
-00
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR otilde
-ENCODING 245
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-50
-A0
-00
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR odieresis
-ENCODING 246
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-50
-50
-00
-70
-D8
-D8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR divide
-ENCODING 247
-SWIDTH 584 0
-DWIDTH 6 0
-BBX 6 5 0 1
-BITMAP
-30
-00
-FC
-00
-30
-ENDCHAR
-STARTCHAR oslash
-ENCODING 248
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 6 6 0 0
-BITMAP
-74
-D8
-F8
-D8
-D8
-70
-ENDCHAR
-STARTCHAR ugrave
-ENCODING 249
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-40
-20
-00
-D8
-D8
-D8
-D8
-D8
-68
-ENDCHAR
-STARTCHAR uacute
-ENCODING 250
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-10
-20
-00
-D8
-D8
-D8
-D8
-D8
-68
-ENDCHAR
-STARTCHAR ucircumflex
-ENCODING 251
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-20
-50
-00
-D8
-D8
-D8
-D8
-D8
-68
-ENDCHAR
-STARTCHAR udieresis
-ENCODING 252
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-50
-50
-00
-D8
-D8
-D8
-D8
-D8
-68
-ENDCHAR
-STARTCHAR yacute
-ENCODING 253
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 11 0 -2
-BITMAP
-10
-20
-00
-D8
-D8
-D8
-D8
-78
-30
-30
-60
-ENDCHAR
-STARTCHAR thorn
-ENCODING 254
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 5 10 0 -2
-BITMAP
-C0
-C0
-F0
-D8
-C8
-C8
-D8
-F0
-C0
-C0
-ENDCHAR
-STARTCHAR ydieresis
-ENCODING 255
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 11 0 -2
-BITMAP
-50
-50
-00
-D8
-D8
-D8
-D8
-78
-30
-30
-60
-ENDCHAR
-STARTCHAR Lslash
-ENCODING -1
-SWIDTH 611 0
-DWIDTH 6 0
-BBX 6 8 -1 0
-BITMAP
-60
-60
-60
-70
-E0
-60
-60
-7C
-ENDCHAR
-STARTCHAR OE
-ENCODING -1
-SWIDTH 1000 0
-DWIDTH 10 0
-BBX 9 8 0 0
-BITMAP
-3F80
-6C00
-CC00
-CF80
-CC00
-CC00
-6C00
-3F80
-ENDCHAR
-STARTCHAR Scaron
-ENCODING -1
-SWIDTH 667 0
-DWIDTH 7 0
-BBX 6 9 0 0
-BITMAP
-28
-10
-00
-78
-CC
-70
-3C
-CC
-78
-ENDCHAR
-STARTCHAR Ydieresis
-ENCODING -1
-SWIDTH 667 0
-DWIDTH 8 0
-BBX 8 8 0 0
-BITMAP
-14
-00
-C3
-66
-3C
-18
-18
-18
-ENDCHAR
-STARTCHAR Zcaron
-ENCODING -1
-SWIDTH 611 0
-DWIDTH 7 0
-BBX 6 9 0 0
-BITMAP
-28
-10
-00
-FC
-18
-30
-60
-C0
-FC
-ENDCHAR
-STARTCHAR breve
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 4 2 0 6
-BITMAP
-90
-60
-ENDCHAR
-STARTCHAR bullet
-ENCODING -1
-SWIDTH 350 0
-DWIDTH 4 0
-BBX 2 2 1 2
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR caron
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 2 0 6
-BITMAP
-A0
-40
-ENDCHAR
-STARTCHAR circumflex
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 2 0 6
-BITMAP
-40
-A0
-ENDCHAR
-STARTCHAR dagger
-ENCODING -1
-SWIDTH 556 0
-DWIDTH 7 0
-BBX 6 10 0 -2
-BITMAP
-30
-30
-FC
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR daggerdbl
-ENCODING -1
-SWIDTH 556 0
-DWIDTH 7 0
-BBX 6 10 0 -2
-BITMAP
-30
-30
-FC
-30
-30
-30
-FC
-30
-30
-30
-ENDCHAR
-STARTCHAR dotaccent
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 2 0
-BBX 1 1 0 7
-BITMAP
-80
-ENDCHAR
-STARTCHAR dotlessi
-ENCODING -1
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 6 0 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR ellipsis
-ENCODING -1
-SWIDTH 1000 0
-DWIDTH 10 0
-BBX 8 1 1 0
-BITMAP
-DB
-ENDCHAR
-STARTCHAR emdash
-ENCODING -1
-SWIDTH 1000 0
-DWIDTH 10 0
-BBX 10 1 0 3
-BITMAP
-FFC0
-ENDCHAR
-STARTCHAR endash
-ENCODING -1
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 6 1 0 3
-BITMAP
-FC
-ENDCHAR
-STARTCHAR fi
-ENCODING -1
-SWIDTH 611 0
-DWIDTH 7 0
-BBX 7 8 -1 0
-BITMAP
-36
-60
-F6
-66
-66
-66
-66
-66
-ENDCHAR
-STARTCHAR fl
-ENCODING -1
-SWIDTH 611 0
-DWIDTH 7 0
-BBX 7 8 -1 0
-BITMAP
-36
-66
-F6
-66
-66
-66
-66
-66
-ENDCHAR
-STARTCHAR florin
-ENCODING -1
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 -2
-BITMAP
-38
-60
-F8
-60
-60
-60
-60
-60
-C0
-ENDCHAR
-STARTCHAR fraction
-ENCODING -1
-SWIDTH 167 0
-DWIDTH 4 0
-BBX 5 7 -1 0
-BITMAP
-08
-10
-10
-20
-40
-40
-80
-ENDCHAR
-STARTCHAR grave
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 2 2 0 6
-BITMAP
-80
-40
-ENDCHAR
-STARTCHAR guilsinglleft
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 3 3 1 1
-BITMAP
-60
-C0
-60
-ENDCHAR
-STARTCHAR guilsinglright
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 3 3 1 1
-BITMAP
-C0
-60
-C0
-ENDCHAR
-STARTCHAR hungarumlaut
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 4 2 0 6
-BITMAP
-50
-A0
-ENDCHAR
-STARTCHAR lslash
-ENCODING -1
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 4 8 -1 0
-BITMAP
-60
-60
-60
-70
-E0
-60
-60
-60
-ENDCHAR
-STARTCHAR oe
-ENCODING -1
-SWIDTH 944 0
-DWIDTH 10 0
-BBX 9 6 0 0
-BITMAP
-7700
-CD80
-CF80
-CC00
-CD80
-7700
-ENDCHAR
-STARTCHAR ogonek
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 3 0
-BBX 2 2 0 -2
-BITMAP
-80
-C0
-ENDCHAR
-STARTCHAR perthousand
-ENCODING -1
-SWIDTH 1000 0
-DWIDTH 11 0
-BBX 10 7 0 0
-BITMAP
-6200
-B400
-6800
-1000
-2D80
-56C0
-8D80
-ENDCHAR
-STARTCHAR quotedblbase
-ENCODING -1
-SWIDTH 500 0
-DWIDTH 6 0
-BBX 5 3 0 -2
-BITMAP
-D8
-48
-90
-ENDCHAR
-STARTCHAR quotedblleft
-ENCODING -1
-SWIDTH 500 0
-DWIDTH 6 0
-BBX 5 3 0 5
-BITMAP
-48
-90
-D8
-ENDCHAR
-STARTCHAR quotedblright
-ENCODING -1
-SWIDTH 500 0
-DWIDTH 6 0
-BBX 5 3 0 5
-BITMAP
-D8
-48
-90
-ENDCHAR
-STARTCHAR quotesinglbase
-ENCODING -1
-SWIDTH 278 0
-DWIDTH 3 0
-BBX 2 3 0 -2
-BITMAP
-C0
-40
-80
-ENDCHAR
-STARTCHAR quotesingle
-ENCODING -1
-SWIDTH 238 0
-DWIDTH 3 0
-BBX 1 3 1 5
-BITMAP
-80
-80
-80
-ENDCHAR
-STARTCHAR ring
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 3 3 0 5
-BITMAP
-40
-A0
-40
-ENDCHAR
-STARTCHAR scaron
-ENCODING -1
-SWIDTH 556 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-50
-20
-00
-70
-D8
-70
-18
-D8
-70
-ENDCHAR
-STARTCHAR tilde
-ENCODING -1
-SWIDTH 333 0
-DWIDTH 4 0
-BBX 4 2 0 6
-BITMAP
-50
-A0
-ENDCHAR
-STARTCHAR trademark
-ENCODING -1
-SWIDTH 1000 0
-DWIDTH 11 0
-BBX 9 4 1 3
-BITMAP
-E880
-4D80
-4A80
-4A80
-ENDCHAR
-STARTCHAR zcaron
-ENCODING -1
-SWIDTH 500 0
-DWIDTH 5 0
-BBX 5 9 0 0
-BITMAP
-50
-20
-00
-F8
-18
-30
-60
-C0
-F8
-ENDCHAR
-ENDFONT
+++ /dev/null
-STARTFONT 2.1
-COMMENT $Xorg: $
-COMMENT ISO10646-1 extension by Markus Kuhn <mkuhn@acm.org>, 2001-03-20
-COMMENT (c) Copyright Bigelow & Holmes 1986, 1985. Lucida is a registered
-COMMENT trademark of Bigelow & Holmes. See LEGAL NOTICE file for terms
-COMMENT of the license.
-COMMENT GRID 0014 0014 0200 0200
-FONT -B&H-Lucida-Bold-R-Normal-Sans-14-140-75-75-P-92-ISO10646-1
-SIZE 14 72 72
-FONTBOUNDINGBOX 18 21 -1 -5
-STARTPROPERTIES 22
-COMMENT Begin LogicalFontDescription
-FONTNAME_REGISTRY ""
-FOUNDRY "B&H"
-FAMILY_NAME "Lucida"
-WEIGHT_NAME "Bold"
-SLANT "R"
-SETWIDTH_NAME "Normal"
-ADD_STYLE_NAME "Sans"
-PIXEL_SIZE 14
-POINT_SIZE 140
-RESOLUTION_X 75
-RESOLUTION_Y 75
-SPACING "P"
-AVERAGE_WIDTH 92
-CHARSET_REGISTRY "ISO10646"
-CHARSET_ENCODING "1"
-COMMENT END LogicalFontDescription
-FONT_ASCENT 13
-FONT_DESCENT 2
-DEFAULT_CHAR 0
-COPYRIGHT "Copyright Bigelow & Holmes 1986, 1985."
-FACE_NAME "Lucida Sans Bold"
-X_HEIGHT 8
-CAP_HEIGHT 10
-ENDPROPERTIES
-CHARS 756
-STARTCHAR char0
-ENCODING 0
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 7 9 2 0
-BITMAP
-AA
-00
-82
-00
-82
-00
-82
-00
-AA
-ENDCHAR
-STARTCHAR space
-ENCODING 32
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR exclam
-ENCODING 33
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 10 1 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-80
-80
-00
-C0
-C0
-ENDCHAR
-STARTCHAR quotedbl
-ENCODING 34
-SWIDTH 530 0
-DWIDTH 7 0
-BBX 5 4 1 7
-BITMAP
-D8
-D8
-90
-90
-ENDCHAR
-STARTCHAR numbersign
-ENCODING 35
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 9 10 0 0
-BITMAP
-1B00
-1B00
-1B00
-7F80
-3600
-3600
-FF80
-6C00
-6C00
-6C00
-ENDCHAR
-STARTCHAR dollar
-ENCODING 36
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 12 1 -1
-BITMAP
-10
-7C
-D6
-D0
-F0
-70
-1C
-1E
-16
-D6
-7C
-10
-ENDCHAR
-STARTCHAR percent
-ENCODING 37
-SWIDTH 898 0
-DWIDTH 12 0
-BBX 10 10 1 0
-BITMAP
-7000
-D980
-DB00
-7200
-0400
-0800
-1380
-36C0
-66C0
-0380
-ENDCHAR
-STARTCHAR ampersand
-ENCODING 38
-SWIDTH 792 0
-DWIDTH 11 0
-BBX 9 10 1 0
-BITMAP
-3C00
-6600
-6600
-6400
-3980
-5980
-CD00
-C600
-E700
-7980
-ENDCHAR
-STARTCHAR quotesingle
-ENCODING 39
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-C0
-C0
-80
-80
-ENDCHAR
-STARTCHAR parenleft
-ENCODING 40
-SWIDTH 386 0
-DWIDTH 6 0
-BBX 4 12 1 -1
-BITMAP
-30
-60
-60
-C0
-C0
-C0
-C0
-C0
-C0
-60
-60
-30
-ENDCHAR
-STARTCHAR parenright
-ENCODING 41
-SWIDTH 386 0
-DWIDTH 6 0
-BBX 4 12 1 -1
-BITMAP
-C0
-60
-60
-30
-30
-30
-30
-30
-30
-60
-60
-C0
-ENDCHAR
-STARTCHAR asterisk
-ENCODING 42
-SWIDTH 464 0
-DWIDTH 7 0
-BBX 5 5 1 5
-BITMAP
-20
-A8
-70
-A8
-20
-ENDCHAR
-STARTCHAR plus
-ENCODING 43
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 7 1 1
-BITMAP
-10
-10
-10
-FE
-10
-10
-10
-ENDCHAR
-STARTCHAR comma
-ENCODING 44
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 2 4 1 -2
-BITMAP
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR hyphen
-ENCODING 45
-SWIDTH 289 0
-DWIDTH 5 0
-BBX 3 1 1 4
-BITMAP
-E0
-ENDCHAR
-STARTCHAR period
-ENCODING 46
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 2 2 1 0
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR slash
-ENCODING 47
-SWIDTH 596 0
-DWIDTH 8 0
-BBX 8 12 0 -1
-BITMAP
-03
-06
-06
-0C
-0C
-18
-18
-30
-30
-60
-60
-C0
-ENDCHAR
-STARTCHAR zero
-ENCODING 48
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-3C
-66
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR one
-ENCODING 49
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 5 10 2 0
-BITMAP
-18
-F8
-18
-18
-18
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR two
-ENCODING 50
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-7E
-C7
-03
-03
-06
-0C
-18
-60
-FF
-FF
-ENDCHAR
-STARTCHAR three
-ENCODING 51
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-7E
-C7
-03
-06
-3C
-06
-03
-03
-C7
-7E
-ENDCHAR
-STARTCHAR four
-ENCODING 52
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-0C
-1C
-2C
-4C
-8C
-FF
-FF
-0C
-0C
-0C
-ENDCHAR
-STARTCHAR five
-ENCODING 53
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 10 2 0
-BITMAP
-FC
-FC
-80
-80
-FC
-0E
-06
-06
-CC
-78
-ENDCHAR
-STARTCHAR six
-ENCODING 54
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-3E
-63
-C0
-DC
-E6
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR seven
-ENCODING 55
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-FF
-FF
-06
-0C
-18
-30
-30
-60
-60
-60
-ENDCHAR
-STARTCHAR eight
-ENCODING 56
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-7E
-C7
-C3
-72
-3C
-4E
-C7
-C3
-E3
-7E
-ENDCHAR
-STARTCHAR nine
-ENCODING 57
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-3C
-66
-C3
-C3
-C3
-67
-1B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR colon
-ENCODING 58
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 2 7 1 0
-BITMAP
-C0
-C0
-00
-00
-00
-C0
-C0
-ENDCHAR
-STARTCHAR semicolon
-ENCODING 59
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 2 9 1 -2
-BITMAP
-C0
-C0
-00
-00
-00
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR less
-ENCODING 60
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 6 7 2 1
-BITMAP
-0C
-38
-60
-C0
-60
-38
-0C
-ENDCHAR
-STARTCHAR equal
-ENCODING 61
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 3 1 3
-BITMAP
-FE
-00
-FE
-ENDCHAR
-STARTCHAR greater
-ENCODING 62
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 6 7 2 1
-BITMAP
-C0
-70
-18
-0C
-18
-70
-C0
-ENDCHAR
-STARTCHAR question
-ENCODING 63
-SWIDTH 572 0
-DWIDTH 8 0
-BBX 6 10 1 0
-BITMAP
-78
-CC
-0C
-0C
-18
-30
-30
-00
-30
-30
-ENDCHAR
-STARTCHAR at
-ENCODING 64
-SWIDTH 833 0
-DWIDTH 12 0
-BBX 10 10 1 0
-BITMAP
-1E00
-6100
-4180
-8F80
-9980
-9980
-9980
-4EC0
-6000
-1F00
-ENDCHAR
-STARTCHAR A
-ENCODING 65
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 10 1 0
-BITMAP
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR B
-ENCODING 66
-SWIDTH 669 0
-DWIDTH 10 0
-BBX 7 10 2 0
-BITMAP
-FC
-C6
-C6
-CC
-F0
-CC
-C6
-C6
-C6
-FC
-ENDCHAR
-STARTCHAR C
-ENCODING 67
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-ENDCHAR
-STARTCHAR D
-ENCODING 68
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 10 2 0
-BITMAP
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-ENDCHAR
-STARTCHAR E
-ENCODING 69
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR F
-ENCODING 70
-SWIDTH 602 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR G
-ENCODING 71
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR H
-ENCODING 72
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 10 2 0
-BITMAP
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR I
-ENCODING 73
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 2 10 2 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR J
-ENCODING 74
-SWIDTH 501 0
-DWIDTH 6 0
-BBX 4 12 0 -2
-BITMAP
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-E0
-ENDCHAR
-STARTCHAR K
-ENCODING 75
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR L
-ENCODING 76
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR M
-ENCODING 77
-SWIDTH 940 0
-DWIDTH 15 0
-BBX 11 10 2 0
-BITMAP
-E0E0
-E0E0
-B160
-B160
-B160
-9A60
-9A60
-8C60
-8C60
-8060
-ENDCHAR
-STARTCHAR N
-ENCODING 78
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 10 2 0
-BITMAP
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR O
-ENCODING 79
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 10 1 0
-BITMAP
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR P
-ENCODING 80
-SWIDTH 657 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-F8
-CC
-CC
-CC
-CC
-F8
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Q
-ENCODING 81
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 12 1 -2
-BITMAP
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-0300
-0180
-ENDCHAR
-STARTCHAR R
-ENCODING 82
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR S
-ENCODING 83
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR T
-ENCODING 84
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR U
-ENCODING 85
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 10 2 0
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR V
-ENCODING 86
-SWIDTH 735 0
-DWIDTH 11 0
-BBX 9 10 1 0
-BITMAP
-C180
-C180
-C180
-6100
-6300
-6300
-3200
-3600
-1C00
-1C00
-ENDCHAR
-STARTCHAR W
-ENCODING 87
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 10 1 0
-BITMAP
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR X
-ENCODING 88
-SWIDTH 699 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-C6
-C6
-6C
-6C
-38
-38
-6C
-6C
-C6
-C6
-ENDCHAR
-STARTCHAR Y
-ENCODING 89
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR Z
-ENCODING 90
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-ENDCHAR
-STARTCHAR bracketleft
-ENCODING 91
-SWIDTH 386 0
-DWIDTH 6 0
-BBX 4 12 1 -1
-BITMAP
-F0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-F0
-ENDCHAR
-STARTCHAR backslash
-ENCODING 92
-SWIDTH 596 0
-DWIDTH 8 0
-BBX 8 12 0 -1
-BITMAP
-C0
-60
-60
-30
-30
-18
-18
-0C
-0C
-06
-06
-03
-ENDCHAR
-STARTCHAR bracketright
-ENCODING 93
-SWIDTH 386 0
-DWIDTH 6 0
-BBX 4 12 1 -1
-BITMAP
-F0
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-F0
-ENDCHAR
-STARTCHAR asciicircum
-ENCODING 94
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 6 7 2 3
-BITMAP
-30
-30
-78
-48
-CC
-84
-84
-ENDCHAR
-STARTCHAR underscore
-ENCODING 95
-SWIDTH 500 0
-DWIDTH 11 0
-BBX 9 1 1 -1
-BITMAP
-FF80
-ENDCHAR
-STARTCHAR grave
-ENCODING 96
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 2 9
-BITMAP
-E0
-38
-ENDCHAR
-STARTCHAR a
-ENCODING 97
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 8 1 0
-BITMAP
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR b
-ENCODING 98
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-C0
-C0
-C0
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-ENDCHAR
-STARTCHAR c
-ENCODING 99
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR d
-ENCODING 100
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-03
-03
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-ENDCHAR
-STARTCHAR e
-ENCODING 101
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR f
-ENCODING 102
-SWIDTH 461 0
-DWIDTH 7 0
-BBX 7 11 0 0
-BITMAP
-1E
-30
-30
-FE
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR g
-ENCODING 103
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR h
-ENCODING 104
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR i
-ENCODING 105
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 2 11 1 0
-BITMAP
-C0
-C0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR j
-ENCODING 106
-SWIDTH 361 0
-DWIDTH 5 0
-BBX 4 13 0 -2
-BITMAP
-30
-30
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-E0
-ENDCHAR
-STARTCHAR k
-ENCODING 107
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-C0
-C0
-C0
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-ENDCHAR
-STARTCHAR l
-ENCODING 108
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 2 11 1 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR m
-ENCODING 109
-SWIDTH 1006 0
-DWIDTH 14 0
-BBX 12 8 1 0
-BITMAP
-DDE0
-EF70
-C630
-C630
-C630
-C630
-C630
-C630
-ENDCHAR
-STARTCHAR n
-ENCODING 110
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR o
-ENCODING 111
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR p
-ENCODING 112
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-C0
-C0
-ENDCHAR
-STARTCHAR q
-ENCODING 113
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-03
-03
-ENDCHAR
-STARTCHAR r
-ENCODING 114
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 8 2 0
-BITMAP
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR s
-ENCODING 115
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 8 1 0
-BITMAP
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR t
-ENCODING 116
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 10 1 0
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-ENDCHAR
-STARTCHAR u
-ENCODING 117
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR v
-ENCODING 118
-SWIDTH 663 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-C6
-C6
-C6
-C6
-64
-68
-38
-38
-ENDCHAR
-STARTCHAR w
-ENCODING 119
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 8 1 0
-BITMAP
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR x
-ENCODING 120
-SWIDTH 568 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-C6
-C6
-64
-38
-38
-4C
-C6
-C6
-ENDCHAR
-STARTCHAR y
-ENCODING 121
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 10 1 -2
-BITMAP
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR z
-ENCODING 122
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-ENDCHAR
-STARTCHAR braceleft
-ENCODING 123
-SWIDTH 386 0
-DWIDTH 6 0
-BBX 4 12 1 -1
-BITMAP
-70
-C0
-C0
-60
-20
-C0
-20
-60
-C0
-C0
-C0
-70
-ENDCHAR
-STARTCHAR bar
-ENCODING 124
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 12 1 -1
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR braceright
-ENCODING 125
-SWIDTH 386 0
-DWIDTH 6 0
-BBX 4 12 1 -1
-BITMAP
-E0
-30
-30
-60
-40
-30
-40
-60
-30
-30
-30
-E0
-ENDCHAR
-STARTCHAR asciitilde
-ENCODING 126
-SWIDTH 687 0
-DWIDTH 9 0
-BBX 7 3 1 3
-BITMAP
-72
-BA
-9C
-ENDCHAR
-STARTCHAR space
-ENCODING 160
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR exclamdown
-ENCODING 161
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 10 1 -2
-BITMAP
-C0
-C0
-00
-40
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR cent
-ENCODING 162
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 12 1 -1
-BITMAP
-08
-08
-3E
-6A
-C8
-C8
-C8
-C8
-68
-3E
-08
-08
-ENDCHAR
-STARTCHAR sterling
-ENCODING 163
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 10 1 0
-BITMAP
-1C
-32
-30
-30
-FC
-30
-30
-30
-60
-FE
-ENDCHAR
-STARTCHAR currency
-ENCODING 164
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 9 10 0 0
-BITMAP
-8080
-4100
-3E00
-6300
-6300
-6300
-6300
-3E00
-4100
-8080
-ENDCHAR
-STARTCHAR yen
-ENCODING 165
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-C3
-C3
-62
-66
-34
-7E
-18
-7E
-18
-18
-ENDCHAR
-STARTCHAR brokenbar
-ENCODING 166
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 12 1 -1
-BITMAP
-C0
-C0
-C0
-C0
-C0
-00
-00
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR section
-ENCODING 167
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 6 11 2 -1
-BITMAP
-78
-CC
-C0
-70
-D8
-CC
-6C
-38
-0C
-CC
-78
-ENDCHAR
-STARTCHAR dieresis
-ENCODING 168
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 2 3 9
-BITMAP
-90
-90
-ENDCHAR
-STARTCHAR copyright
-ENCODING 169
-SWIDTH 825 0
-DWIDTH 12 0
-BBX 10 10 1 0
-BITMAP
-1E00
-6180
-4080
-8E40
-9840
-9840
-8E40
-4080
-6180
-1E00
-ENDCHAR
-STARTCHAR ordfeminine
-ENCODING 170
-SWIDTH 536 0
-DWIDTH 8 0
-BBX 6 6 1 4
-BITMAP
-70
-18
-78
-D8
-D8
-6C
-ENDCHAR
-STARTCHAR guillemotleft
-ENCODING 171
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 8 5 0 2
-BITMAP
-33
-66
-CC
-66
-33
-ENDCHAR
-STARTCHAR logicalnot
-ENCODING 172
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 4 1 1
-BITMAP
-FE
-02
-02
-02
-ENDCHAR
-STARTCHAR hyphen
-ENCODING 173
-SWIDTH 289 0
-DWIDTH 5 0
-BBX 3 1 1 4
-BITMAP
-E0
-ENDCHAR
-STARTCHAR registered
-ENCODING 174
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 7 1 3
-BITMAP
-38
-44
-BA
-B2
-AA
-44
-38
-ENDCHAR
-STARTCHAR macron
-ENCODING 175
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 1 3 9
-BITMAP
-F0
-ENDCHAR
-STARTCHAR degree
-ENCODING 176
-SWIDTH 241 0
-DWIDTH 4 0
-BBX 4 3 0 7
-BITMAP
-60
-90
-60
-ENDCHAR
-STARTCHAR plusminus
-ENCODING 177
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 7 1 1
-BITMAP
-10
-10
-FE
-10
-10
-00
-FE
-ENDCHAR
-STARTCHAR twosuperior
-ENCODING 178
-SWIDTH 536 0
-DWIDTH 7 0
-BBX 5 6 1 4
-BITMAP
-F0
-18
-18
-60
-C0
-F8
-ENDCHAR
-STARTCHAR threesuperior
-ENCODING 179
-SWIDTH 536 0
-DWIDTH 7 0
-BBX 5 6 1 4
-BITMAP
-F0
-18
-70
-18
-18
-F0
-ENDCHAR
-STARTCHAR acute
-ENCODING 180
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 3 9
-BITMAP
-38
-E0
-ENDCHAR
-STARTCHAR mu
-ENCODING 181
-SWIDTH 699 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-FB
-C0
-C0
-ENDCHAR
-STARTCHAR paragraph
-ENCODING 182
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 6 11 2 -1
-BITMAP
-7C
-F4
-F4
-F4
-F4
-74
-14
-14
-14
-14
-14
-ENDCHAR
-STARTCHAR periodcentered
-ENCODING 183
-SWIDTH 343 0
-DWIDTH 10 0
-BBX 2 2 4 3
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR cedilla
-ENCODING 184
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 3 2 3 -2
-BITMAP
-20
-C0
-ENDCHAR
-STARTCHAR onesuperior
-ENCODING 185
-SWIDTH 536 0
-DWIDTH 7 0
-BBX 4 6 1 4
-BITMAP
-30
-F0
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR ordmasculine
-ENCODING 186
-SWIDTH 536 0
-DWIDTH 8 0
-BBX 6 6 1 4
-BITMAP
-78
-CC
-CC
-CC
-CC
-78
-ENDCHAR
-STARTCHAR guillemotright
-ENCODING 187
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 8 5 1 2
-BITMAP
-CC
-66
-33
-66
-CC
-ENDCHAR
-STARTCHAR onequarter
-ENCODING 188
-SWIDTH 1066 0
-DWIDTH 14 0
-BBX 12 10 1 0
-BITMAP
-6100
-E100
-6200
-6200
-64E0
-6560
-0A60
-0BF0
-1060
-1060
-ENDCHAR
-STARTCHAR onehalf
-ENCODING 189
-SWIDTH 1066 0
-DWIDTH 14 0
-BBX 12 10 1 0
-BITMAP
-6100
-E100
-6200
-6200
-64E0
-6530
-0870
-08E0
-1180
-11F0
-ENDCHAR
-STARTCHAR threequarters
-ENCODING 190
-SWIDTH 1120 0
-DWIDTH 15 0
-BBX 13 10 1 0
-BITMAP
-7080
-9880
-3100
-1A00
-9A70
-74B0
-0530
-09F8
-1030
-1030
-ENDCHAR
-STARTCHAR questiondown
-ENCODING 191
-SWIDTH 572 0
-DWIDTH 8 0
-BBX 6 10 1 -2
-BITMAP
-30
-30
-00
-30
-30
-60
-C0
-C0
-CC
-78
-ENDCHAR
-STARTCHAR Agrave
-ENCODING 192
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-7000
-1C00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR Aacute
-ENCODING 193
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-0700
-1C00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR Acircumflex
-ENCODING 194
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1C00
-2600
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR Atilde
-ENCODING 195
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1A00
-2C00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR Adieresis
-ENCODING 196
-SWIDTH 773 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-24
-24
-00
-18
-18
-2C
-2C
-66
-46
-FE
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR Aring
-ENCODING 197
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1C00
-2600
-1C00
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR AE
-ENCODING 198
-SWIDTH 997 0
-DWIDTH 13 0
-BBX 11 10 1 0
-BITMAP
-1FE0
-1600
-2600
-2600
-67C0
-4600
-7E00
-C600
-C600
-C7E0
-ENDCHAR
-STARTCHAR Ccedilla
-ENCODING 199
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 12 2 -2
-BITMAP
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-08
-30
-ENDCHAR
-STARTCHAR Egrave
-ENCODING 200
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-70
-1C
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR Eacute
-ENCODING 201
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-1C
-70
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR Ecircumflex
-ENCODING 202
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-30
-58
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR Edieresis
-ENCODING 203
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-48
-48
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR Igrave
-ENCODING 204
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 4 13 1 0
-BITMAP
-E0
-30
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Iacute
-ENCODING 205
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 4 13 1 0
-BITMAP
-70
-C0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Icircumflex
-ENCODING 206
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 4 13 1 0
-BITMAP
-60
-B0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Idieresis
-ENCODING 207
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 4 13 1 0
-BITMAP
-90
-90
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Eth
-ENCODING 208
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 11 10 0 0
-BITMAP
-3F80
-30C0
-3060
-3060
-FC60
-3060
-3060
-3060
-30C0
-3F80
-ENDCHAR
-STARTCHAR Ntilde
-ENCODING 209
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-1A
-2C
-00
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR Ograve
-ENCODING 210
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-3800
-0E00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR Oacute
-ENCODING 211
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-0700
-1C00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR Ocircumflex
-ENCODING 212
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-0C00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR Otilde
-ENCODING 213
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-0D00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR Odieresis
-ENCODING 214
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-2100
-2100
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR multiply
-ENCODING 215
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 5 5 2 2
-BITMAP
-C8
-70
-20
-70
-98
-ENDCHAR
-STARTCHAR Oslash
-ENCODING 216
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 12 1 -1
-BITMAP
-0040
-3F40
-6180
-C2C0
-C2C0
-C4C0
-C8C0
-D0C0
-D0C0
-6180
-BF00
-8000
-ENDCHAR
-STARTCHAR Ugrave
-ENCODING 217
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-70
-1C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR Uacute
-ENCODING 218
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-0E
-38
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR Ucircumflex
-ENCODING 219
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-18
-2C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR Udieresis
-ENCODING 220
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-64
-3C
-ENDCHAR
-STARTCHAR Yacute
-ENCODING 221
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-0E
-38
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR Thorn
-ENCODING 222
-SWIDTH 657 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-C0
-C0
-F8
-CC
-CC
-CC
-CC
-F8
-C0
-C0
-ENDCHAR
-STARTCHAR germandbls
-ENCODING 223
-SWIDTH 724 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-7C
-C6
-C6
-C4
-CC
-C6
-C3
-C3
-C3
-C3
-CE
-ENDCHAR
-STARTCHAR agrave
-ENCODING 224
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-70
-1C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR aacute
-ENCODING 225
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-0E
-38
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR acircumflex
-ENCODING 226
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-18
-2C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR atilde
-ENCODING 227
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-34
-58
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR adieresis
-ENCODING 228
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-24
-24
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR aring
-ENCODING 229
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-18
-2C
-18
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR ae
-ENCODING 230
-SWIDTH 913 0
-DWIDTH 14 0
-BBX 12 8 1 0
-BITMAP
-7DE0
-0730
-0630
-7FF0
-C600
-C600
-C710
-79E0
-ENDCHAR
-STARTCHAR ccedilla
-ENCODING 231
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 10 1 -2
-BITMAP
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-10
-60
-ENDCHAR
-STARTCHAR egrave
-ENCODING 232
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-70
-1C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR eacute
-ENCODING 233
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-0E
-38
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR ecircumflex
-ENCODING 234
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-18
-2C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR edieresis
-ENCODING 235
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-44
-44
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR igrave
-ENCODING 236
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 11 0 0
-BITMAP
-E0
-30
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR iacute
-ENCODING 237
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 11 0 0
-BITMAP
-70
-C0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR icircumflex
-ENCODING 238
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 11 0 0
-BITMAP
-60
-B0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR idieresis
-ENCODING 239
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 11 0 0
-BITMAP
-90
-90
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR eth
-ENCODING 240
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-10
-3E
-0C
-3E
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR ntilde
-ENCODING 241
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-1A
-2C
-00
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR ograve
-ENCODING 242
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-70
-1C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR oacute
-ENCODING 243
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-0E
-38
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR ocircumflex
-ENCODING 244
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-18
-2C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR otilde
-ENCODING 245
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-34
-58
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR odieresis
-ENCODING 246
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-24
-24
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR divide
-ENCODING 247
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 7 1 1
-BITMAP
-10
-10
-00
-FE
-00
-10
-10
-ENDCHAR
-STARTCHAR oslash
-ENCODING 248
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 10 1 -1
-BITMAP
-01
-3D
-66
-CB
-CB
-D3
-D3
-66
-BC
-80
-ENDCHAR
-STARTCHAR ugrave
-ENCODING 249
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-70
-1C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uacute
-ENCODING 250
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-1C
-70
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR ucircumflex
-ENCODING 251
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-18
-2C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR udieresis
-ENCODING 252
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR yacute
-ENCODING 253
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-1C
-70
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR thorn
-ENCODING 254
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-C0
-C0
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-C0
-C0
-ENDCHAR
-STARTCHAR ydieresis
-ENCODING 255
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-44
-44
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR Amacron
-ENCODING 256
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 12 1 0
-BITMAP
-1E00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR amacron
-ENCODING 257
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 10 1 0
-BITMAP
-3C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR Abreve
-ENCODING 258
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-2100
-1E00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR abreve
-ENCODING 259
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-42
-3C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR Aogonek
-ENCODING 260
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 12 1 -2
-BITMAP
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-0800
-0600
-ENDCHAR
-STARTCHAR aogonek
-ENCODING 261
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 10 1 -2
-BITMAP
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-10
-0C
-ENDCHAR
-STARTCHAR Cacute
-ENCODING 262
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-0E
-38
-00
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-ENDCHAR
-STARTCHAR cacute
-ENCODING 263
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-0E
-38
-00
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Ccircumflex
-ENCODING 264
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-18
-2C
-00
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-ENDCHAR
-STARTCHAR ccircumflex
-ENCODING 265
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-30
-58
-00
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Cdotaccent
-ENCODING 266
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-18
-18
-00
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-ENDCHAR
-STARTCHAR cdotaccent
-ENCODING 267
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-30
-30
-00
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Ccaron
-ENCODING 268
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-2C
-18
-00
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-ENDCHAR
-STARTCHAR ccaron
-ENCODING 269
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-58
-30
-00
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Dcaron
-ENCODING 270
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 13 2 0
-BITMAP
-2C00
-1800
-0000
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-ENDCHAR
-STARTCHAR dcaron
-ENCODING 271
-SWIDTH 926 0
-DWIDTH 14 0
-BBX 12 11 1 0
-BITMAP
-0330
-0330
-0310
-3F20
-6300
-C300
-C300
-C300
-C300
-6700
-3B00
-ENDCHAR
-STARTCHAR Dcroat
-ENCODING 272
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 11 10 0 0
-BITMAP
-3F80
-30C0
-3060
-3060
-FC60
-3060
-3060
-3060
-30C0
-3F80
-ENDCHAR
-STARTCHAR dcroat
-ENCODING 273
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-03
-1F
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-ENDCHAR
-STARTCHAR Emacron
-ENCODING 274
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 12 2 0
-BITMAP
-F0
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR emacron
-ENCODING 275
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-3C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Ebreve
-ENCODING 276
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-84
-78
-00
-7E
-60
-60
-60
-7C
-60
-60
-60
-60
-7E
-ENDCHAR
-STARTCHAR ebreve
-ENCODING 277
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-42
-3C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Edotaccent
-ENCODING 278
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-60
-60
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR edotaccent
-ENCODING 279
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-18
-18
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Eogonek
-ENCODING 280
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 12 2 -2
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-20
-18
-ENDCHAR
-STARTCHAR eogonek
-ENCODING 281
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 10 1 -2
-BITMAP
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-20
-18
-ENDCHAR
-STARTCHAR Ecaron
-ENCODING 282
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-B0
-60
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR ecaron
-ENCODING 283
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-2C
-18
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR Gcircumflex
-ENCODING 284
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-18
-2C
-00
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR gcircumflex
-ENCODING 285
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-18
-2C
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR Gbreve
-ENCODING 286
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-42
-3C
-00
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR gbreve
-ENCODING 287
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-42
-3C
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR Gdotaccent
-ENCODING 288
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-18
-18
-00
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR gdotaccent
-ENCODING 289
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-18
-18
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR Gcommaaccent
-ENCODING 290
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 15 2 -5
-BITMAP
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR gcommaaccent
-ENCODING 291
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 15 1 -2
-BITMAP
-08
-10
-18
-18
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR Hcircumflex
-ENCODING 292
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-18
-2C
-00
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR hcircumflex
-ENCODING 293
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-60
-B0
-00
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR Hbar
-ENCODING 294
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 10 2 0
-BITMAP
-C3
-FF
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR hbar
-ENCODING 295
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-C0
-F8
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR Itilde
-ENCODING 296
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 5 13 1 0
-BITMAP
-68
-B0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR itilde
-ENCODING 297
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 5 11 0 0
-BITMAP
-68
-B0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Imacron
-ENCODING 298
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 4 12 1 0
-BITMAP
-F0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR imacron
-ENCODING 299
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 10 0 0
-BITMAP
-F0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Ibreve
-ENCODING 300
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 6 13 0 0
-BITMAP
-84
-78
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR ibreve
-ENCODING 301
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 6 11 -1 0
-BITMAP
-84
-78
-00
-30
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR Iogonek
-ENCODING 302
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 3 12 2 -2
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-80
-60
-ENDCHAR
-STARTCHAR iogonek
-ENCODING 303
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 3 13 1 -2
-BITMAP
-C0
-C0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-80
-60
-ENDCHAR
-STARTCHAR Idotaccent
-ENCODING 304
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 2 13 2 0
-BITMAP
-C0
-C0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR dotlessi
-ENCODING 305
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 2 8 1 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR IJ
-ENCODING 306
-SWIDTH 844 0
-DWIDTH 12 0
-BBX 8 12 2 -2
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-03
-0E
-ENDCHAR
-STARTCHAR ij
-ENCODING 307
-SWIDTH 704 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-C6
-C6
-00
-C6
-C6
-C6
-C6
-C6
-C6
-C6
-C6
-06
-1C
-ENDCHAR
-STARTCHAR Jcircumflex
-ENCODING 308
-SWIDTH 501 0
-DWIDTH 6 0
-BBX 5 15 0 -2
-BITMAP
-30
-58
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-E0
-ENDCHAR
-STARTCHAR jcircumflex
-ENCODING 309
-SWIDTH 361 0
-DWIDTH 5 0
-BBX 5 13 0 -2
-BITMAP
-30
-58
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-E0
-ENDCHAR
-STARTCHAR Kcommaaccent
-ENCODING 310
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 15 2 -5
-BITMAP
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR kcommaaccent
-ENCODING 311
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 16 1 -5
-BITMAP
-C0
-C0
-C0
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR kgreenlandic
-ENCODING 312
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 8 1 0
-BITMAP
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-ENDCHAR
-STARTCHAR Lacute
-ENCODING 313
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-38
-E0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR lacute
-ENCODING 314
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 5 14 0 0
-BITMAP
-38
-E0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR Lcommaaccent
-ENCODING 315
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 15 2 -5
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-00
-60
-60
-20
-40
-ENDCHAR
-STARTCHAR lcommaaccent
-ENCODING 316
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 2 16 1 -5
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-00
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR Lcaron
-ENCODING 317
-SWIDTH 854 0
-DWIDTH 13 0
-BBX 10 11 2 0
-BITMAP
-00C0
-C0C0
-C040
-C080
-C000
-C000
-C000
-C000
-C000
-C000
-FC00
-ENDCHAR
-STARTCHAR lcaron
-ENCODING 318
-SWIDTH 608 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-CC
-CC
-C4
-C8
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Ldot
-ENCODING 319
-SWIDTH 932 0
-DWIDTH 19 0
-BBX 13 10 2 0
-BITMAP
-C000
-C000
-C000
-C000
-C000
-C018
-C018
-C000
-C000
-FC00
-ENDCHAR
-STARTCHAR ldot
-ENCODING 320
-SWIDTH 686 0
-DWIDTH 14 0
-BBX 9 11 1 0
-BITMAP
-C000
-C000
-C000
-C000
-C000
-C000
-C180
-C180
-C000
-C000
-C000
-ENDCHAR
-STARTCHAR Lslash
-ENCODING 321
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 8 10 0 0
-BITMAP
-30
-30
-30
-30
-3C
-F0
-30
-30
-30
-3F
-ENDCHAR
-STARTCHAR lslash
-ENCODING 322
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 6 11 0 0
-BITMAP
-30
-30
-30
-30
-3C
-F0
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR Nacute
-ENCODING 323
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-0E
-38
-00
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR nacute
-ENCODING 324
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-0E
-38
-00
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR Ncommaaccent
-ENCODING 325
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 15 2 -5
-BITMAP
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-00
-0C
-0C
-04
-08
-ENDCHAR
-STARTCHAR ncommaaccent
-ENCODING 326
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 13 1 -5
-BITMAP
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR Ncaron
-ENCODING 327
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-58
-30
-00
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR ncaron
-ENCODING 328
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-2C
-18
-00
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR napostrophe
-ENCODING 329
-SWIDTH 945 0
-DWIDTH 14 0
-BBX 12 11 1 0
-BITMAP
-C000
-C000
-4000
-8DE0
-0E70
-0C30
-0C30
-0C30
-0C30
-0C30
-0C30
-ENDCHAR
-STARTCHAR Eng
-ENCODING 330
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 12 2 -2
-BITMAP
-E1
-E1
-B1
-B1
-99
-99
-8F
-8F
-87
-87
-03
-0E
-ENDCHAR
-STARTCHAR eng
-ENCODING 331
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-03
-0E
-ENDCHAR
-STARTCHAR Omacron
-ENCODING 332
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 12 1 0
-BITMAP
-1E00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR omacron
-ENCODING 333
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-3C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR Obreve
-ENCODING 334
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-2100
-1E00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR obreve
-ENCODING 335
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-42
-3C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR Ohungarumlaut
-ENCODING 336
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-1B00
-1200
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR ohungarumlaut
-ENCODING 337
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-36
-24
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR OE
-ENCODING 338
-SWIDTH 1102 0
-DWIDTH 15 0
-BBX 13 10 1 0
-BITMAP
-3DF8
-6380
-C180
-C180
-C1F0
-C180
-C180
-C180
-6380
-3DF8
-ENDCHAR
-STARTCHAR oe
-ENCODING 339
-SWIDTH 990 0
-DWIDTH 15 0
-BBX 13 8 1 0
-BITMAP
-3CF0
-6398
-C318
-C3F8
-C300
-C300
-6388
-3CF0
-ENDCHAR
-STARTCHAR Racute
-ENCODING 340
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-0E
-38
-00
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR racute
-ENCODING 341
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 11 2 0
-BITMAP
-38
-E0
-00
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Rcommaaccent
-ENCODING 342
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 15 2 -5
-BITMAP
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR rcommaaccent
-ENCODING 343
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 13 2 -5
-BITMAP
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-00
-60
-60
-20
-40
-ENDCHAR
-STARTCHAR Rcaron
-ENCODING 344
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-2C
-18
-00
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR rcaron
-ENCODING 345
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 11 2 0
-BITMAP
-B0
-60
-00
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR Sacute
-ENCODING 346
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-1C
-70
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR sacute
-ENCODING 347
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-1C
-70
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR Scircumflex
-ENCODING 348
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-30
-58
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR scircumflex
-ENCODING 349
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-60
-B0
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR Scedilla
-ENCODING 350
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 12 1 -2
-BITMAP
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-08
-30
-ENDCHAR
-STARTCHAR scedilla
-ENCODING 351
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 10 1 -2
-BITMAP
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-10
-60
-ENDCHAR
-STARTCHAR Scaron
-ENCODING 352
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-2C
-18
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR scaron
-ENCODING 353
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-58
-30
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR Tcommaaccent
-ENCODING 354
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-08
-30
-ENDCHAR
-STARTCHAR tcommaaccent
-ENCODING 355
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 12 1 -2
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-20
-C0
-ENDCHAR
-STARTCHAR Tcaron
-ENCODING 356
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-2C
-18
-00
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR tcaron
-ENCODING 357
-SWIDTH 679 0
-DWIDTH 11 0
-BBX 9 11 1 0
-BITMAP
-0180
-6180
-6080
-F900
-6000
-6000
-6000
-6000
-6000
-6000
-3800
-ENDCHAR
-STARTCHAR Tbar
-ENCODING 358
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-FF
-18
-18
-18
-3E
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR tbar
-ENCODING 359
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 10 1 0
-BITMAP
-60
-60
-F8
-60
-60
-F8
-60
-60
-60
-38
-ENDCHAR
-STARTCHAR Utilde
-ENCODING 360
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-1A
-2C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR utilde
-ENCODING 361
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-1A
-2C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR Umacron
-ENCODING 362
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 12 2 0
-BITMAP
-3C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR umacron
-ENCODING 363
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-3C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR Ubreve
-ENCODING 364
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-42
-3C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR ubreve
-ENCODING 365
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-42
-3C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR Uring
-ENCODING 366
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 14 2 0
-BITMAP
-18
-2C
-18
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uring
-ENCODING 367
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 12 1 0
-BITMAP
-18
-2C
-18
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR Uhungarumlaut
-ENCODING 368
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-36
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uhungarumlaut
-ENCODING 369
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-36
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR Uogonek
-ENCODING 370
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 12 2 -2
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-10
-0C
-ENDCHAR
-STARTCHAR uogonek
-ENCODING 371
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-10
-0C
-ENDCHAR
-STARTCHAR Wcircumflex
-ENCODING 372
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 13 1 0
-BITMAP
-0C00
-1600
-0000
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR wcircumflex
-ENCODING 373
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 11 1 0
-BITMAP
-0C00
-1600
-0000
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR Ycircumflex
-ENCODING 374
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-18
-2C
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR ycircumflex
-ENCODING 375
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-30
-58
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR Ydieresis
-ENCODING 376
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-24
-24
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR Zacute
-ENCODING 377
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-0E
-38
-00
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-ENDCHAR
-STARTCHAR zacute
-ENCODING 378
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-0E
-38
-00
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-ENDCHAR
-STARTCHAR Zdotaccent
-ENCODING 379
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-18
-18
-00
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-ENDCHAR
-STARTCHAR zdotaccent
-ENCODING 380
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-18
-18
-00
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-ENDCHAR
-STARTCHAR Zcaron
-ENCODING 381
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-2C
-18
-00
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-ENDCHAR
-STARTCHAR zcaron
-ENCODING 382
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-2C
-18
-00
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-ENDCHAR
-STARTCHAR uni0186
-ENCODING 390
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-7C
-C6
-03
-03
-03
-03
-03
-03
-C6
-7C
-ENDCHAR
-STARTCHAR uni0189
-ENCODING 393
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 11 10 0 0
-BITMAP
-3F80
-30C0
-3060
-3060
-FC60
-3060
-3060
-3060
-30C0
-3F80
-ENDCHAR
-STARTCHAR uni018E
-ENCODING 398
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-FC
-0C
-0C
-0C
-0C
-7C
-0C
-0C
-0C
-FC
-ENDCHAR
-STARTCHAR florin
-ENCODING 402
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 11 2 -1
-BITMAP
-1C
-32
-30
-30
-FC
-60
-60
-60
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni0197
-ENCODING 407
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 5 10 1 0
-BITMAP
-60
-60
-60
-60
-F8
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni019A
-ENCODING 410
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 5 11 0 0
-BITMAP
-60
-60
-60
-60
-60
-F8
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni019D
-ENCODING 413
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 10 12 0 -2
-BITMAP
-3840
-3840
-2C40
-2C40
-2640
-2640
-3340
-3140
-31C0
-31C0
-3000
-E000
-ENDCHAR
-STARTCHAR uni019F
-ENCODING 415
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 10 1 0
-BITMAP
-3F00
-6180
-C0C0
-C0C0
-FFC0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR Ohorn
-ENCODING 416
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 11 10 1 0
-BITMAP
-3F60
-61E0
-C0E0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR ohorn
-ENCODING 417
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 10 8 1 0
-BITMAP
-3CC0
-66C0
-C340
-C380
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni01A7
-ENCODING 423
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-7C
-C6
-06
-0E
-3C
-78
-E0
-C0
-C6
-7C
-ENDCHAR
-STARTCHAR uni01A8
-ENCODING 424
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 8 1 0
-BITMAP
-F8
-0C
-0C
-3C
-F0
-C0
-C0
-7C
-ENDCHAR
-STARTCHAR uni01AE
-ENCODING 430
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-18
-0E
-ENDCHAR
-STARTCHAR Uhorn
-ENCODING 431
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 10 10 2 0
-BITMAP
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uhorn
-ENCODING 432
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 10 8 1 0
-BITMAP
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-E700
-7B00
-ENDCHAR
-STARTCHAR uni01B5
-ENCODING 437
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-FE
-06
-0C
-1C
-7C
-30
-70
-60
-C0
-FE
-ENDCHAR
-STARTCHAR uni01B6
-ENCODING 438
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-FE
-06
-0C
-7C
-30
-60
-C0
-FE
-ENDCHAR
-STARTCHAR uni01BB
-ENCODING 443
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 10 1 0
-BITMAP
-7E
-C7
-03
-03
-FF
-0C
-18
-60
-FF
-FF
-ENDCHAR
-STARTCHAR uni01BC
-ENCODING 444
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 10 2 0
-BITMAP
-FC
-FC
-80
-80
-FC
-0E
-06
-06
-CC
-78
-ENDCHAR
-STARTCHAR uni01C0
-ENCODING 448
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 12 1 -1
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni01C2
-ENCODING 450
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 12 1 -1
-BITMAP
-18
-18
-18
-18
-18
-FE
-18
-FE
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR uni01C3
-ENCODING 451
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 10 1 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-80
-80
-00
-C0
-C0
-ENDCHAR
-STARTCHAR uni01CD
-ENCODING 461
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1600
-0C00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni01CE
-ENCODING 462
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-2C
-18
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni01CF
-ENCODING 463
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 4 13 1 0
-BITMAP
-B0
-60
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni01D0
-ENCODING 464
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 11 0 0
-BITMAP
-B0
-60
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni01D1
-ENCODING 465
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-1600
-0C00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni01D2
-ENCODING 466
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-2C
-18
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni01D3
-ENCODING 467
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-2C
-18
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni01D4
-ENCODING 468
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-2C
-18
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni01D5
-ENCODING 469
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 15 2 0
-BITMAP
-3C
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-64
-3C
-ENDCHAR
-STARTCHAR uni01D6
-ENCODING 470
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-3C
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni01D7
-ENCODING 471
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 16 2 0
-BITMAP
-0E
-38
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-64
-3C
-ENDCHAR
-STARTCHAR uni01D8
-ENCODING 472
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-0E
-38
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni01D9
-ENCODING 473
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 16 2 0
-BITMAP
-2C
-18
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-64
-3C
-ENDCHAR
-STARTCHAR uni01DA
-ENCODING 474
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-2C
-18
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni01DB
-ENCODING 475
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 16 2 0
-BITMAP
-70
-1C
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-64
-3C
-ENDCHAR
-STARTCHAR uni01DC
-ENCODING 476
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-70
-1C
-00
-24
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni01DD
-ENCODING 477
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-78
-8C
-06
-06
-FE
-C6
-CC
-78
-ENDCHAR
-STARTCHAR uni01DE
-ENCODING 478
-SWIDTH 773 0
-DWIDTH 10 0
-BBX 8 15 1 0
-BITMAP
-3C
-00
-24
-24
-00
-18
-18
-2C
-2C
-66
-46
-FE
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni01DF
-ENCODING 479
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 13 1 0
-BITMAP
-3C
-00
-24
-24
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni01E0
-ENCODING 480
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 15 1 0
-BITMAP
-1E00
-0000
-0C00
-0C00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni01E1
-ENCODING 481
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 13 1 0
-BITMAP
-3C
-00
-18
-18
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni01E2
-ENCODING 482
-SWIDTH 997 0
-DWIDTH 13 0
-BBX 11 12 1 0
-BITMAP
-0F00
-0000
-1FE0
-1600
-2600
-2600
-67C0
-4600
-7E00
-C600
-C600
-C7E0
-ENDCHAR
-STARTCHAR uni01E3
-ENCODING 483
-SWIDTH 913 0
-DWIDTH 14 0
-BBX 12 10 1 0
-BITMAP
-0780
-0000
-7DE0
-0730
-0630
-7FF0
-C600
-C600
-C710
-79E0
-ENDCHAR
-STARTCHAR uni01E4
-ENCODING 484
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 9 10 2 0
-BITMAP
-3E00
-6300
-C000
-C000
-C000
-C300
-CF80
-C300
-6300
-3F00
-ENDCHAR
-STARTCHAR uni01E5
-ENCODING 485
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-3F
-63
-C3
-C3
-C3
-67
-3B
-FF
-C6
-7C
-ENDCHAR
-STARTCHAR Gcaron
-ENCODING 486
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-2C
-18
-00
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR gcaron
-ENCODING 487
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-2C
-18
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR uni01E8
-ENCODING 488
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-2C
-18
-00
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni01E9
-ENCODING 489
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-B0
-60
-00
-C0
-C0
-C0
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-ENDCHAR
-STARTCHAR uni01EA
-ENCODING 490
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 12 1 -2
-BITMAP
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-0800
-0600
-ENDCHAR
-STARTCHAR uni01EB
-ENCODING 491
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-10
-0C
-ENDCHAR
-STARTCHAR uni01EC
-ENCODING 492
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 14 1 -2
-BITMAP
-1E00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-0800
-0600
-ENDCHAR
-STARTCHAR uni01ED
-ENCODING 493
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-3C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-10
-0C
-ENDCHAR
-STARTCHAR uni01F0
-ENCODING 496
-SWIDTH 361 0
-DWIDTH 5 0
-BBX 5 13 0 -2
-BITMAP
-58
-30
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-E0
-ENDCHAR
-STARTCHAR uni01F4
-ENCODING 500
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-0E
-38
-00
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR uni01F5
-ENCODING 501
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-07
-1C
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR uni01F8
-ENCODING 504
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-E0
-38
-00
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR uni01F9
-ENCODING 505
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-70
-1C
-00
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR Aringacute
-ENCODING 506
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-0700
-1C00
-0000
-1C00
-2600
-1C00
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR aringacute
-ENCODING 507
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-0E
-38
-00
-18
-2C
-18
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR AEacute
-ENCODING 508
-SWIDTH 997 0
-DWIDTH 13 0
-BBX 11 13 1 0
-BITMAP
-0380
-0E00
-0000
-1FE0
-1600
-2600
-2600
-67C0
-4600
-7E00
-C600
-C600
-C7E0
-ENDCHAR
-STARTCHAR aeacute
-ENCODING 509
-SWIDTH 913 0
-DWIDTH 14 0
-BBX 12 11 1 0
-BITMAP
-01C0
-0700
-0000
-7DE0
-0730
-0630
-7FF0
-C600
-C600
-C710
-79E0
-ENDCHAR
-STARTCHAR Oslashacute
-ENCODING 510
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 15 1 -1
-BITMAP
-0380
-0E00
-0000
-0040
-3F40
-6180
-C2C0
-C2C0
-C4C0
-C8C0
-D0C0
-D0C0
-6180
-BF00
-8000
-ENDCHAR
-STARTCHAR oslashacute
-ENCODING 511
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 13 1 -1
-BITMAP
-07
-1C
-00
-01
-3D
-66
-CB
-CB
-D3
-D3
-66
-BC
-80
-ENDCHAR
-STARTCHAR uni0200
-ENCODING 512
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-3600
-1200
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni0201
-ENCODING 513
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-36
-12
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni0202
-ENCODING 514
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1E00
-2100
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni0203
-ENCODING 515
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-3C
-42
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni0204
-ENCODING 516
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-D8
-48
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR uni0205
-ENCODING 517
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-6C
-24
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni0206
-ENCODING 518
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-78
-84
-00
-7E
-60
-60
-60
-7C
-60
-60
-60
-60
-7E
-ENDCHAR
-STARTCHAR uni0207
-ENCODING 519
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-3C
-42
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni0208
-ENCODING 520
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 5 13 0 0
-BITMAP
-D8
-48
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR uni0209
-ENCODING 521
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 5 11 -1 0
-BITMAP
-D8
-48
-00
-30
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR uni020A
-ENCODING 522
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 6 13 0 0
-BITMAP
-78
-84
-00
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR uni020B
-ENCODING 523
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 6 11 -1 0
-BITMAP
-78
-84
-00
-30
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR uni020C
-ENCODING 524
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-3600
-1200
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni020D
-ENCODING 525
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-6C
-24
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni020E
-ENCODING 526
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-1E00
-2100
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni020F
-ENCODING 527
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-3C
-42
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni0210
-ENCODING 528
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-6C
-24
-00
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni0211
-ENCODING 529
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-D8
-48
-00
-6C
-6C
-70
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni0212
-ENCODING 530
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-3C
-42
-00
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni0213
-ENCODING 531
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-78
-84
-00
-6C
-6C
-70
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni0214
-ENCODING 532
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-6C
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni0215
-ENCODING 533
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-6C
-24
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni0216
-ENCODING 534
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-3C
-42
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni0217
-ENCODING 535
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-3C
-42
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR Scommaaccent
-ENCODING 536
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 15 1 -5
-BITMAP
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR scommaaccent
-ENCODING 537
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 13 1 -5
-BITMAP
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-00
-30
-30
-10
-20
-ENDCHAR
-STARTCHAR Tcommaaccent
-ENCODING 538
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 15 1 -5
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-00
-18
-18
-08
-10
-ENDCHAR
-STARTCHAR tcommaaccent
-ENCODING 539
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 15 1 -5
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-00
-30
-30
-10
-20
-ENDCHAR
-STARTCHAR uni021E
-ENCODING 542
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-2C
-18
-00
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni021F
-ENCODING 543
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-B0
-60
-00
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni0226
-ENCODING 550
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-0C00
-0C00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni0227
-ENCODING 551
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 0
-BITMAP
-18
-18
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni0228
-ENCODING 552
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 12 2 -2
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-20
-C0
-ENDCHAR
-STARTCHAR uni0229
-ENCODING 553
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 10 1 -2
-BITMAP
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-10
-60
-ENDCHAR
-STARTCHAR uni022A
-ENCODING 554
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 15 1 0
-BITMAP
-1E00
-0000
-2100
-2100
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni022B
-ENCODING 555
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-3C
-00
-24
-24
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni022C
-ENCODING 556
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 15 1 0
-BITMAP
-1E00
-0000
-0D00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni022D
-ENCODING 557
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-3C
-00
-34
-58
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni022E
-ENCODING 558
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 0
-BITMAP
-0C00
-0C00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni022F
-ENCODING 559
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-18
-18
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni0230
-ENCODING 560
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 15 1 0
-BITMAP
-1E00
-0000
-0C00
-0C00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni0231
-ENCODING 561
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-3C
-00
-18
-18
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni0232
-ENCODING 562
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 12 1 0
-BITMAP
-3C
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR uni0233
-ENCODING 563
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 12 1 -2
-BITMAP
-3C
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR uni0250
-ENCODING 592
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 8 1 0
-BITMAP
-EE
-73
-63
-63
-7E
-60
-60
-3E
-ENDCHAR
-STARTCHAR uni0254
-ENCODING 596
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-78
-CC
-06
-06
-06
-06
-8C
-78
-ENDCHAR
-STARTCHAR uni0258
-ENCODING 600
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-78
-CC
-C6
-FE
-06
-06
-8C
-78
-ENDCHAR
-STARTCHAR uni0259
-ENCODING 601
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-78
-8C
-06
-06
-FE
-C6
-CC
-78
-ENDCHAR
-STARTCHAR uni025F
-ENCODING 607
-SWIDTH 461 0
-DWIDTH 7 0
-BBX 7 11 0 -3
-BITMAP
-18
-18
-18
-18
-18
-18
-18
-FE
-18
-18
-F0
-ENDCHAR
-STARTCHAR uni0265
-ENCODING 613
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-03
-03
-03
-ENDCHAR
-STARTCHAR uni0275
-ENCODING 629
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-3C
-66
-C3
-FF
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni0279
-ENCODING 633
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 8 2 0
-BITMAP
-18
-18
-18
-18
-18
-38
-D8
-D8
-ENDCHAR
-STARTCHAR uni0287
-ENCODING 647
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 10 1 0
-BITMAP
-E0
-30
-30
-30
-30
-30
-30
-F8
-30
-30
-ENDCHAR
-STARTCHAR uni0288
-ENCODING 648
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 12 1 -2
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-60
-60
-38
-ENDCHAR
-STARTCHAR uni0289
-ENCODING 649
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 8 1 0
-BITMAP
-C3
-C3
-C3
-FF
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni028C
-ENCODING 652
-SWIDTH 663 0
-DWIDTH 9 0
-BBX 7 8 1 0
-BITMAP
-38
-38
-2C
-4C
-C6
-C6
-C6
-C6
-ENDCHAR
-STARTCHAR uni028D
-ENCODING 653
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 8 1 0
-BITMAP
-3180
-3180
-3BC0
-6AC0
-6EC0
-C460
-C460
-C060
-ENDCHAR
-STARTCHAR uni028E
-ENCODING 654
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 10 1 0
-BITMAP
-0E
-0C
-18
-38
-2C
-6C
-C6
-C6
-C6
-C6
-ENDCHAR
-STARTCHAR uni029E
-ENCODING 670
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 11 1 -3
-BITMAP
-E3
-63
-33
-1B
-0F
-1B
-33
-63
-03
-03
-03
-ENDCHAR
-STARTCHAR uni02BB
-ENCODING 699
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-40
-80
-C0
-C0
-ENDCHAR
-STARTCHAR afii57929
-ENCODING 700
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR afii64937
-ENCODING 701
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-C0
-C0
-80
-40
-ENDCHAR
-STARTCHAR circumflex
-ENCODING 710
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 2 3 9
-BITMAP
-60
-B0
-ENDCHAR
-STARTCHAR caron
-ENCODING 711
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 2 3 9
-BITMAP
-B0
-60
-ENDCHAR
-STARTCHAR uni02C8
-ENCODING 712
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-C0
-C0
-80
-80
-ENDCHAR
-STARTCHAR macron
-ENCODING 713
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 1 3 9
-BITMAP
-F0
-ENDCHAR
-STARTCHAR uni02CA
-ENCODING 714
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 3 9
-BITMAP
-38
-E0
-ENDCHAR
-STARTCHAR uni02CB
-ENCODING 715
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 2 9
-BITMAP
-E0
-38
-ENDCHAR
-STARTCHAR uni02CD
-ENCODING 717
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 1 3 -2
-BITMAP
-F0
-ENDCHAR
-STARTCHAR uni02CE
-ENCODING 718
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 2 -3
-BITMAP
-E0
-38
-ENDCHAR
-STARTCHAR uni02CF
-ENCODING 719
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 3 -3
-BITMAP
-38
-E0
-ENDCHAR
-STARTCHAR breve
-ENCODING 728
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 6 2 2 9
-BITMAP
-84
-78
-ENDCHAR
-STARTCHAR dotaccent
-ENCODING 729
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 2 2 4 9
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR ring
-ENCODING 730
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 4 3 3 8
-BITMAP
-60
-B0
-60
-ENDCHAR
-STARTCHAR ogonek
-ENCODING 731
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 3 2 5 -2
-BITMAP
-80
-60
-ENDCHAR
-STARTCHAR tilde
-ENCODING 732
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 3 9
-BITMAP
-68
-B0
-ENDCHAR
-STARTCHAR hungarumlaut
-ENCODING 733
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 3 9
-BITMAP
-D8
-90
-ENDCHAR
-STARTCHAR uni02EE
-ENCODING 750
-SWIDTH 530 0
-DWIDTH 7 0
-BBX 5 4 1 7
-BITMAP
-D8
-D8
-48
-90
-ENDCHAR
-STARTCHAR uni037E
-ENCODING 894
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 2 9 1 -2
-BITMAP
-C0
-C0
-00
-00
-00
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR tonos
-ENCODING 900
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 2 3 9
-BITMAP
-38
-E0
-ENDCHAR
-STARTCHAR dieresistonos
-ENCODING 901
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 5 5 3 9
-BITMAP
-38
-E0
-00
-90
-90
-ENDCHAR
-STARTCHAR anoteleia
-ENCODING 903
-SWIDTH 343 0
-DWIDTH 10 0
-BBX 2 2 4 3
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR mu
-ENCODING 956
-SWIDTH 699 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-FB
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E00
-ENCODING 7680
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 14 1 -4
-BITMAP
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-0000
-0C00
-1600
-0C00
-ENDCHAR
-STARTCHAR uni1E01
-ENCODING 7681
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 12 1 -4
-BITMAP
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-00
-18
-2C
-18
-ENDCHAR
-STARTCHAR uni1E02
-ENCODING 7682
-SWIDTH 669 0
-DWIDTH 10 0
-BBX 7 13 2 0
-BITMAP
-30
-30
-00
-FC
-C6
-C6
-CC
-F0
-CC
-C6
-C6
-C6
-FC
-ENDCHAR
-STARTCHAR uni1E03
-ENCODING 7683
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-60
-60
-00
-C0
-C0
-C0
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-ENDCHAR
-STARTCHAR uni1E04
-ENCODING 7684
-SWIDTH 669 0
-DWIDTH 10 0
-BBX 7 13 2 -3
-BITMAP
-FC
-C6
-C6
-CC
-F0
-CC
-C6
-C6
-C6
-FC
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E05
-ENCODING 7685
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 14 1 -3
-BITMAP
-C0
-C0
-C0
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E06
-ENCODING 7686
-SWIDTH 669 0
-DWIDTH 10 0
-BBX 7 12 2 -2
-BITMAP
-FC
-C6
-C6
-CC
-F0
-CC
-C6
-C6
-C6
-FC
-00
-78
-ENDCHAR
-STARTCHAR uni1E07
-ENCODING 7687
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-C0
-C0
-C0
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-00
-3C
-ENDCHAR
-STARTCHAR uni1E08
-ENCODING 7688
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 8 15 2 -2
-BITMAP
-0E
-38
-00
-3E
-63
-C0
-C0
-C0
-C0
-C0
-C0
-63
-3E
-08
-30
-ENDCHAR
-STARTCHAR uni1E09
-ENCODING 7689
-SWIDTH 545 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-0E
-38
-00
-3C
-66
-C0
-C0
-C0
-C0
-62
-3C
-10
-60
-ENDCHAR
-STARTCHAR uni1E0A
-ENCODING 7690
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 13 2 0
-BITMAP
-1800
-1800
-0000
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-ENDCHAR
-STARTCHAR uni1E0B
-ENCODING 7691
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-06
-06
-00
-03
-03
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-ENDCHAR
-STARTCHAR uni1E0C
-ENCODING 7692
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 13 2 -3
-BITMAP
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR uni1E0D
-ENCODING 7693
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 14 1 -3
-BITMAP
-03
-03
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E0E
-ENCODING 7694
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 12 2 -2
-BITMAP
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-0000
-3C00
-ENDCHAR
-STARTCHAR uni1E0F
-ENCODING 7695
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-03
-03
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-00
-3C
-ENDCHAR
-STARTCHAR uni1E10
-ENCODING 7696
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 12 2 -2
-BITMAP
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-0800
-3000
-ENDCHAR
-STARTCHAR uni1E11
-ENCODING 7697
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-03
-03
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-08
-30
-ENDCHAR
-STARTCHAR uni1E12
-ENCODING 7698
-SWIDTH 819 0
-DWIDTH 12 0
-BBX 9 13 2 -3
-BITMAP
-FE00
-C300
-C180
-C180
-C180
-C180
-C180
-C180
-C300
-FE00
-0000
-1800
-2C00
-ENDCHAR
-STARTCHAR uni1E13
-ENCODING 7699
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 14 1 -3
-BITMAP
-03
-03
-03
-3F
-63
-C3
-C3
-C3
-C3
-67
-3B
-00
-18
-2C
-ENDCHAR
-STARTCHAR uni1E14
-ENCODING 7700
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 15 1 0
-BITMAP
-E0
-38
-00
-78
-00
-7E
-60
-60
-60
-7C
-60
-60
-60
-60
-7E
-ENDCHAR
-STARTCHAR uni1E15
-ENCODING 7701
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-70
-1C
-00
-3C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni1E16
-ENCODING 7702
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 15 2 0
-BITMAP
-1C
-70
-00
-F0
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR uni1E17
-ENCODING 7703
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-0E
-38
-00
-3C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni1E18
-ENCODING 7704
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 -3
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-00
-60
-B0
-ENDCHAR
-STARTCHAR uni1E19
-ENCODING 7705
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 -3
-BITMAP
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-00
-30
-58
-ENDCHAR
-STARTCHAR uni1E1A
-ENCODING 7706
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 -3
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-00
-68
-B0
-ENDCHAR
-STARTCHAR uni1E1B
-ENCODING 7707
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 -3
-BITMAP
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-00
-34
-58
-ENDCHAR
-STARTCHAR uni1E1C
-ENCODING 7708
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 15 1 -2
-BITMAP
-84
-78
-00
-7E
-60
-60
-60
-7C
-60
-60
-60
-60
-7E
-10
-60
-ENDCHAR
-STARTCHAR uni1E1D
-ENCODING 7709
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-42
-3C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-10
-60
-ENDCHAR
-STARTCHAR uni1E1E
-ENCODING 7710
-SWIDTH 602 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-60
-60
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E1F
-ENCODING 7711
-SWIDTH 461 0
-DWIDTH 7 0
-BBX 7 14 0 0
-BITMAP
-18
-18
-00
-1E
-30
-30
-FE
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR uni1E20
-ENCODING 7712
-SWIDTH 759 0
-DWIDTH 11 0
-BBX 8 12 2 0
-BITMAP
-3C
-00
-3E
-63
-C0
-C0
-C0
-C3
-C3
-C3
-63
-3F
-ENDCHAR
-STARTCHAR uni1E21
-ENCODING 7713
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-3C
-00
-3F
-63
-C3
-C3
-C3
-67
-3B
-03
-C6
-7C
-ENDCHAR
-STARTCHAR uni1E22
-ENCODING 7714
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-18
-18
-00
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E23
-ENCODING 7715
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-60
-60
-00
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E24
-ENCODING 7716
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E25
-ENCODING 7717
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 -3
-BITMAP
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E26
-ENCODING 7718
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-24
-24
-00
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E27
-ENCODING 7719
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-90
-90
-00
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E28
-ENCODING 7720
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 12 2 -2
-BITMAP
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-08
-30
-ENDCHAR
-STARTCHAR uni1E29
-ENCODING 7721
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-08
-30
-ENDCHAR
-STARTCHAR uni1E2A
-ENCODING 7722
-SWIDTH 813 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C3
-C3
-C3
-FF
-C3
-C3
-C3
-C3
-C3
-00
-42
-3C
-ENDCHAR
-STARTCHAR uni1E2B
-ENCODING 7723
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 -3
-BITMAP
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-42
-3C
-ENDCHAR
-STARTCHAR uni1E2C
-ENCODING 7724
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 5 13 0 -3
-BITMAP
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-00
-68
-B0
-ENDCHAR
-STARTCHAR uni1E2D
-ENCODING 7725
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 5 14 -1 -3
-BITMAP
-30
-30
-00
-30
-30
-30
-30
-30
-30
-30
-30
-00
-68
-B0
-ENDCHAR
-STARTCHAR uni1E2E
-ENCODING 7726
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 5 16 1 0
-BITMAP
-38
-E0
-00
-90
-90
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni1E2F
-ENCODING 7727
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 5 14 0 0
-BITMAP
-38
-E0
-00
-90
-90
-00
-60
-60
-60
-60
-60
-60
-60
-60
-ENDCHAR
-STARTCHAR uni1E30
-ENCODING 7728
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-0E
-38
-00
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E31
-ENCODING 7729
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-38
-E0
-00
-C0
-C0
-C0
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-ENDCHAR
-STARTCHAR uni1E32
-ENCODING 7730
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E33
-ENCODING 7731
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 14 1 -3
-BITMAP
-C0
-C0
-C0
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E34
-ENCODING 7732
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 12 2 -2
-BITMAP
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-00
-3C
-ENDCHAR
-STARTCHAR uni1E35
-ENCODING 7733
-SWIDTH 681 0
-DWIDTH 9 0
-BBX 8 13 1 -2
-BITMAP
-C0
-C0
-C0
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C7
-00
-3C
-ENDCHAR
-STARTCHAR uni1E36
-ENCODING 7734
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 13 2 -3
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1E37
-ENCODING 7735
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 2 14 1 -3
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-00
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E38
-ENCODING 7736
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 15 2 -3
-BITMAP
-F0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1E39
-ENCODING 7737
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 16 0 -3
-BITMAP
-F0
-00
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1E3A
-ENCODING 7738
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 12 2 -2
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-00
-F0
-ENDCHAR
-STARTCHAR uni1E3B
-ENCODING 7739
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 13 0 -2
-BITMAP
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-00
-F0
-ENDCHAR
-STARTCHAR uni1E3C
-ENCODING 7740
-SWIDTH 620 0
-DWIDTH 9 0
-BBX 6 13 2 -3
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-FC
-00
-60
-B0
-ENDCHAR
-STARTCHAR uni1E3D
-ENCODING 7741
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 4 14 0 -3
-BITMAP
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-60
-00
-60
-B0
-ENDCHAR
-STARTCHAR uni1E3E
-ENCODING 7742
-SWIDTH 940 0
-DWIDTH 15 0
-BBX 11 13 2 0
-BITMAP
-0380
-0E00
-0000
-E0E0
-E0E0
-B160
-B160
-B160
-9A60
-9A60
-8C60
-8C60
-8060
-ENDCHAR
-STARTCHAR uni1E3F
-ENCODING 7743
-SWIDTH 1006 0
-DWIDTH 14 0
-BBX 12 11 1 0
-BITMAP
-0380
-0E00
-0000
-DDE0
-EF70
-C630
-C630
-C630
-C630
-C630
-C630
-ENDCHAR
-STARTCHAR uni1E40
-ENCODING 7744
-SWIDTH 940 0
-DWIDTH 15 0
-BBX 11 13 2 0
-BITMAP
-0600
-0600
-0000
-E0E0
-E0E0
-B160
-B160
-B160
-9A60
-9A60
-8C60
-8C60
-8060
-ENDCHAR
-STARTCHAR uni1E41
-ENCODING 7745
-SWIDTH 1006 0
-DWIDTH 14 0
-BBX 12 11 1 0
-BITMAP
-0600
-0600
-0000
-DDE0
-EF70
-C630
-C630
-C630
-C630
-C630
-C630
-ENDCHAR
-STARTCHAR uni1E42
-ENCODING 7746
-SWIDTH 940 0
-DWIDTH 15 0
-BBX 11 13 2 -3
-BITMAP
-E0E0
-E0E0
-B160
-B160
-B160
-9A60
-9A60
-8C60
-8C60
-8060
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E43
-ENCODING 7747
-SWIDTH 1006 0
-DWIDTH 14 0
-BBX 12 11 1 -3
-BITMAP
-DDE0
-EF70
-C630
-C630
-C630
-C630
-C630
-C630
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E44
-ENCODING 7748
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 0
-BITMAP
-30
-30
-00
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR uni1E45
-ENCODING 7749
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 0
-BITMAP
-18
-18
-00
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E46
-ENCODING 7750
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-00
-0C
-0C
-ENDCHAR
-STARTCHAR uni1E47
-ENCODING 7751
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E48
-ENCODING 7752
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 12 2 -2
-BITMAP
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-00
-1E
-ENDCHAR
-STARTCHAR uni1E49
-ENCODING 7753
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 10 1 -2
-BITMAP
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-3C
-ENDCHAR
-STARTCHAR uni1E4A
-ENCODING 7754
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-E1
-E1
-B1
-B1
-99
-99
-8D
-8D
-87
-87
-00
-0C
-16
-ENDCHAR
-STARTCHAR uni1E4B
-ENCODING 7755
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-18
-2C
-ENDCHAR
-STARTCHAR uni1E4C
-ENCODING 7756
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 16 1 0
-BITMAP
-0700
-1C00
-0000
-0D00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1E4D
-ENCODING 7757
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-0E
-38
-00
-34
-58
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1E4E
-ENCODING 7758
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 16 1 0
-BITMAP
-1200
-1200
-0000
-0D00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1E4F
-ENCODING 7759
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-24
-24
-00
-34
-58
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1E50
-ENCODING 7760
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 15 1 0
-BITMAP
-3800
-0E00
-0000
-1E00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1E51
-ENCODING 7761
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-70
-1C
-00
-3C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1E52
-ENCODING 7762
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 15 1 0
-BITMAP
-0700
-1C00
-0000
-1E00
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1E53
-ENCODING 7763
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-0E
-38
-00
-3C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1E54
-ENCODING 7764
-SWIDTH 657 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-1C
-70
-00
-F8
-CC
-CC
-CC
-CC
-F8
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E55
-ENCODING 7765
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-0E
-38
-00
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E56
-ENCODING 7766
-SWIDTH 657 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-30
-30
-00
-F8
-CC
-CC
-CC
-CC
-F8
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E57
-ENCODING 7767
-SWIDTH 696 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-18
-18
-00
-DC
-E6
-C3
-C3
-C3
-C3
-C6
-FC
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E58
-ENCODING 7768
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 13 2 0
-BITMAP
-18
-18
-00
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni1E59
-ENCODING 7769
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 11 2 0
-BITMAP
-60
-60
-00
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni1E5A
-ENCODING 7770
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 13 2 -3
-BITMAP
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E5B
-ENCODING 7771
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 11 2 -3
-BITMAP
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1E5C
-ENCODING 7772
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 15 2 -3
-BITMAP
-78
-00
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E5D
-ENCODING 7773
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 13 2 -3
-BITMAP
-F0
-00
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1E5E
-ENCODING 7774
-SWIDTH 734 0
-DWIDTH 11 0
-BBX 8 12 2 -2
-BITMAP
-FC
-C6
-C6
-C4
-CC
-F8
-CC
-C6
-C3
-C3
-00
-3C
-ENDCHAR
-STARTCHAR uni1E5F
-ENCODING 7775
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 5 10 2 -2
-BITMAP
-D8
-D8
-E0
-C0
-C0
-C0
-C0
-C0
-00
-F0
-ENDCHAR
-STARTCHAR uni1E60
-ENCODING 7776
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-30
-30
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR uni1E61
-ENCODING 7777
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 11 1 0
-BITMAP
-30
-30
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR uni1E62
-ENCODING 7778
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 13 1 -3
-BITMAP
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E63
-ENCODING 7779
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 11 1 -3
-BITMAP
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E64
-ENCODING 7780
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 16 1 0
-BITMAP
-18
-18
-00
-1C
-70
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR uni1E65
-ENCODING 7781
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 14 1 0
-BITMAP
-30
-30
-00
-1C
-70
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR uni1E66
-ENCODING 7782
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 16 1 0
-BITMAP
-18
-18
-00
-2C
-18
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-ENDCHAR
-STARTCHAR uni1E67
-ENCODING 7783
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 14 1 0
-BITMAP
-30
-30
-00
-58
-30
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-ENDCHAR
-STARTCHAR uni1E68
-ENCODING 7784
-SWIDTH 594 0
-DWIDTH 9 0
-BBX 7 16 1 -3
-BITMAP
-30
-30
-00
-7C
-C6
-C0
-E0
-78
-3C
-0E
-06
-C6
-7C
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E69
-ENCODING 7785
-SWIDTH 622 0
-DWIDTH 8 0
-BBX 6 14 1 -3
-BITMAP
-30
-30
-00
-7C
-C0
-C0
-F0
-3C
-0C
-0C
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E6A
-ENCODING 7786
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-18
-18
-00
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR uni1E6B
-ENCODING 7787
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 13 1 0
-BITMAP
-60
-60
-00
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-ENDCHAR
-STARTCHAR uni1E6C
-ENCODING 7788
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 13 1 -3
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E6D
-ENCODING 7789
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 13 1 -3
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E6E
-ENCODING 7790
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-00
-3C
-ENDCHAR
-STARTCHAR uni1E6F
-ENCODING 7791
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 12 1 -2
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-00
-78
-ENDCHAR
-STARTCHAR uni1E70
-ENCODING 7792
-SWIDTH 735 0
-DWIDTH 10 0
-BBX 8 13 1 -3
-BITMAP
-FF
-18
-18
-18
-18
-18
-18
-18
-18
-18
-00
-18
-2C
-ENDCHAR
-STARTCHAR uni1E71
-ENCODING 7793
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 13 1 -3
-BITMAP
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-00
-30
-58
-ENDCHAR
-STARTCHAR uni1E72
-ENCODING 7794
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-00
-24
-24
-ENDCHAR
-STARTCHAR uni1E73
-ENCODING 7795
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-00
-24
-24
-ENDCHAR
-STARTCHAR uni1E74
-ENCODING 7796
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-00
-34
-58
-ENDCHAR
-STARTCHAR uni1E75
-ENCODING 7797
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-00
-34
-58
-ENDCHAR
-STARTCHAR uni1E76
-ENCODING 7798
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-00
-18
-2C
-ENDCHAR
-STARTCHAR uni1E77
-ENCODING 7799
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-00
-18
-2C
-ENDCHAR
-STARTCHAR uni1E78
-ENCODING 7800
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 16 2 0
-BITMAP
-0E
-38
-00
-1A
-2C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1E79
-ENCODING 7801
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-07
-1C
-00
-1A
-2C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni1E7A
-ENCODING 7802
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 15 2 0
-BITMAP
-24
-24
-00
-3C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1E7B
-ENCODING 7803
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-24
-24
-00
-3C
-00
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-ENDCHAR
-STARTCHAR uni1E7C
-ENCODING 7804
-SWIDTH 735 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1A00
-2C00
-0000
-C180
-C180
-C180
-6100
-6300
-6300
-3200
-3600
-1C00
-1C00
-ENDCHAR
-STARTCHAR uni1E7D
-ENCODING 7805
-SWIDTH 663 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-34
-58
-00
-C6
-C6
-C6
-C6
-64
-68
-38
-38
-ENDCHAR
-STARTCHAR uni1E7E
-ENCODING 7806
-SWIDTH 735 0
-DWIDTH 11 0
-BBX 9 13 1 -3
-BITMAP
-C180
-C180
-C180
-6100
-6300
-6300
-3200
-3600
-1C00
-1C00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E7F
-ENCODING 7807
-SWIDTH 663 0
-DWIDTH 9 0
-BBX 7 11 1 -3
-BITMAP
-C6
-C6
-C6
-C6
-64
-68
-38
-38
-00
-30
-30
-ENDCHAR
-STARTCHAR Wgrave
-ENCODING 7808
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 13 1 0
-BITMAP
-3800
-0E00
-0000
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR wgrave
-ENCODING 7809
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 11 1 0
-BITMAP
-3800
-0E00
-0000
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR Wacute
-ENCODING 7810
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 13 1 0
-BITMAP
-0380
-0E00
-0000
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR wacute
-ENCODING 7811
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 11 1 0
-BITMAP
-0380
-0E00
-0000
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR Wdieresis
-ENCODING 7812
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 13 1 0
-BITMAP
-0900
-0900
-0000
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR wdieresis
-ENCODING 7813
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 11 1 0
-BITMAP
-0900
-0900
-0000
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR uni1E86
-ENCODING 7814
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 13 1 0
-BITMAP
-0600
-0600
-0000
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR uni1E87
-ENCODING 7815
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 11 1 0
-BITMAP
-0600
-0600
-0000
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR uni1E88
-ENCODING 7816
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 13 1 -3
-BITMAP
-C060
-C060
-C660
-C660
-6640
-6B40
-6B40
-7BC0
-3180
-3180
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E89
-ENCODING 7817
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 11 1 -3
-BITMAP
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E8A
-ENCODING 7818
-SWIDTH 699 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-18
-18
-00
-C6
-C6
-6C
-6C
-38
-38
-6C
-6C
-C6
-C6
-ENDCHAR
-STARTCHAR uni1E8B
-ENCODING 7819
-SWIDTH 568 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-30
-30
-00
-C6
-C6
-64
-38
-38
-4C
-C6
-C6
-ENDCHAR
-STARTCHAR uni1E8C
-ENCODING 7820
-SWIDTH 699 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-24
-24
-00
-C6
-C6
-6C
-6C
-38
-38
-6C
-6C
-C6
-C6
-ENDCHAR
-STARTCHAR uni1E8D
-ENCODING 7821
-SWIDTH 568 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-48
-48
-00
-C6
-C6
-64
-38
-38
-4C
-C6
-C6
-ENDCHAR
-STARTCHAR uni1E8E
-ENCODING 7822
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-18
-18
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR uni1E8F
-ENCODING 7823
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-18
-18
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR uni1E90
-ENCODING 7824
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 13 1 0
-BITMAP
-18
-2C
-00
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-ENDCHAR
-STARTCHAR uni1E91
-ENCODING 7825
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-18
-2C
-00
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-ENDCHAR
-STARTCHAR uni1E92
-ENCODING 7826
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 13 1 -3
-BITMAP
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E93
-ENCODING 7827
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 11 1 -3
-BITMAP
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E94
-ENCODING 7828
-SWIDTH 675 0
-DWIDTH 9 0
-BBX 7 12 1 -2
-BITMAP
-FE
-06
-0C
-1C
-18
-30
-70
-60
-C0
-FE
-00
-78
-ENDCHAR
-STARTCHAR uni1E95
-ENCODING 7829
-SWIDTH 608 0
-DWIDTH 9 0
-BBX 7 10 1 -2
-BITMAP
-FE
-06
-0C
-18
-30
-60
-C0
-FE
-00
-78
-ENDCHAR
-STARTCHAR uni1E96
-ENCODING 7830
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 13 1 -2
-BITMAP
-C0
-C0
-C0
-DE
-E7
-C3
-C3
-C3
-C3
-C3
-C3
-00
-3C
-ENDCHAR
-STARTCHAR uni1E97
-ENCODING 7831
-SWIDTH 436 0
-DWIDTH 7 0
-BBX 5 13 1 0
-BITMAP
-90
-90
-00
-60
-60
-F8
-60
-60
-60
-60
-60
-60
-38
-ENDCHAR
-STARTCHAR uni1E98
-ENCODING 7832
-SWIDTH 885 0
-DWIDTH 13 0
-BBX 11 12 1 0
-BITMAP
-0600
-0B00
-0600
-0000
-C060
-C460
-C460
-6EC0
-6AC0
-7B80
-3180
-3180
-ENDCHAR
-STARTCHAR uni1E99
-ENCODING 7833
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 14 1 -2
-BITMAP
-18
-2C
-18
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR uni1EA0
-ENCODING 7840
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 -3
-BITMAP
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EA1
-ENCODING 7841
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 11 1 -3
-BITMAP
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EA4
-ENCODING 7844
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-0700
-1C00
-0000
-1C00
-2600
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni1EA5
-ENCODING 7845
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-0E
-38
-00
-18
-2C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni1EA6
-ENCODING 7846
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-7000
-1C00
-0000
-1C00
-2600
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni1EA7
-ENCODING 7847
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-70
-1C
-00
-18
-2C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni1EAA
-ENCODING 7850
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-1A00
-2C00
-0000
-1C00
-2600
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni1EAB
-ENCODING 7851
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-1A
-2C
-00
-18
-2C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni1EAC
-ENCODING 7852
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 -3
-BITMAP
-0C00
-1600
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EAD
-ENCODING 7853
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 -3
-BITMAP
-18
-2C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EAE
-ENCODING 7854
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-0700
-1C00
-0000
-2100
-1E00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni1EAF
-ENCODING 7855
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-0E
-38
-00
-42
-3C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni1EB0
-ENCODING 7856
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-3800
-0E00
-0000
-2100
-1E00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni1EB1
-ENCODING 7857
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-70
-1C
-00
-42
-3C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni1EB4
-ENCODING 7860
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 0
-BITMAP
-1A00
-2C00
-0000
-2100
-1E00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni1EB5
-ENCODING 7861
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 0
-BITMAP
-1A
-2C
-00
-42
-3C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-ENDCHAR
-STARTCHAR uni1EB6
-ENCODING 7862
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 16 1 -3
-BITMAP
-2100
-1E00
-0000
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EB7
-ENCODING 7863
-SWIDTH 623 0
-DWIDTH 9 0
-BBX 8 14 1 -3
-BITMAP
-42
-3C
-00
-7C
-06
-06
-7E
-C6
-C6
-CE
-77
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EB8
-ENCODING 7864
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 -3
-BITMAP
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1EB9
-ENCODING 7865
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 -3
-BITMAP
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1EBC
-ENCODING 7868
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 13 2 0
-BITMAP
-68
-B0
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR uni1EBD
-ENCODING 7869
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 11 1 0
-BITMAP
-34
-58
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni1EBE
-ENCODING 7870
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 16 2 0
-BITMAP
-1C
-70
-00
-30
-58
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR uni1EBF
-ENCODING 7871
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 14 1 0
-BITMAP
-0E
-38
-00
-18
-2C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni1EC0
-ENCODING 7872
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 16 2 0
-BITMAP
-E0
-38
-00
-30
-58
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR uni1EC1
-ENCODING 7873
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 14 1 0
-BITMAP
-70
-1C
-00
-18
-2C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni1EC4
-ENCODING 7876
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 16 2 0
-BITMAP
-34
-58
-00
-30
-58
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-ENDCHAR
-STARTCHAR uni1EC5
-ENCODING 7877
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 14 1 0
-BITMAP
-1A
-2C
-00
-18
-2C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-ENDCHAR
-STARTCHAR uni1EC6
-ENCODING 7878
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 16 2 -3
-BITMAP
-60
-B0
-00
-FC
-C0
-C0
-C0
-F8
-C0
-C0
-C0
-C0
-FC
-00
-60
-60
-ENDCHAR
-STARTCHAR uni1EC7
-ENCODING 7879
-SWIDTH 614 0
-DWIDTH 9 0
-BBX 7 14 1 -3
-BITMAP
-18
-2C
-00
-3C
-66
-C6
-FE
-C0
-C0
-62
-3C
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1ECA
-ENCODING 7882
-SWIDTH 361 0
-DWIDTH 6 0
-BBX 2 13 2 -3
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-00
-C0
-C0
-ENDCHAR
-STARTCHAR uni1ECB
-ENCODING 7883
-SWIDTH 361 0
-DWIDTH 4 0
-BBX 2 14 1 -3
-BITMAP
-C0
-C0
-00
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-00
-C0
-C0
-ENDCHAR
-STARTCHAR uni1ECC
-ENCODING 7884
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 13 1 -3
-BITMAP
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1ECD
-ENCODING 7885
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1ED0
-ENCODING 7888
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 16 1 0
-BITMAP
-0700
-1C00
-0000
-0C00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1ED1
-ENCODING 7889
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-0E
-38
-00
-18
-2C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1ED2
-ENCODING 7890
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 16 1 0
-BITMAP
-3800
-0E00
-0000
-0C00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1ED3
-ENCODING 7891
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-70
-1C
-00
-18
-2C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1ED6
-ENCODING 7894
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 16 1 0
-BITMAP
-0D00
-1600
-0000
-0C00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1ED7
-ENCODING 7895
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 14 1 0
-BITMAP
-1A
-2C
-00
-18
-2C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-ENDCHAR
-STARTCHAR uni1ED8
-ENCODING 7896
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 10 16 1 -3
-BITMAP
-0C00
-1600
-0000
-3F00
-6180
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1ED9
-ENCODING 7897
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 8 14 1 -3
-BITMAP
-18
-2C
-00
-3C
-66
-C3
-C3
-C3
-C3
-66
-3C
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EDA
-ENCODING 7898
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 11 13 1 0
-BITMAP
-0380
-0E00
-0000
-3F60
-61E0
-C0E0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1EDB
-ENCODING 7899
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 10 11 1 0
-BITMAP
-0380
-0E00
-0000
-3CC0
-66C0
-C340
-C380
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni1EDC
-ENCODING 7900
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 11 13 1 0
-BITMAP
-1C00
-0700
-0000
-3F60
-61E0
-C0E0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1EDD
-ENCODING 7901
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 10 11 1 0
-BITMAP
-3800
-0E00
-0000
-3CC0
-66C0
-C340
-C380
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni1EE0
-ENCODING 7904
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 11 13 1 0
-BITMAP
-0680
-0B00
-0000
-3F60
-61E0
-C0E0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-ENDCHAR
-STARTCHAR uni1EE1
-ENCODING 7905
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 10 11 1 0
-BITMAP
-0D00
-1600
-0000
-3CC0
-66C0
-C340
-C380
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni1EE2
-ENCODING 7906
-SWIDTH 855 0
-DWIDTH 12 0
-BBX 11 13 1 -3
-BITMAP
-3F60
-61E0
-C0E0
-C0C0
-C0C0
-C0C0
-C0C0
-C0C0
-6180
-3F00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EE3
-ENCODING 7907
-SWIDTH 675 0
-DWIDTH 10 0
-BBX 10 11 1 -3
-BITMAP
-3CC0
-66C0
-C340
-C380
-C300
-C300
-6600
-3C00
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR uni1EE4
-ENCODING 7908
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 13 2 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-C3
-66
-3C
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EE5
-ENCODING 7909
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 8 11 1 -3
-BITMAP
-C3
-C3
-C3
-C3
-C3
-C3
-E7
-7B
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EE8
-ENCODING 7912
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 10 13 2 0
-BITMAP
-0380
-0E00
-0000
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni1EE9
-ENCODING 7913
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 10 11 1 0
-BITMAP
-0380
-0E00
-0000
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-E700
-7B00
-ENDCHAR
-STARTCHAR uni1EEA
-ENCODING 7914
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 10 13 2 0
-BITMAP
-3800
-0E00
-0000
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni1EEB
-ENCODING 7915
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 10 11 1 0
-BITMAP
-3800
-0E00
-0000
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-E700
-7B00
-ENDCHAR
-STARTCHAR uni1EEE
-ENCODING 7918
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 10 13 2 0
-BITMAP
-0D00
-1600
-0000
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-C300
-C300
-6600
-3C00
-ENDCHAR
-STARTCHAR uni1EEF
-ENCODING 7919
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 10 11 1 0
-BITMAP
-0D00
-1600
-0000
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-E700
-7B00
-ENDCHAR
-STARTCHAR uni1EF0
-ENCODING 7920
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 10 13 2 -3
-BITMAP
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-C300
-C300
-6600
-3C00
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR uni1EF1
-ENCODING 7921
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 10 11 1 -3
-BITMAP
-C3C0
-C3C0
-C340
-C380
-C300
-C300
-E700
-7B00
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR Ygrave
-ENCODING 7922
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-70
-1C
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR ygrave
-ENCODING 7923
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-E0
-38
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR uni1EF4
-ENCODING 7924
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 -3
-BITMAP
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1EF5
-ENCODING 7925
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -5
-BITMAP
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1EF8
-ENCODING 7928
-SWIDTH 738 0
-DWIDTH 10 0
-BBX 8 13 1 0
-BITMAP
-1A
-2C
-00
-C3
-C3
-62
-66
-34
-18
-18
-18
-18
-18
-ENDCHAR
-STARTCHAR uni1EF9
-ENCODING 7929
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 7 13 1 -2
-BITMAP
-34
-58
-00
-C6
-C6
-C6
-C6
-6C
-68
-38
-30
-60
-E0
-ENDCHAR
-STARTCHAR uni2000
-ENCODING 8192
-SWIDTH 500 0
-DWIDTH 7 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2001
-ENCODING 8193
-SWIDTH 1000 0
-DWIDTH 15 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2002
-ENCODING 8194
-SWIDTH 500 0
-DWIDTH 7 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2003
-ENCODING 8195
-SWIDTH 1000 0
-DWIDTH 15 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2004
-ENCODING 8196
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2005
-ENCODING 8197
-SWIDTH 250 0
-DWIDTH 4 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2006
-ENCODING 8198
-SWIDTH 167 0
-DWIDTH 2 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2007
-ENCODING 8199
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2008
-ENCODING 8200
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2009
-ENCODING 8201
-SWIDTH 200 0
-DWIDTH 3 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni200A
-ENCODING 8202
-SWIDTH 100 0
-DWIDTH 1 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni200B
-ENCODING 8203
-SWIDTH 0 0
-DWIDTH 0 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2010
-ENCODING 8208
-SWIDTH 289 0
-DWIDTH 5 0
-BBX 3 1 1 4
-BITMAP
-E0
-ENDCHAR
-STARTCHAR uni2011
-ENCODING 8209
-SWIDTH 289 0
-DWIDTH 5 0
-BBX 3 1 1 4
-BITMAP
-E0
-ENDCHAR
-STARTCHAR figuredash
-ENCODING 8210
-SWIDTH 500 0
-DWIDTH 7 0
-BBX 5 1 1 4
-BITMAP
-F8
-ENDCHAR
-STARTCHAR endash
-ENCODING 8211
-SWIDTH 500 0
-DWIDTH 7 0
-BBX 5 1 1 4
-BITMAP
-F8
-ENDCHAR
-STARTCHAR emdash
-ENCODING 8212
-SWIDTH 1000 0
-DWIDTH 15 0
-BBX 13 1 1 4
-BITMAP
-FFF8
-ENDCHAR
-STARTCHAR afii00208
-ENCODING 8213
-SWIDTH 1000 0
-DWIDTH 15 0
-BBX 13 1 1 4
-BITMAP
-FFF8
-ENDCHAR
-STARTCHAR quoteleft
-ENCODING 8216
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-40
-80
-C0
-C0
-ENDCHAR
-STARTCHAR quoteright
-ENCODING 8217
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR quotesinglbase
-ENCODING 8218
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 -2
-BITMAP
-C0
-C0
-40
-80
-ENDCHAR
-STARTCHAR quotereversed
-ENCODING 8219
-SWIDTH 265 0
-DWIDTH 4 0
-BBX 2 4 1 7
-BITMAP
-C0
-C0
-80
-40
-ENDCHAR
-STARTCHAR quotedblleft
-ENCODING 8220
-SWIDTH 530 0
-DWIDTH 7 0
-BBX 5 4 1 7
-BITMAP
-48
-90
-D8
-D8
-ENDCHAR
-STARTCHAR quotedblright
-ENCODING 8221
-SWIDTH 530 0
-DWIDTH 7 0
-BBX 5 4 1 7
-BITMAP
-D8
-D8
-48
-90
-ENDCHAR
-STARTCHAR quotedblbase
-ENCODING 8222
-SWIDTH 530 0
-DWIDTH 7 0
-BBX 5 4 1 -2
-BITMAP
-D8
-D8
-48
-90
-ENDCHAR
-STARTCHAR uni201F
-ENCODING 8223
-SWIDTH 530 0
-DWIDTH 7 0
-BBX 5 4 1 7
-BITMAP
-D8
-D8
-90
-48
-ENDCHAR
-STARTCHAR dagger
-ENCODING 8224
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 6 11 2 -1
-BITMAP
-30
-30
-30
-FC
-30
-30
-30
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR daggerdbl
-ENCODING 8225
-SWIDTH 693 0
-DWIDTH 10 0
-BBX 6 11 2 -1
-BITMAP
-30
-30
-30
-FC
-30
-30
-30
-FC
-30
-30
-30
-ENDCHAR
-STARTCHAR bullet
-ENCODING 8226
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 4 4 3 2
-BITMAP
-F0
-F0
-F0
-F0
-ENDCHAR
-STARTCHAR ellipsis
-ENCODING 8230
-SWIDTH 1000 0
-DWIDTH 10 0
-BBX 6 2 2 0
-BITMAP
-CC
-CC
-ENDCHAR
-STARTCHAR perthousand
-ENCODING 8240
-SWIDTH 1313 0
-DWIDTH 18 0
-BBX 16 10 1 0
-BITMAP
-7000
-D980
-DB00
-7200
-0400
-0800
-138E
-36DB
-66DB
-038E
-ENDCHAR
-STARTCHAR guilsinglleft
-ENCODING 8249
-SWIDTH 361 0
-DWIDTH 5 0
-BBX 4 5 0 2
-BITMAP
-30
-60
-C0
-60
-30
-ENDCHAR
-STARTCHAR guilsinglright
-ENCODING 8250
-SWIDTH 361 0
-DWIDTH 5 0
-BBX 4 5 1 2
-BITMAP
-C0
-60
-30
-60
-C0
-ENDCHAR
-STARTCHAR fraction
-ENCODING 8260
-SWIDTH 93 0
-DWIDTH 4 0
-BBX 6 10 -1 0
-BITMAP
-0C
-0C
-18
-18
-30
-30
-60
-60
-C0
-C0
-ENDCHAR
-STARTCHAR oneinferior
-ENCODING 8321
-SWIDTH 536 0
-DWIDTH 7 0
-BBX 4 6 1 -2
-BITMAP
-30
-F0
-30
-30
-30
-30
-ENDCHAR
-STARTCHAR twoinferior
-ENCODING 8322
-SWIDTH 536 0
-DWIDTH 7 0
-BBX 5 6 1 -2
-BITMAP
-F0
-18
-18
-60
-C0
-F8
-ENDCHAR
-STARTCHAR threeinferior
-ENCODING 8323
-SWIDTH 536 0
-DWIDTH 7 0
-BBX 5 6 1 -2
-BITMAP
-F0
-18
-70
-18
-18
-F0
-ENDCHAR
-STARTCHAR uni20A5
-ENCODING 8357
-SWIDTH 1006 0
-DWIDTH 14 0
-BBX 12 12 1 -2
-BITMAP
-00C0
-0180
-DDE0
-EF70
-C730
-C630
-C630
-CE30
-CE30
-DE30
-1800
-3000
-ENDCHAR
-STARTCHAR uni20A6
-ENCODING 8358
-SWIDTH 783 0
-DWIDTH 12 0
-BBX 8 10 2 0
-BITMAP
-E1
-E1
-B1
-FF
-99
-FF
-8D
-8D
-87
-87
-ENDCHAR
-STARTCHAR uni20A9
-ENCODING 8361
-SWIDTH 940 0
-DWIDTH 13 0
-BBX 11 10 1 0
-BITMAP
-C060
-C060
-C660
-FFE0
-6640
-7FC0
-6B40
-7BC0
-3180
-3180
-ENDCHAR
-STARTCHAR Euro
-ENCODING 8364
-SWIDTH 726 0
-DWIDTH 11 0
-BBX 9 10 1 0
-BITMAP
-1F00
-3180
-6000
-FE00
-6000
-FE00
-6000
-6000
-3180
-1F00
-ENDCHAR
-STARTCHAR uni20AD
-ENCODING 8365
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-C3
-C6
-CC
-D8
-FF
-D8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni2103
-ENCODING 8451
-SWIDTH 955 0
-DWIDTH 15 0
-BBX 14 10 0 0
-BITMAP
-60F8
-918C
-6300
-0300
-0300
-0300
-0300
-0300
-018C
-00F8
-ENDCHAR
-STARTCHAR uni2109
-ENCODING 8457
-SWIDTH 831 0
-DWIDTH 13 0
-BBX 12 10 0 0
-BITMAP
-63F0
-9300
-6300
-0300
-03E0
-0300
-0300
-0300
-0300
-0300
-ENDCHAR
-STARTCHAR trademark
-ENCODING 8482
-SWIDTH 901 0
-DWIDTH 13 0
-BBX 10 5 1 5
-BITMAP
-FEC0
-2540
-2540
-2540
-2440
-ENDCHAR
-STARTCHAR uni212A
-ENCODING 8490
-SWIDTH 753 0
-DWIDTH 11 0
-BBX 8 10 2 0
-BITMAP
-C3
-C6
-CC
-D8
-F0
-D8
-CC
-C6
-C3
-C3
-ENDCHAR
-STARTCHAR uni212B
-ENCODING 8491
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 13 1 0
-BITMAP
-1C00
-2600
-1C00
-1C00
-1C00
-2600
-2600
-6300
-4300
-FF00
-C180
-C180
-C180
-ENDCHAR
-STARTCHAR uni2132
-ENCODING 8498
-SWIDTH 602 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-0C
-0C
-0C
-0C
-0C
-7C
-0C
-0C
-0C
-FC
-ENDCHAR
-STARTCHAR universal
-ENCODING 8704
-SWIDTH 773 0
-DWIDTH 11 0
-BBX 9 10 1 0
-BITMAP
-C180
-C180
-C180
-FF00
-4300
-6300
-2600
-2600
-1C00
-1C00
-ENDCHAR
-STARTCHAR existential
-ENCODING 8707
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 6 10 2 0
-BITMAP
-FC
-0C
-0C
-0C
-7C
-0C
-0C
-0C
-0C
-FC
-ENDCHAR
-STARTCHAR uni2204
-ENCODING 8708
-SWIDTH 645 0
-DWIDTH 9 0
-BBX 8 12 1 -1
-BITMAP
-03
-7E
-06
-0E
-0E
-3E
-1E
-36
-36
-66
-7E
-C0
-ENDCHAR
-STARTCHAR minus
-ENCODING 8722
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 1 1 4
-BITMAP
-FE
-ENDCHAR
-STARTCHAR fraction
-ENCODING 8725
-SWIDTH 93 0
-DWIDTH 4 0
-BBX 6 10 -1 0
-BITMAP
-0C
-0C
-18
-18
-30
-30
-60
-60
-C0
-C0
-ENDCHAR
-STARTCHAR periodcentered
-ENCODING 8729
-SWIDTH 343 0
-DWIDTH 10 0
-BBX 2 2 4 3
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR uni2236
-ENCODING 8758
-SWIDTH 343 0
-DWIDTH 4 0
-BBX 2 7 1 0
-BITMAP
-C0
-C0
-00
-00
-00
-C0
-C0
-ENDCHAR
-STARTCHAR uni2259
-ENCODING 8793
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 6 1 3
-BITMAP
-18
-2C
-00
-FE
-00
-FE
-ENDCHAR
-STARTCHAR uni225A
-ENCODING 8794
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 6 1 3
-BITMAP
-2C
-18
-00
-FE
-00
-FE
-ENDCHAR
-STARTCHAR notequal
-ENCODING 8800
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 12 1 -1
-BITMAP
-03
-06
-06
-0C
-0C
-FE
-18
-FE
-30
-60
-60
-C0
-ENDCHAR
-STARTCHAR equivalence
-ENCODING 8801
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 7 5 0 2
-BITMAP
-FE
-00
-FE
-00
-FE
-ENDCHAR
-STARTCHAR uni2262
-ENCODING 8802
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 12 0 -1
-BITMAP
-03
-06
-06
-0C
-FE
-18
-FE
-30
-FE
-60
-60
-C0
-ENDCHAR
-STARTCHAR lessequal
-ENCODING 8804
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 6 9 2 -1
-BITMAP
-0C
-38
-60
-C0
-60
-38
-0C
-00
-FC
-ENDCHAR
-STARTCHAR greaterequal
-ENCODING 8805
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 6 9 2 -1
-BITMAP
-C0
-70
-18
-0C
-18
-70
-C0
-00
-FC
-ENDCHAR
-STARTCHAR uni226E
-ENCODING 8814
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 12 1 -1
-BITMAP
-03
-06
-06
-0E
-1C
-38
-78
-30
-3C
-66
-60
-C0
-ENDCHAR
-STARTCHAR uni226F
-ENCODING 8815
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 12 1 -1
-BITMAP
-03
-06
-06
-6C
-3C
-1C
-1E
-3C
-38
-60
-60
-C0
-ENDCHAR
-STARTCHAR uni2270
-ENCODING 8816
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-03
-06
-06
-1C
-3C
-78
-38
-3C
-36
-60
-7E
-C0
-ENDCHAR
-STARTCHAR uni2271
-ENCODING 8817
-SWIDTH 687 0
-DWIDTH 10 0
-BBX 8 12 1 -2
-BITMAP
-03
-06
-66
-3C
-0C
-1E
-1C
-38
-70
-60
-7E
-C0
-ENDCHAR
-STARTCHAR fi
-ENCODING -1
-SWIDTH 711 0
-DWIDTH 11 0
-BBX 9 11 0 0
-BITMAP
-1D80
-3180
-3000
-FF80
-3180
-3180
-3180
-3180
-3180
-3180
-3180
-ENDCHAR
-STARTCHAR fl
-ENCODING -1
-SWIDTH 711 0
-DWIDTH 10 0
-BBX 9 11 0 0
-BITMAP
-1F80
-3180
-3180
-FD80
-3180
-3180
-3180
-3180
-3180
-3180
-3180
-ENDCHAR
-ENDFONT
+++ /dev/null
-STARTFONT 2.1
-FONT -Adobe-New Century Schoolbook-Bold-R-Normal--18-180-75-75-P-113-ISO10646-1
-SIZE 18 75 75
-FONTBOUNDINGBOX 24 31 -3 -8
-COMMENT $Xorg: $
-COMMENT ISO10646-1 extension by Markus Kuhn <mkuhn@acm.org>, 2001-03-20
-COMMENT
-COMMENT +
-COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated.
-COMMENT Copyright 1988, 1994 Digital Equipment Corporation.
-COMMENT
-COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be
-COMMENT registered in certain jurisdictions.
-COMMENT Permission to use these trademarks is hereby granted only in
-COMMENT association with the images described in this file.
-COMMENT
-COMMENT Permission to use, copy, modify, distribute and sell this software
-COMMENT and its documentation for any purpose and without fee is hereby
-COMMENT granted, provided that the above copyright notices appear in all
-COMMENT copies and that both those copyright notices and this permission
-COMMENT notice appear in supporting documentation, and that the names of
-COMMENT Adobe Systems and Digital Equipment Corporation not be used in
-COMMENT advertising or publicity pertaining to distribution of the software
-COMMENT without specific, written prior permission. Adobe Systems and
-COMMENT Digital Equipment Corporation make no representations about the
-COMMENT suitability of this software for any purpose. It is provided "as
-COMMENT is" without express or implied warranty.
-COMMENT -
-STARTPROPERTIES 26
-FOUNDRY "Adobe"
-FAMILY_NAME "New Century Schoolbook"
-WEIGHT_NAME "Bold"
-SLANT "R"
-SETWIDTH_NAME "Normal"
-ADD_STYLE_NAME ""
-PIXEL_SIZE 18
-POINT_SIZE 180
-RESOLUTION_X 75
-RESOLUTION_Y 75
-SPACING "P"
-AVERAGE_WIDTH 113
-CHARSET_REGISTRY "ISO10646"
-CHARSET_ENCODING "1"
-CAP_HEIGHT 14
-X_HEIGHT 9
-FONT_ASCENT 16
-FONT_DESCENT 4
-FACE_NAME "New Century Schoolbook Bold"
-COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved."
-NOTICE "New Century Schoolbook is a trademark of Linotype-Hell AG and/or its subsidiaries."
-_DEC_DEVICE_FONTNAMES "PS=NewCenturySchlbk-Bold"
-DEFAULT_CHAR 0
-RELATIVE_SETWIDTH 50
-RELATIVE_WEIGHT 70
-FULL_NAME "New Century Schoolbook Bold"
-ENDPROPERTIES
-CHARS 756
-STARTCHAR char0
-ENCODING 0
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 13 13 1 0
-BITMAP
-AAA8
-0000
-8008
-0000
-8008
-0000
-8008
-0000
-8008
-0000
-8008
-0000
-AAA8
-ENDCHAR
-STARTCHAR space
-ENCODING 32
-SWIDTH 287 0
-DWIDTH 5 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR exclam
-ENCODING 33
-SWIDTH 296 0
-DWIDTH 6 0
-BBX 4 14 1 0
-BITMAP
-60
-F0
-F0
-F0
-F0
-F0
-60
-60
-60
-00
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR quotedbl
-ENCODING 34
-SWIDTH 333 0
-DWIDTH 8 0
-BBX 5 5 1 9
-BITMAP
-D8
-D8
-D8
-D8
-D8
-ENDCHAR
-STARTCHAR numbersign
-ENCODING 35
-SWIDTH 574 0
-DWIDTH 12 0
-BBX 11 13 0 0
-BITMAP
-0D80
-0D80
-0D80
-7FE0
-7FE0
-1B00
-1B00
-FFC0
-FFC0
-3600
-3600
-3600
-3600
-ENDCHAR
-STARTCHAR dollar
-ENCODING 36
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 18 1 -2
-BITMAP
-0800
-0800
-3E00
-6B80
-C980
-C980
-E800
-F800
-7E00
-3F00
-0F80
-0B80
-C980
-C980
-EB80
-7F00
-0800
-0800
-ENDCHAR
-STARTCHAR percent
-ENCODING 37
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 14 14 0 0
-BITMAP
-38C0
-6740
-C4C0
-C480
-C580
-C900
-7300
-0238
-0664
-04C4
-0CC4
-08C4
-18C8
-1070
-ENDCHAR
-STARTCHAR ampersand
-ENCODING 38
-SWIDTH 852 0
-DWIDTH 17 0
-BBX 16 14 0 0
-BITMAP
-0780
-0CC0
-1840
-18C0
-1D80
-1F00
-0E3E
-3F18
-7790
-E3E0
-E1E0
-E0F1
-F1FE
-3F1C
-ENDCHAR
-STARTCHAR quotesingle
-ENCODING 39
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 2 5 1 9
-BITMAP
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR parenleft
-ENCODING 40
-SWIDTH 389 0
-DWIDTH 6 0
-BBX 5 16 1 -2
-BITMAP
-18
-30
-60
-60
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-60
-60
-30
-18
-ENDCHAR
-STARTCHAR parenright
-ENCODING 41
-SWIDTH 389 0
-DWIDTH 6 0
-BBX 5 16 0 -2
-BITMAP
-C0
-60
-30
-30
-18
-18
-18
-18
-18
-18
-18
-18
-30
-30
-60
-C0
-ENDCHAR
-STARTCHAR asterisk
-ENCODING 42
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 7 7 0 7
-BITMAP
-38
-92
-D6
-38
-D6
-92
-38
-ENDCHAR
-STARTCHAR plus
-ENCODING 43
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 10 0 0
-BITMAP
-0C00
-0C00
-0C00
-0C00
-FFC0
-FFC0
-0C00
-0C00
-0C00
-0C00
-ENDCHAR
-STARTCHAR comma
-ENCODING 44
-SWIDTH 278 0
-DWIDTH 5 0
-BBX 4 7 0 -3
-BITMAP
-60
-F0
-F0
-70
-20
-40
-80
-ENDCHAR
-STARTCHAR hyphen
-ENCODING 45
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 5 2 0 4
-BITMAP
-F8
-F8
-ENDCHAR
-STARTCHAR period
-ENCODING 46
-SWIDTH 278 0
-DWIDTH 5 0
-BBX 4 4 0 0
-BITMAP
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR slash
-ENCODING 47
-SWIDTH 278 0
-DWIDTH 7 0
-BBX 6 14 0 0
-BITMAP
-0C
-0C
-0C
-18
-18
-18
-30
-30
-30
-60
-60
-60
-C0
-C0
-ENDCHAR
-STARTCHAR zero
-ENCODING 48
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1C00
-7700
-6300
-E380
-E380
-E380
-E380
-E380
-E380
-E380
-E380
-6300
-7700
-1C00
-ENDCHAR
-STARTCHAR one
-ENCODING 49
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 7 14 2 0
-BITMAP
-18
-38
-F8
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-FE
-ENDCHAR
-STARTCHAR two
-ENCODING 50
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1E00
-6700
-E380
-E380
-6380
-0380
-0700
-0700
-0E00
-1800
-3000
-6080
-FF80
-FF80
-ENDCHAR
-STARTCHAR three
-ENCODING 51
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1E00
-6700
-E380
-E380
-6380
-0300
-1C00
-0300
-0380
-6380
-E380
-E380
-6700
-3E00
-ENDCHAR
-STARTCHAR four
-ENCODING 52
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-0700
-0F00
-0F00
-1700
-1700
-2700
-2700
-4700
-4700
-8700
-FF80
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR five
-ENCODING 53
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-7F80
-7F00
-4000
-4000
-4000
-7E00
-4700
-0380
-0380
-6380
-E380
-E380
-6700
-3E00
-ENDCHAR
-STARTCHAR six
-ENCODING 54
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1F00
-7380
-6380
-E300
-E000
-EE00
-F700
-E380
-E380
-E380
-E380
-6380
-7300
-1C00
-ENDCHAR
-STARTCHAR seven
-ENCODING 55
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-FF80
-FF80
-FF80
-8300
-0600
-0600
-0C00
-0C00
-1C00
-1C00
-3800
-3800
-3800
-3800
-ENDCHAR
-STARTCHAR eight
-ENCODING 56
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1C00
-6300
-C180
-C180
-E180
-FB00
-7E00
-3F00
-4F80
-C380
-C180
-C180
-E300
-3C00
-ENDCHAR
-STARTCHAR nine
-ENCODING 57
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1C00
-6700
-E300
-E380
-E380
-E380
-E380
-7780
-3B80
-0380
-6380
-E300
-E700
-7C00
-ENDCHAR
-STARTCHAR colon
-ENCODING 58
-SWIDTH 278 0
-DWIDTH 6 0
-BBX 4 9 1 0
-BITMAP
-60
-F0
-F0
-60
-00
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR semicolon
-ENCODING 59
-SWIDTH 278 0
-DWIDTH 6 0
-BBX 4 12 1 -3
-BITMAP
-60
-F0
-F0
-60
-00
-60
-F0
-F0
-70
-20
-40
-80
-ENDCHAR
-STARTCHAR less
-ENCODING 60
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 10 0 0
-BITMAP
-00C0
-03C0
-0F00
-3C00
-F000
-F000
-3C00
-0F00
-03C0
-00C0
-ENDCHAR
-STARTCHAR equal
-ENCODING 61
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 6 1 2
-BITMAP
-FF80
-FF80
-0000
-0000
-FF80
-FF80
-ENDCHAR
-STARTCHAR greater
-ENCODING 62
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 10 0 0
-BITMAP
-C000
-F000
-3C00
-0F00
-03C0
-03C0
-0F00
-3C00
-F000
-C000
-ENDCHAR
-STARTCHAR question
-ENCODING 63
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-1F00
-6780
-E380
-E380
-6380
-0300
-0600
-0C00
-1800
-0000
-1800
-3C00
-3C00
-1800
-ENDCHAR
-STARTCHAR at
-ENCODING 64
-SWIDTH 747 0
-DWIDTH 16 0
-BBX 15 14 0 0
-BITMAP
-07F0
-1C1C
-300C
-63E6
-6666
-CC66
-CC66
-D8CC
-D8CC
-D9D8
-CEF0
-6008
-7870
-1FC0
-ENDCHAR
-STARTCHAR A
-ENCODING 65
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 14 0 0
-BITMAP
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR B
-ENCODING 66
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 14 1 0
-BITMAP
-FFC0
-71E0
-70E0
-70E0
-70E0
-71C0
-7F80
-70E0
-70F0
-7070
-7070
-7070
-70E0
-FF80
-ENDCHAR
-STARTCHAR C
-ENCODING 67
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 14 1 0
-BITMAP
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-ENDCHAR
-STARTCHAR D
-ENCODING 68
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-ENDCHAR
-STARTCHAR E
-ENCODING 69
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR F
-ENCODING 70
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7320
-7F00
-7300
-7100
-7100
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR G
-ENCODING 71
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 14 1 0
-BITMAP
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR H
-ENCODING 72
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-ENDCHAR
-STARTCHAR I
-ENCODING 73
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 5 14 2 0
-BITMAP
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR J
-ENCODING 74
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-07E0
-01C0
-01C0
-01C0
-01C0
-01C0
-01C0
-01C0
-61C0
-F1C0
-F1C0
-C3C0
-4780
-3E00
-ENDCHAR
-STARTCHAR K
-ENCODING 75
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 14 1 0
-BITMAP
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-ENDCHAR
-STARTCHAR L
-ENCODING 76
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 14 1 0
-BITMAP
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR M
-ENCODING 77
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 17 14 1 0
-BITMAP
-7C0780
-3C0F00
-3E0F00
-2E1F00
-2F1700
-2F1700
-273700
-27A700
-23E700
-23C700
-23C700
-21C700
-718700
-F88F80
-ENDCHAR
-STARTCHAR N
-ENCODING 78
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 1 0
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR O
-ENCODING 79
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 0 0
-BITMAP
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR P
-ENCODING 80
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 12 14 1 0
-BITMAP
-FFE0
-70F0
-7070
-7070
-7070
-70F0
-71E0
-7F80
-7000
-7000
-7000
-7000
-7000
-FC00
-ENDCHAR
-STARTCHAR Q
-ENCODING 81
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 0 -4
-BITMAP
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F79E
-79DC
-70FC
-3CF8
-0FE0
-0060
-0074
-007C
-0038
-ENDCHAR
-STARTCHAR R
-ENCODING 82
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-ENDCHAR
-STARTCHAR S
-ENCODING 83
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-ENDCHAR
-STARTCHAR T
-ENCODING 84
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-ENDCHAR
-STARTCHAR U
-ENCODING 85
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR V
-ENCODING 86
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 14 0 0
-BITMAP
-F87C
-7038
-7830
-3820
-3820
-3C60
-1C40
-1E40
-0EC0
-0E80
-0780
-0780
-0300
-0300
-ENDCHAR
-STARTCHAR W
-ENCODING 87
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 14 0 0
-BITMAP
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR X
-ENCODING 88
-SWIDTH 722 0
-DWIDTH 17 0
-BBX 16 14 0 0
-BITMAP
-7E3F
-3C1C
-1E18
-0E30
-0F60
-07C0
-03C0
-03E0
-06F0
-0C70
-1878
-303C
-703E
-F87F
-ENDCHAR
-STARTCHAR Y
-ENCODING 89
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 14 1 0
-BITMAP
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR Z
-ENCODING 90
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-0F00
-1E00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-ENDCHAR
-STARTCHAR bracketleft
-ENCODING 91
-SWIDTH 389 0
-DWIDTH 5 0
-BBX 4 16 1 -2
-BITMAP
-F0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-F0
-ENDCHAR
-STARTCHAR backslash
-ENCODING 92
-SWIDTH 606 0
-DWIDTH 9 0
-BBX 8 14 0 0
-BITMAP
-C0
-C0
-60
-60
-30
-30
-18
-18
-0C
-0C
-06
-06
-03
-03
-ENDCHAR
-STARTCHAR bracketright
-ENCODING 93
-SWIDTH 389 0
-DWIDTH 5 0
-BBX 4 16 0 -2
-BITMAP
-F0
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-30
-F0
-ENDCHAR
-STARTCHAR asciicircum
-ENCODING 94
-SWIDTH 606 0
-DWIDTH 9 0
-BBX 8 8 0 6
-BITMAP
-18
-18
-3C
-3C
-66
-66
-C3
-C3
-ENDCHAR
-STARTCHAR underscore
-ENCODING 95
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 10 2 0 -3
-BITMAP
-FFC0
-FFC0
-ENDCHAR
-STARTCHAR grave
-ENCODING 96
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 10
-BITMAP
-C0
-E0
-70
-18
-ENDCHAR
-STARTCHAR a
-ENCODING 97
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 9 0 0
-BITMAP
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR b
-ENCODING 98
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 12 14 -1 0
-BITMAP
-F000
-7000
-7000
-7000
-7000
-7780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-6F80
-ENDCHAR
-STARTCHAR c
-ENCODING 99
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 9 0 0
-BITMAP
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-ENDCHAR
-STARTCHAR d
-ENCODING 100
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-01E0
-00E0
-00E0
-00E0
-00E0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-ENDCHAR
-STARTCHAR e
-ENCODING 101
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 9 0 0
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR f
-ENCODING 102
-SWIDTH 389 0
-DWIDTH 7 0
-BBX 8 14 0 0
-BITMAP
-1E
-37
-77
-70
-70
-FC
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR g
-ENCODING 103
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 15 0 -4
-BITMAP
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR h
-ENCODING 104
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR i
-ENCODING 105
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 5 14 0 0
-BITMAP
-70
-70
-70
-00
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR j
-ENCODING 106
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 7 18 -3 -4
-BITMAP
-0E
-0E
-0E
-00
-00
-1E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-EE
-EC
-78
-ENDCHAR
-STARTCHAR k
-ENCODING 107
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-F000
-7000
-7000
-7000
-7000
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-ENDCHAR
-STARTCHAR l
-ENCODING 108
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 5 14 0 0
-BITMAP
-F0
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR m
-ENCODING 109
-SWIDTH 963 0
-DWIDTH 20 0
-BBX 19 9 0 0
-BITMAP
-F7DF80
-79F3C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-F9F3E0
-ENDCHAR
-STARTCHAR n
-ENCODING 110
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 9 0 0
-BITMAP
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR o
-ENCODING 111
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 9 0 0
-BITMAP
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR p
-ENCODING 112
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 12 13 -1 -4
-BITMAP
-E780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-7780
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR q
-ENCODING 113
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 12 13 0 -4
-BITMAP
-1E60
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EE0
-00E0
-00E0
-00E0
-01F0
-ENDCHAR
-STARTCHAR r
-ENCODING 114
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 9 0 0
-BITMAP
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR s
-ENCODING 115
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 9 0 0
-BITMAP
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR t
-ENCODING 116
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 13 0 0
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-ENDCHAR
-STARTCHAR u
-ENCODING 117
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 9 0 0
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR v
-ENCODING 118
-SWIDTH 611 0
-DWIDTH 9 0
-BBX 10 9 -1 0
-BITMAP
-F9C0
-7080
-7080
-3900
-3900
-1E00
-1E00
-0C00
-0C00
-ENDCHAR
-STARTCHAR w
-ENCODING 119
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 9 -1 0
-BITMAP
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR x
-ENCODING 120
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 9 0 0
-BITMAP
-FCE0
-78C0
-3D00
-1E00
-0E00
-0F00
-1780
-63C0
-E7E0
-ENDCHAR
-STARTCHAR y
-ENCODING 121
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 -4
-BITMAP
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR z
-ENCODING 122
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 9 0 0
-BITMAP
-FF
-CF
-8E
-1C
-38
-39
-71
-F3
-FF
-ENDCHAR
-STARTCHAR braceleft
-ENCODING 123
-SWIDTH 389 0
-DWIDTH 6 0
-BBX 5 16 0 -2
-BITMAP
-18
-20
-60
-60
-60
-60
-60
-C0
-60
-60
-60
-60
-60
-60
-20
-18
-ENDCHAR
-STARTCHAR bar
-ENCODING 124
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 2 14 4 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR braceright
-ENCODING 125
-SWIDTH 389 0
-DWIDTH 6 0
-BBX 5 16 0 -2
-BITMAP
-C0
-20
-30
-30
-30
-30
-30
-18
-30
-30
-30
-30
-30
-30
-20
-C0
-ENDCHAR
-STARTCHAR asciitilde
-ENCODING 126
-SWIDTH 606 0
-DWIDTH 12 0
-BBX 10 3 1 4
-BITMAP
-39C0
-7F80
-E700
-ENDCHAR
-STARTCHAR space
-ENCODING 160
-SWIDTH 287 0
-DWIDTH 5 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR exclamdown
-ENCODING 161
-SWIDTH 296 0
-DWIDTH 7 0
-BBX 4 14 1 -4
-BITMAP
-60
-F0
-F0
-60
-00
-60
-60
-60
-F0
-F0
-F0
-F0
-F0
-60
-ENDCHAR
-STARTCHAR cent
-ENCODING 162
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 13 1 -2
-BITMAP
-0080
-0080
-1F00
-7380
-E380
-E400
-E400
-E800
-E880
-7180
-1E00
-2000
-2000
-ENDCHAR
-STARTCHAR sterling
-ENCODING 163
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-1F00
-3180
-7380
-7380
-7000
-7000
-3800
-FF80
-1C00
-1C00
-1840
-70C0
-9FC0
-EF80
-ENDCHAR
-STARTCHAR currency
-ENCODING 164
-SWIDTH 606 0
-DWIDTH 10 0
-BBX 9 9 0 2
-BITMAP
-DD80
-FF80
-6300
-C180
-C180
-C180
-6300
-FF80
-DD80
-ENDCHAR
-STARTCHAR yen
-ENCODING 165
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 14 1 0
-BITMAP
-F878
-7030
-7820
-3860
-1C40
-1CC0
-0F80
-1FC0
-0700
-1FC0
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR brokenbar
-ENCODING 166
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 2 14 4 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-00
-00
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR section
-ENCODING 167
-SWIDTH 500 0
-DWIDTH 8 0
-BBX 7 16 0 -2
-BITMAP
-78
-CC
-8C
-C0
-70
-7C
-9E
-86
-C2
-F2
-7C
-1C
-04
-C4
-CC
-78
-ENDCHAR
-STARTCHAR dieresis
-ENCODING 168
-SWIDTH 333 0
-DWIDTH 10 0
-BBX 6 2 2 10
-BITMAP
-CC
-CC
-ENDCHAR
-STARTCHAR copyright
-ENCODING 169
-SWIDTH 747 0
-DWIDTH 15 0
-BBX 14 14 0 0
-BITMAP
-0780
-1860
-2010
-47C8
-4CC8
-9844
-9804
-9804
-9804
-4C48
-4788
-2010
-1860
-0780
-ENDCHAR
-STARTCHAR ordfeminine
-ENCODING 170
-SWIDTH 367 0
-DWIDTH 8 0
-BBX 7 8 0 6
-BITMAP
-78
-CC
-3C
-CC
-DC
-6E
-00
-FE
-ENDCHAR
-STARTCHAR guillemotleft
-ENCODING 171
-SWIDTH 500 0
-DWIDTH 9 0
-BBX 8 5 0 3
-BITMAP
-11
-66
-CC
-66
-11
-ENDCHAR
-STARTCHAR logicalnot
-ENCODING 172
-SWIDTH 606 0
-DWIDTH 10 0
-BBX 9 6 0 2
-BITMAP
-FF80
-FF80
-0180
-0180
-0180
-0180
-ENDCHAR
-STARTCHAR hyphen
-ENCODING 173
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 5 2 0 4
-BITMAP
-F8
-F8
-ENDCHAR
-STARTCHAR registered
-ENCODING 174
-SWIDTH 747 0
-DWIDTH 15 0
-BBX 14 14 0 0
-BITMAP
-0780
-1860
-2010
-5F88
-4CC8
-8CC4
-8F84
-8D84
-8CC4
-5EE8
-4008
-2010
-1860
-0780
-ENDCHAR
-STARTCHAR macron
-ENCODING 175
-SWIDTH 333 0
-DWIDTH 8 0
-BBX 6 2 1 10
-BITMAP
-FC
-FC
-ENDCHAR
-STARTCHAR degree
-ENCODING 176
-SWIDTH 400 0
-DWIDTH 7 0
-BBX 6 6 0 8
-BITMAP
-78
-CC
-84
-84
-CC
-78
-ENDCHAR
-STARTCHAR plusminus
-ENCODING 177
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 11 0 0
-BITMAP
-0C00
-0C00
-0C00
-FFC0
-FFC0
-0C00
-0C00
-0C00
-0000
-FFC0
-FFC0
-ENDCHAR
-STARTCHAR twosuperior
-ENCODING 178
-SWIDTH 344 0
-DWIDTH 6 0
-BBX 6 8 0 6
-BITMAP
-78
-CC
-CC
-18
-30
-60
-C4
-FC
-ENDCHAR
-STARTCHAR threesuperior
-ENCODING 179
-SWIDTH 344 0
-DWIDTH 6 0
-BBX 6 8 0 6
-BITMAP
-78
-CC
-0C
-38
-0C
-CC
-CC
-78
-ENDCHAR
-STARTCHAR acute
-ENCODING 180
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 10
-BITMAP
-18
-38
-70
-C0
-ENDCHAR
-STARTCHAR mu
-ENCODING 181
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 -4
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-7EF0
-6000
-7000
-7000
-2000
-ENDCHAR
-STARTCHAR paragraph
-ENCODING 182
-SWIDTH 747 0
-DWIDTH 14 0
-BBX 13 14 0 0
-BITMAP
-3FF8
-7E70
-FE70
-FE70
-FE70
-FE70
-7E70
-3E70
-0E70
-0E70
-0E70
-0E70
-0E70
-1FF8
-ENDCHAR
-STARTCHAR periodcentered
-ENCODING 183
-SWIDTH 278 0
-DWIDTH 5 0
-BBX 4 4 0 3
-BITMAP
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR cedilla
-ENCODING 184
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 4 4 1 -4
-BITMAP
-40
-70
-30
-E0
-ENDCHAR
-STARTCHAR onesuperior
-ENCODING 185
-SWIDTH 344 0
-DWIDTH 6 0
-BBX 6 8 0 6
-BITMAP
-30
-F0
-30
-30
-30
-30
-30
-FC
-ENDCHAR
-STARTCHAR ordmasculine
-ENCODING 186
-SWIDTH 367 0
-DWIDTH 7 0
-BBX 6 8 0 6
-BITMAP
-78
-CC
-CC
-CC
-CC
-78
-00
-FC
-ENDCHAR
-STARTCHAR guillemotright
-ENCODING 187
-SWIDTH 500 0
-DWIDTH 9 0
-BBX 8 5 0 3
-BITMAP
-88
-66
-33
-66
-88
-ENDCHAR
-STARTCHAR onequarter
-ENCODING 188
-SWIDTH 861 0
-DWIDTH 15 0
-BBX 14 14 0 0
-BITMAP
-3060
-F060
-30C0
-30C0
-3180
-3180
-3318
-FF38
-0678
-06D8
-0D98
-0DFC
-1818
-183C
-ENDCHAR
-STARTCHAR onehalf
-ENCODING 189
-SWIDTH 861 0
-DWIDTH 15 0
-BBX 14 14 0 0
-BITMAP
-3060
-F060
-30C0
-30C0
-3180
-3180
-3378
-FFCC
-06CC
-0618
-0C30
-0C60
-18C4
-18FC
-ENDCHAR
-STARTCHAR threequarters
-ENCODING 190
-SWIDTH 861 0
-DWIDTH 15 0
-BBX 14 14 0 0
-BITMAP
-7860
-CC60
-0CC0
-38C0
-0D80
-CD80
-CF18
-7B38
-0678
-06D8
-0D98
-0DFC
-1818
-183C
-ENDCHAR
-STARTCHAR questiondown
-ENCODING 191
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 14 0 -4
-BITMAP
-0C00
-1E00
-1E00
-0C00
-0000
-0C00
-1800
-3000
-6000
-E300
-E380
-E380
-F300
-7C00
-ENDCHAR
-STARTCHAR Agrave
-ENCODING 192
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 19 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR Aacute
-ENCODING 193
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 19 0 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR Acircumflex
-ENCODING 194
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0380
-07C0
-0C60
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR Atilde
-ENCODING 195
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0620
-0FC0
-1180
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR Adieresis
-ENCODING 196
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 17 0 0
-BITMAP
-0CC0
-0CC0
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR Aring
-ENCODING 197
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0300
-0480
-0480
-0300
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR AE
-ENCODING 198
-SWIDTH 981 0
-DWIDTH 21 0
-BBX 20 14 0 0
-BITMAP
-03FFF0
-00B870
-01B830
-013890
-033890
-063980
-043F80
-0C3980
-1FF880
-103890
-203810
-203830
-603870
-F1FFF0
-ENDCHAR
-STARTCHAR Ccedilla
-ENCODING 199
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 18 1 -4
-BITMAP
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-0400
-0700
-0300
-0E00
-ENDCHAR
-STARTCHAR Egrave
-ENCODING 200
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR Eacute
-ENCODING 201
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR Ecircumflex
-ENCODING 202
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 0
-BITMAP
-0E00
-1F00
-3180
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR Edieresis
-ENCODING 203
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 17 1 0
-BITMAP
-1980
-1980
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR Igrave
-ENCODING 204
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 5 19 2 0
-BITMAP
-C0
-E0
-70
-18
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Iacute
-ENCODING 205
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 6 19 2 0
-BITMAP
-0C
-1C
-38
-60
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Icircumflex
-ENCODING 206
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 7 18 1 0
-BITMAP
-38
-7C
-C6
-00
-7C
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR Idieresis
-ENCODING 207
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 6 17 2 0
-BITMAP
-CC
-CC
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Eth
-ENCODING 208
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 0 0
-BITMAP
-7FE0
-3878
-383C
-381C
-381E
-380E
-FE0E
-380E
-380E
-381E
-381C
-383C
-3878
-7FE0
-ENDCHAR
-STARTCHAR Ntilde
-ENCODING 209
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 1 0
-BITMAP
-0310
-07E0
-08C0
-0000
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR Ograve
-ENCODING 210
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 0 0
-BITMAP
-0C00
-0E00
-0700
-0180
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR Oacute
-ENCODING 211
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 0 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR Ocircumflex
-ENCODING 212
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 0 0
-BITMAP
-0380
-07C0
-0C60
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR Otilde
-ENCODING 213
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 0 0
-BITMAP
-0310
-07E0
-08C0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR Odieresis
-ENCODING 214
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 0 0
-BITMAP
-0660
-0660
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR multiply
-ENCODING 215
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 10 0 0
-BITMAP
-C0C0
-E1C0
-7380
-3F00
-1E00
-1E00
-3F00
-7380
-E1C0
-C0C0
-ENDCHAR
-STARTCHAR Oslash
-ENCODING 216
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-0FC8
-38F0
-7078
-7078
-E0BC
-E11C
-E21C
-E21C
-E41C
-E83C
-7038
-7078
-78F0
-8FC0
-ENDCHAR
-STARTCHAR Ugrave
-ENCODING 217
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-0C00
-0E00
-0700
-0180
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR Uacute
-ENCODING 218
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR Ucircumflex
-ENCODING 219
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 0
-BITMAP
-0380
-07C0
-0C60
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR Udieresis
-ENCODING 220
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 0
-BITMAP
-0CC0
-0CC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR Yacute
-ENCODING 221
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 19 1 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR Thorn
-ENCODING 222
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 12 14 1 0
-BITMAP
-F800
-7000
-7000
-7FC0
-70F0
-7070
-7070
-7070
-7070
-70E0
-7F80
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR germandbls
-ENCODING 223
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-1E00
-3380
-71C0
-71C0
-71C0
-7180
-7700
-71C0
-70E0
-70E0
-70E0
-70E0
-71C0
-F700
-ENDCHAR
-STARTCHAR agrave
-ENCODING 224
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR aacute
-ENCODING 225
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-0600
-0E00
-1C00
-3000
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR acircumflex
-ENCODING 226
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-1C00
-3E00
-6300
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR atilde
-ENCODING 227
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-1880
-3F00
-4600
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR adieresis
-ENCODING 228
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 12 0 0
-BITMAP
-3300
-3300
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR aring
-ENCODING 229
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-0C00
-1200
-1200
-0C00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR ae
-ENCODING 230
-SWIDTH 870 0
-DWIDTH 17 0
-BBX 16 9 0 0
-BITMAP
-3F78
-63CE
-E387
-0787
-3BFF
-E380
-E381
-E7C3
-78FC
-ENDCHAR
-STARTCHAR ccedilla
-ENCODING 231
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 13 0 -4
-BITMAP
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-1000
-1C00
-0C00
-3800
-ENDCHAR
-STARTCHAR egrave
-ENCODING 232
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR eacute
-ENCODING 233
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-0600
-0E00
-1C00
-3000
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR ecircumflex
-ENCODING 234
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-0E00
-1F00
-3180
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR edieresis
-ENCODING 235
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 12 0 0
-BITMAP
-3300
-3300
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR igrave
-ENCODING 236
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 5 14 0 0
-BITMAP
-C0
-E0
-70
-18
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR iacute
-ENCODING 237
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 5 14 0 0
-BITMAP
-18
-38
-70
-C0
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR icircumflex
-ENCODING 238
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 7 13 -1 0
-BITMAP
-38
-7C
-C6
-00
-78
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR idieresis
-ENCODING 239
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 6 12 0 0
-BITMAP
-CC
-CC
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR eth
-ENCODING 240
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-6000
-1B00
-1C00
-6600
-0300
-1F80
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR ntilde
-ENCODING 241
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 0
-BITMAP
-0C40
-1F80
-2300
-0000
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR ograve
-ENCODING 242
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR oacute
-ENCODING 243
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR ocircumflex
-ENCODING 244
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 0
-BITMAP
-0E00
-1F00
-3180
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR otilde
-ENCODING 245
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 0
-BITMAP
-1880
-3F00
-4600
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR odieresis
-ENCODING 246
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 12 0 0
-BITMAP
-1980
-1980
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR divide
-ENCODING 247
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 10 0 0
-BITMAP
-0C00
-0C00
-0000
-0000
-FFC0
-FFC0
-0000
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR oslash
-ENCODING 248
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 11 0 -1
-BITMAP
-0100
-1F00
-7380
-E3C0
-E5C0
-E5C0
-E9C0
-E9C0
-7380
-3E00
-2000
-ENDCHAR
-STARTCHAR ugrave
-ENCODING 249
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uacute
-ENCODING 250
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR ucircumflex
-ENCODING 251
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 0
-BITMAP
-0700
-0F80
-18C0
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR udieresis
-ENCODING 252
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 0
-BITMAP
-1980
-1980
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR yacute
-ENCODING 253
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 -4
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR thorn
-ENCODING 254
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 12 18 -1 -4
-BITMAP
-F000
-7000
-7000
-7000
-7000
-7780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-7780
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR ydieresis
-ENCODING 255
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 -4
-BITMAP
-1980
-1980
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR Amacron
-ENCODING 256
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 17 0 0
-BITMAP
-0FC0
-0FC0
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR amacron
-ENCODING 257
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 12 0 0
-BITMAP
-3F00
-3F00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR Abreve
-ENCODING 258
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0840
-0CC0
-0780
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR abreve
-ENCODING 259
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-2100
-3300
-1E00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR Aogonek
-ENCODING 260
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 -4
-BITMAP
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-0180
-0300
-0340
-0180
-ENDCHAR
-STARTCHAR aogonek
-ENCODING 261
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 13 0 -4
-BITMAP
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-0C00
-1800
-1A00
-0C00
-ENDCHAR
-STARTCHAR Cacute
-ENCODING 262
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-ENDCHAR
-STARTCHAR cacute
-ENCODING 263
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-ENDCHAR
-STARTCHAR Ccircumflex
-ENCODING 264
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 19 1 0
-BITMAP
-0200
-0700
-0F80
-18C0
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-ENDCHAR
-STARTCHAR ccircumflex
-ENCODING 265
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-0800
-1C00
-3E00
-6300
-0000
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-ENDCHAR
-STARTCHAR Cdotaccent
-ENCODING 266
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 17 1 0
-BITMAP
-0600
-0600
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-ENDCHAR
-STARTCHAR cdotaccent
-ENCODING 267
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 12 0 0
-BITMAP
-0C00
-0C00
-0000
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-ENDCHAR
-STARTCHAR Ccaron
-ENCODING 268
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-ENDCHAR
-STARTCHAR ccaron
-ENCODING 269
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-6300
-3E00
-1C00
-0800
-0000
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-ENDCHAR
-STARTCHAR Dcaron
-ENCODING 270
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-ENDCHAR
-STARTCHAR dcaron
-ENCODING 271
-SWIDTH 875 0
-DWIDTH 17 0
-BBX 16 14 0 0
-BITMAP
-01E6
-00EF
-00EF
-00E7
-00E2
-1EE4
-71E8
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-ENDCHAR
-STARTCHAR Dcroat
-ENCODING 272
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 0 0
-BITMAP
-7FE0
-3878
-383C
-381C
-381E
-380E
-FE0E
-380E
-380E
-381E
-381C
-383C
-3878
-7FE0
-ENDCHAR
-STARTCHAR dcroat
-ENCODING 273
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-01E0
-00E0
-00E0
-01F0
-01F0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-ENDCHAR
-STARTCHAR Emacron
-ENCODING 274
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 17 1 0
-BITMAP
-1F80
-1F80
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR emacron
-ENCODING 275
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 12 0 0
-BITMAP
-3F00
-3F00
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR Ebreve
-ENCODING 276
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 0
-BITMAP
-1080
-1980
-0F00
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR ebreve
-ENCODING 277
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-2100
-3300
-1E00
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR Edotaccent
-ENCODING 278
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 17 1 0
-BITMAP
-0600
-0600
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR edotaccent
-ENCODING 279
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 12 0 0
-BITMAP
-0C00
-0C00
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR Eogonek
-ENCODING 280
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 -4
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0600
-0C00
-0D00
-0600
-ENDCHAR
-STARTCHAR eogonek
-ENCODING 281
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 -4
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0C00
-1800
-1A00
-0C00
-ENDCHAR
-STARTCHAR Ecaron
-ENCODING 282
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR ecaron
-ENCODING 283
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR Gcircumflex
-ENCODING 284
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 19 1 0
-BITMAP
-0200
-0700
-0F80
-18C0
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR gcircumflex
-ENCODING 285
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 20 0 -4
-BITMAP
-0200
-0700
-0F80
-18C0
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR Gbreve
-ENCODING 286
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 18 1 0
-BITMAP
-1080
-1980
-0F00
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR gbreve
-ENCODING 287
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 19 0 -4
-BITMAP
-1080
-1980
-0F00
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR Gdotaccent
-ENCODING 288
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 17 1 0
-BITMAP
-0600
-0600
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR gdotaccent
-ENCODING 289
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 18 0 -4
-BITMAP
-0600
-0600
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR Gcommaaccent
-ENCODING 290
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 22 1 -8
-BITMAP
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-0000
-0300
-0780
-0780
-0380
-0100
-0200
-0400
-ENDCHAR
-STARTCHAR gcommaaccent
-ENCODING 291
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 23 0 -4
-BITMAP
-0100
-0200
-0400
-0E00
-0F00
-0F00
-0600
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR Hcircumflex
-ENCODING 292
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-0100
-0380
-07C0
-0C60
-0000
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-ENDCHAR
-STARTCHAR hcircumflex
-ENCODING 293
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 19 0 0
-BITMAP
-1000
-3800
-7C00
-C600
-0000
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR Hbar
-ENCODING 294
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-FCFC
-7038
-7038
-7038
-FFFC
-FFFC
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-ENDCHAR
-STARTCHAR hbar
-ENCODING 295
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-F000
-7000
-7000
-7C00
-7C00
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR Itilde
-ENCODING 296
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 8 18 1 0
-BITMAP
-31
-7E
-8C
-00
-7C
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR itilde
-ENCODING 297
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 8 13 -1 0
-BITMAP
-31
-7E
-8C
-00
-78
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR Imacron
-ENCODING 298
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 6 17 2 0
-BITMAP
-FC
-FC
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR imacron
-ENCODING 299
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 6 12 -1 0
-BITMAP
-FC
-FC
-00
-78
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR Ibreve
-ENCODING 300
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 6 18 2 0
-BITMAP
-84
-CC
-78
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR ibreve
-ENCODING 301
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 6 13 -1 0
-BITMAP
-84
-CC
-78
-00
-78
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR Iogonek
-ENCODING 302
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 5 18 2 -4
-BITMAP
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-30
-60
-68
-30
-ENDCHAR
-STARTCHAR iogonek
-ENCODING 303
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 5 18 0 -4
-BITMAP
-70
-70
-70
-00
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-30
-60
-68
-30
-ENDCHAR
-STARTCHAR Idotaccent
-ENCODING 304
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 5 17 2 0
-BITMAP
-30
-30
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR dotlessi
-ENCODING 305
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 5 9 0 0
-BITMAP
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR IJ
-ENCODING 306
-SWIDTH 1070 0
-DWIDTH 21 0
-BBX 18 14 2 0
-BITMAP
-F80FC0
-700380
-700380
-700380
-700380
-700380
-700380
-700380
-70C380
-71E380
-71E380
-718780
-708F00
-F87C00
-ENDCHAR
-STARTCHAR ij
-ENCODING 307
-SWIDTH 704 0
-DWIDTH 12 0
-BBX 10 18 0 -4
-BITMAP
-71C0
-71C0
-71C0
-0000
-0000
-F3C0
-71C0
-71C0
-71C0
-71C0
-71C0
-71C0
-71C0
-F9C0
-01C0
-1DC0
-1D80
-0F00
-ENDCHAR
-STARTCHAR Jcircumflex
-ENCODING 308
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 11 19 0 0
-BITMAP
-0100
-0380
-07C0
-0C60
-0000
-07E0
-01C0
-01C0
-01C0
-01C0
-01C0
-01C0
-01C0
-61C0
-F1C0
-F1C0
-C3C0
-4780
-3E00
-ENDCHAR
-STARTCHAR jcircumflex
-ENCODING 309
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 8 18 -3 -4
-BITMAP
-08
-1C
-3E
-63
-00
-1E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-EE
-EC
-78
-ENDCHAR
-STARTCHAR Kcommaaccent
-ENCODING 310
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 22 1 -8
-BITMAP
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-0000
-0180
-03C0
-03C0
-01C0
-0080
-0100
-0200
-ENDCHAR
-STARTCHAR kcommaaccent
-ENCODING 311
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 22 0 -8
-BITMAP
-F000
-7000
-7000
-7000
-7000
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-0000
-0600
-0F00
-0F00
-0700
-0200
-0400
-0800
-ENDCHAR
-STARTCHAR kgreenlandic
-ENCODING 312
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 9 0 0
-BITMAP
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-ENDCHAR
-STARTCHAR Lacute
-ENCODING 313
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 19 1 0
-BITMAP
-0600
-0E00
-1C00
-3000
-0000
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR lacute
-ENCODING 314
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 5 19 0 0
-BITMAP
-18
-38
-70
-C0
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Lcommaaccent
-ENCODING 315
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 22 1 -8
-BITMAP
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-0000
-0C00
-1E00
-1E00
-0E00
-0400
-0800
-1000
-ENDCHAR
-STARTCHAR lcommaaccent
-ENCODING 316
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 5 22 0 -8
-BITMAP
-F0
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-00
-30
-78
-78
-38
-10
-20
-40
-ENDCHAR
-STARTCHAR Lcaron
-ENCODING 317
-SWIDTH 927 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-FC18
-703C
-703C
-701C
-7008
-7010
-7020
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR lcaron
-ENCODING 318
-SWIDTH 575 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-F180
-73C0
-73C0
-71C0
-7080
-7100
-7200
-7000
-7000
-7000
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR Ldot
-ENCODING 319
-SWIDTH 964 0
-DWIDTH 16 0
-BBX 14 14 1 0
-BITMAP
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7018
-703C
-703C
-7038
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR ldot
-ENCODING 320
-SWIDTH 612 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-F000
-7000
-7000
-7000
-7000
-7000
-7000
-7180
-73C0
-73C0
-7180
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR Lslash
-ENCODING 321
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 12 14 -1 0
-BITMAP
-7E00
-3C00
-3C00
-3C00
-3D00
-3E00
-3C00
-3C00
-7C00
-BC10
-3C10
-3C30
-3C70
-7FF0
-ENDCHAR
-STARTCHAR lslash
-ENCODING 322
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 6 14 0 0
-BITMAP
-F0
-70
-70
-70
-74
-78
-70
-F0
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Nacute
-ENCODING 323
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 1 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR nacute
-ENCODING 324
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR Ncommaaccent
-ENCODING 325
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 22 1 -8
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-0000
-0300
-0780
-0780
-0380
-0100
-0200
-0400
-ENDCHAR
-STARTCHAR ncommaaccent
-ENCODING 326
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 -8
-BITMAP
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-0600
-0F00
-0F00
-0700
-0200
-0400
-0800
-ENDCHAR
-STARTCHAR Ncaron
-ENCODING 327
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR ncaron
-ENCODING 328
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR napostrophe
-ENCODING 329
-SWIDTH 914 0
-DWIDTH 18 0
-BBX 17 14 0 0
-BITMAP
-600000
-F00000
-F00000
-700000
-200000
-47BE00
-83CF00
-038700
-038700
-038700
-038700
-038700
-038700
-07CF80
-ENDCHAR
-STARTCHAR Eng
-ENCODING 330
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 1 -4
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F838
-0038
-03B8
-03B0
-01E0
-ENDCHAR
-STARTCHAR eng
-ENCODING 331
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 11 13 0 -4
-BITMAP
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F8E0
-00E0
-0EE0
-0EC0
-0780
-ENDCHAR
-STARTCHAR Omacron
-ENCODING 332
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 0 0
-BITMAP
-07E0
-07E0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR omacron
-ENCODING 333
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 12 0 0
-BITMAP
-1F80
-1F80
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR Obreve
-ENCODING 334
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 0 0
-BITMAP
-0420
-0660
-03C0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR obreve
-ENCODING 335
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 0
-BITMAP
-1080
-1980
-0F00
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR Ohungarumlaut
-ENCODING 336
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 0 0
-BITMAP
-0660
-0660
-0CC0
-0880
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR ohungarumlaut
-ENCODING 337
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-1980
-1980
-3300
-2200
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR OE
-ENCODING 338
-SWIDTH 1000 0
-DWIDTH 22 0
-BBX 21 14 0 0
-BITMAP
-0FFFF8
-3C7C38
-783C18
-783C48
-F03C48
-F03CC0
-F03FC0
-F03CC0
-F03C40
-F03C48
-783C08
-783C18
-3C7C38
-0FFFF8
-ENDCHAR
-STARTCHAR oe
-ENCODING 339
-SWIDTH 907 0
-DWIDTH 19 0
-BBX 18 9 0 0
-BITMAP
-1F1E00
-71F380
-E0E1C0
-E0E1C0
-E0FFC0
-E0E000
-E0E040
-71F0C0
-1F1F00
-ENDCHAR
-STARTCHAR Racute
-ENCODING 340
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-ENDCHAR
-STARTCHAR racute
-ENCODING 341
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 14 0 0
-BITMAP
-06
-0E
-1C
-30
-00
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Rcommaaccent
-ENCODING 342
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 22 1 -8
-BITMAP
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-0000
-0300
-0780
-0780
-0380
-0100
-0200
-0400
-ENDCHAR
-STARTCHAR rcommaaccent
-ENCODING 343
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 17 0 -8
-BITMAP
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-00
-30
-78
-78
-38
-10
-20
-40
-ENDCHAR
-STARTCHAR Rcaron
-ENCODING 344
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-ENDCHAR
-STARTCHAR rcaron
-ENCODING 345
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 14 0 0
-BITMAP
-63
-3E
-1C
-08
-00
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR Sacute
-ENCODING 346
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 19 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-ENDCHAR
-STARTCHAR sacute
-ENCODING 347
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-0600
-0E00
-1C00
-3000
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR Scircumflex
-ENCODING 348
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 19 0 0
-BITMAP
-0400
-0E00
-1F00
-3180
-0000
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-ENDCHAR
-STARTCHAR scircumflex
-ENCODING 349
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-0800
-1C00
-3E00
-6300
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR Scedilla
-ENCODING 350
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 18 0 -4
-BITMAP
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-0800
-0E00
-0600
-1C00
-ENDCHAR
-STARTCHAR scedilla
-ENCODING 351
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 13 0 -4
-BITMAP
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-1000
-1C00
-0C00
-3800
-ENDCHAR
-STARTCHAR Scaron
-ENCODING 352
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 10 14 0 0
-BITMAP
-6180
-3300
-1E00
-0C00
-0000
-3F80
-7180
-7880
-7E00
-3F00
-0F80
-83C0
-C780
-BF00
-ENDCHAR
-STARTCHAR scaron
-ENCODING 353
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 14 0 0
-BITMAP
-C300
-6600
-3C00
-1800
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR Tcommaaccent
-ENCODING 354
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 18 1 -4
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-0800
-0E00
-0600
-1C00
-ENDCHAR
-STARTCHAR tcommaaccent
-ENCODING 355
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 17 0 -4
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-20
-38
-18
-70
-ENDCHAR
-STARTCHAR Tcaron
-ENCODING 356
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-ENDCHAR
-STARTCHAR tcaron
-ENCODING 357
-SWIDTH 646 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-0060
-10F0
-30F0
-3070
-7020
-FC40
-7080
-7000
-7000
-7000
-7000
-7200
-7200
-3C00
-ENDCHAR
-STARTCHAR Tbar
-ENCODING 358
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-1F00
-1F00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-ENDCHAR
-STARTCHAR tbar
-ENCODING 359
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 13 0 0
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-7C
-7C
-72
-72
-3C
-ENDCHAR
-STARTCHAR Utilde
-ENCODING 360
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 0
-BITMAP
-0620
-0FC0
-1180
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR utilde
-ENCODING 361
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 0
-BITMAP
-0C40
-1F80
-2300
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR Umacron
-ENCODING 362
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 0
-BITMAP
-0FC0
-0FC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR umacron
-ENCODING 363
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 0
-BITMAP
-1F80
-1F80
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR Ubreve
-ENCODING 364
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 0
-BITMAP
-0840
-0CC0
-0780
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR ubreve
-ENCODING 365
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 0
-BITMAP
-1080
-1980
-0F00
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR Uring
-ENCODING 366
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-0300
-0480
-0480
-0300
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uring
-ENCODING 367
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-0600
-0900
-0900
-0600
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR Uhungarumlaut
-ENCODING 368
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-0CC0
-0CC0
-1980
-1100
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uhungarumlaut
-ENCODING 369
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-0CC0
-0CC0
-1980
-1100
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR Uogonek
-ENCODING 370
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 -4
-BITMAP
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-0600
-0C00
-0D00
-0600
-ENDCHAR
-STARTCHAR uogonek
-ENCODING 371
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 -4
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-0300
-0600
-0680
-0300
-ENDCHAR
-STARTCHAR Wcircumflex
-ENCODING 372
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 19 0 0
-BITMAP
-008000
-01C000
-03E000
-063000
-000000
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR wcircumflex
-ENCODING 373
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 14 -1 0
-BITMAP
-0100
-0380
-07C0
-0C60
-0000
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR Ycircumflex
-ENCODING 374
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 19 1 0
-BITMAP
-0200
-0700
-0F80
-18C0
-0000
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR ycircumflex
-ENCODING 375
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 -4
-BITMAP
-0800
-1C00
-3E00
-6300
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR Ydieresis
-ENCODING 376
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 14 0 0
-BITMAP
-0CC0
-0CC0
-0000
-0000
-0000
-FCF8
-7870
-3CE0
-1FC0
-0F80
-0780
-0780
-0780
-0FC0
-ENDCHAR
-STARTCHAR Zacute
-ENCODING 377
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-0F00
-1E00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-ENDCHAR
-STARTCHAR zacute
-ENCODING 378
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 14 0 0
-BITMAP
-06
-0E
-1C
-30
-00
-FF
-CF
-8E
-1C
-38
-39
-71
-F3
-FF
-ENDCHAR
-STARTCHAR Zdotaccent
-ENCODING 379
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 17 1 0
-BITMAP
-0600
-0600
-0000
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-0F00
-1E00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-ENDCHAR
-STARTCHAR zdotaccent
-ENCODING 380
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 12 0 0
-BITMAP
-18
-18
-00
-FF
-CF
-8E
-1C
-38
-39
-71
-F3
-FF
-ENDCHAR
-STARTCHAR Zcaron
-ENCODING 381
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-30C0
-1980
-0F00
-0600
-0000
-FFF0
-C1E0
-83C0
-0780
-0F10
-1E10
-3C30
-7870
-FFF0
-ENDCHAR
-STARTCHAR zcaron
-ENCODING 382
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 14 0 0
-BITMAP
-C3
-66
-3C
-18
-00
-FF
-C7
-8F
-1E
-3C
-79
-F1
-E3
-FF
-ENDCHAR
-STARTCHAR uni0186
-ENCODING 390
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 14 1 0
-BITMAP
-1F00
-63C0
-41E0
-80E0
-80F0
-0070
-0070
-0070
-8070
-80F0
-C0E0
-C1E0
-E3C0
-9F00
-ENDCHAR
-STARTCHAR uni0189
-ENCODING 393
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 0 0
-BITMAP
-7FE0
-3878
-383C
-381C
-381E
-380E
-FE0E
-380E
-380E
-381E
-381C
-383C
-3878
-7FE0
-ENDCHAR
-STARTCHAR uni018E
-ENCODING 398
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-E1C0
-C1C0
-81C0
-91C0
-11C0
-19C0
-1FC0
-19C0
-91C0
-91C0
-C1C0
-E1C0
-FFE0
-ENDCHAR
-STARTCHAR florin
-ENCODING 402
-SWIDTH 574 0
-DWIDTH 12 0
-BBX 11 18 0 -4
-BITMAP
-01C0
-0360
-0760
-0700
-0700
-1FC0
-0E00
-0E00
-0E00
-0E00
-0E00
-1C00
-1C00
-1C00
-1C00
-DC00
-D800
-7000
-ENDCHAR
-STARTCHAR uni0197
-ENCODING 407
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 5 14 2 0
-BITMAP
-F8
-70
-70
-70
-70
-70
-F8
-F8
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni019A
-ENCODING 410
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 5 14 0 0
-BITMAP
-F0
-70
-70
-70
-70
-70
-F8
-F8
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni019D
-ENCODING 413
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 17 18 -1 -4
-BITMAP
-3E0F80
-1F0700
-0F0200
-0F8200
-0BC200
-09E200
-08E200
-087200
-087A00
-083A00
-0E1E00
-0E1E00
-0E0E00
-0E0600
-0E0000
-EE0000
-EC0000
-780000
-ENDCHAR
-STARTCHAR uni019F
-ENCODING 415
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 0 0
-BITMAP
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-FFFE
-FFFE
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR Ohorn
-ENCODING 416
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 18 14 0 0
-BITMAP
-0FE180
-3C7BC0
-783FC0
-701DC0
-F01E80
-E00F00
-E00E00
-E00E00
-E00E00
-F01E00
-701C00
-783C00
-3C7800
-0FE000
-ENDCHAR
-STARTCHAR ohorn
-ENCODING 417
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 14 9 0 0
-BITMAP
-1F18
-71FC
-E0FC
-E0FC
-E0E8
-E0F0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni01A7
-ENCODING 423
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-5F80
-70C0
-6060
-4060
-00E0
-0FE0
-7FC0
-FFC0
-FE00
-E020
-C020
-C060
-60E0
-3FA0
-ENDCHAR
-STARTCHAR uni01A8
-ENCODING 424
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 9 0 0
-BITMAP
-5E00
-6300
-4380
-1F80
-7F00
-F800
-E080
-6180
-3E80
-ENDCHAR
-STARTCHAR uni01AE
-ENCODING 430
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 18 1 -4
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0EE0
-06E0
-03C0
-ENDCHAR
-STARTCHAR Uhorn
-ENCODING 431
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 17 14 1 0
-BITMAP
-F87F00
-703F80
-701780
-701380
-701100
-701200
-701400
-701000
-701000
-701000
-701000
-701000
-382000
-1FC000
-ENDCHAR
-STARTCHAR uhorn
-ENCODING 432
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 15 9 0 0
-BITMAP
-F1EC
-70FE
-70FE
-70EE
-70E4
-70E8
-70F0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni01B5
-ENCODING 437
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-1F00
-1F00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-ENDCHAR
-STARTCHAR uni01B6
-ENCODING 438
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 9 0 0
-BITMAP
-FF
-CF
-8E
-3E
-3E
-39
-71
-F3
-FF
-ENDCHAR
-STARTCHAR uni01BB
-ENCODING 443
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-1E00
-6700
-E380
-E380
-6380
-0380
-FF80
-FF80
-0E00
-1800
-3000
-6080
-FF80
-FF80
-ENDCHAR
-STARTCHAR uni01BC
-ENCODING 444
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 9 14 1 0
-BITMAP
-7F80
-7F00
-4000
-4000
-4000
-7E00
-4700
-0380
-0380
-6380
-E380
-E380
-6700
-3E00
-ENDCHAR
-STARTCHAR uni01C0
-ENCODING 448
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 2 14 4 0
-BITMAP
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR uni01C2
-ENCODING 450
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 14 1 -2
-BITMAP
-0C00
-0C00
-0C00
-0C00
-FF80
-FF80
-0C00
-0C00
-FF80
-FF80
-0C00
-0C00
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni01C3
-ENCODING 451
-SWIDTH 296 0
-DWIDTH 6 0
-BBX 4 14 1 0
-BITMAP
-60
-F0
-F0
-F0
-F0
-F0
-60
-60
-60
-00
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR uni01CD
-ENCODING 461
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 19 0 0
-BITMAP
-0C60
-07C0
-0380
-0100
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni01CE
-ENCODING 462
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-6300
-3E00
-1C00
-0800
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni01CF
-ENCODING 463
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 7 19 1 0
-BITMAP
-C6
-7C
-38
-10
-00
-7C
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR uni01D0
-ENCODING 464
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 7 14 -1 0
-BITMAP
-C6
-7C
-38
-10
-00
-78
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR uni01D1
-ENCODING 465
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 0 0
-BITMAP
-0C60
-07C0
-0380
-0100
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni01D2
-ENCODING 466
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni01D3
-ENCODING 467
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni01D4
-ENCODING 468
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni01D5
-ENCODING 469
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 20 1 0
-BITMAP
-0FC0
-0FC0
-0000
-0CC0
-0CC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni01D6
-ENCODING 470
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 15 0 0
-BITMAP
-1F80
-1F80
-0000
-1980
-1980
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni01D7
-ENCODING 471
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 22 1 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0CC0
-0CC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni01D8
-ENCODING 472
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-1980
-1980
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni01D9
-ENCODING 473
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 22 1 0
-BITMAP
-0C60
-07C0
-0380
-0100
-0000
-0CC0
-0CC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni01DA
-ENCODING 474
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 0
-BITMAP
-3180
-1F00
-0E00
-0400
-0000
-1980
-1980
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni01DB
-ENCODING 475
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 22 1 0
-BITMAP
-0C00
-0E00
-0700
-0180
-0000
-0CC0
-0CC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni01DC
-ENCODING 476
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-1980
-1980
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni01DD
-ENCODING 477
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 9 0 0
-BITMAP
-3E00
-C380
-81C0
-01C0
-FFC0
-E1C0
-E1C0
-7380
-1E00
-ENDCHAR
-STARTCHAR uni01DE
-ENCODING 478
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 20 0 0
-BITMAP
-0FC0
-0FC0
-0000
-0CC0
-0CC0
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni01DF
-ENCODING 479
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 15 0 0
-BITMAP
-3F00
-3F00
-0000
-3300
-3300
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni01E0
-ENCODING 480
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 20 0 0
-BITMAP
-0FC0
-0FC0
-0000
-0300
-0300
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni01E1
-ENCODING 481
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 15 0 0
-BITMAP
-3F00
-3F00
-0000
-0C00
-0C00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni01E2
-ENCODING 482
-SWIDTH 981 0
-DWIDTH 21 0
-BBX 20 17 0 0
-BITMAP
-007E00
-007E00
-000000
-03FFF0
-00B870
-01B830
-013890
-033890
-063980
-043F80
-0C3980
-1FF880
-103890
-203810
-203830
-603870
-F1FFF0
-ENDCHAR
-STARTCHAR uni01E3
-ENCODING 483
-SWIDTH 870 0
-DWIDTH 17 0
-BBX 16 12 0 0
-BITMAP
-07E0
-07E0
-0000
-3F78
-63CE
-E387
-0787
-3BFF
-E380
-E381
-E7C3
-78FC
-ENDCHAR
-STARTCHAR uni01E4
-ENCODING 484
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 14 14 1 0
-BITMAP
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-787C
-3CFC
-0F90
-ENDCHAR
-STARTCHAR uni01E5
-ENCODING 485
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 15 0 -4
-BITMAP
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-FFE0
-FFE0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR Gcaron
-ENCODING 486
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR gcaron
-ENCODING 487
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 20 0 -4
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR uni01E8
-ENCODING 488
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 19 1 0
-BITMAP
-18C0
-0F80
-0700
-0200
-0000
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-ENDCHAR
-STARTCHAR uni01E9
-ENCODING 489
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 19 0 0
-BITMAP
-C600
-7C00
-3800
-1000
-0000
-F000
-7000
-7000
-7000
-7000
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-ENDCHAR
-STARTCHAR uni01EA
-ENCODING 490
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 0 -4
-BITMAP
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-0180
-0300
-0340
-0180
-ENDCHAR
-STARTCHAR uni01EB
-ENCODING 491
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 -4
-BITMAP
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-0600
-0C00
-0D00
-0600
-ENDCHAR
-STARTCHAR uni01EC
-ENCODING 492
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 21 0 -4
-BITMAP
-07E0
-07E0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-0180
-0300
-0340
-0180
-ENDCHAR
-STARTCHAR uni01ED
-ENCODING 493
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 -4
-BITMAP
-1F80
-1F80
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-0600
-0C00
-0D00
-0600
-ENDCHAR
-STARTCHAR uni01F0
-ENCODING 496
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 8 18 -3 -4
-BITMAP
-63
-3E
-1C
-08
-00
-1E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-EE
-EC
-78
-ENDCHAR
-STARTCHAR uni01F4
-ENCODING 500
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR uni01F5
-ENCODING 501
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 20 0 -4
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR uni01F8
-ENCODING 504
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 1 0
-BITMAP
-0C00
-0E00
-0700
-0180
-0000
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR uni01F9
-ENCODING 505
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR Aringacute
-ENCODING 506
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 23 0 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0300
-0480
-0480
-0300
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR aringacute
-ENCODING 507
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 19 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-0C00
-1200
-1200
-0C00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR AEacute
-ENCODING 508
-SWIDTH 981 0
-DWIDTH 21 0
-BBX 20 19 0 0
-BITMAP
-000600
-000E00
-001C00
-003000
-000000
-03FFF0
-00B870
-01B830
-013890
-033890
-063980
-043F80
-0C3980
-1FF880
-103890
-203810
-203830
-603870
-F1FFF0
-ENDCHAR
-STARTCHAR aeacute
-ENCODING 509
-SWIDTH 870 0
-DWIDTH 17 0
-BBX 16 14 0 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-3F78
-63CE
-E387
-0787
-3BFF
-E380
-E381
-E7C3
-78FC
-ENDCHAR
-STARTCHAR Oslashacute
-ENCODING 510
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0FC8
-38F0
-7078
-7078
-E0BC
-E11C
-E21C
-E21C
-E41C
-E83C
-7038
-7078
-78F0
-8FC0
-ENDCHAR
-STARTCHAR oslashacute
-ENCODING 511
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 16 0 -1
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-0100
-1F00
-7380
-E3C0
-E5C0
-E5C0
-E9C0
-E9C0
-7380
-3E00
-2000
-ENDCHAR
-STARTCHAR uni0200
-ENCODING 512
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 19 0 0
-BITMAP
-1980
-1980
-0CC0
-0440
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni0201
-ENCODING 513
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-6600
-6600
-3300
-1100
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni0202
-ENCODING 514
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0780
-0CC0
-0840
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni0203
-ENCODING 515
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-1E00
-3300
-2100
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni0204
-ENCODING 516
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-3300
-3300
-1980
-0880
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni0205
-ENCODING 517
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 14 0 0
-BITMAP
-6600
-6600
-3300
-1100
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni0206
-ENCODING 518
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 0
-BITMAP
-0F00
-1980
-1080
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni0207
-ENCODING 519
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-1E00
-3300
-2100
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni0208
-ENCODING 520
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 7 19 1 0
-BITMAP
-CC
-CC
-66
-22
-00
-7C
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR uni0209
-ENCODING 521
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 7 14 -2 0
-BITMAP
-CC
-CC
-66
-22
-00
-3C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-3E
-ENDCHAR
-STARTCHAR uni020A
-ENCODING 522
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 6 18 2 0
-BITMAP
-78
-CC
-84
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni020B
-ENCODING 523
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 6 13 -1 0
-BITMAP
-78
-CC
-84
-00
-78
-38
-38
-38
-38
-38
-38
-38
-7C
-ENDCHAR
-STARTCHAR uni020C
-ENCODING 524
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 0 0
-BITMAP
-0CC0
-0CC0
-0660
-0220
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni020D
-ENCODING 525
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-3300
-3300
-1980
-0880
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni020E
-ENCODING 526
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 18 0 0
-BITMAP
-03C0
-0660
-0420
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni020F
-ENCODING 527
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 0
-BITMAP
-0F00
-1980
-1080
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni0210
-ENCODING 528
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-1980
-1980
-0CC0
-0440
-0000
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-ENDCHAR
-STARTCHAR uni0211
-ENCODING 529
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 14 0 0
-BITMAP
-CC
-CC
-66
-22
-00
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni0212
-ENCODING 530
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 18 1 0
-BITMAP
-0F00
-1980
-1080
-0000
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-ENDCHAR
-STARTCHAR uni0213
-ENCODING 531
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 13 0 0
-BITMAP
-3C
-66
-42
-00
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni0214
-ENCODING 532
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-1980
-1980
-0CC0
-0440
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni0215
-ENCODING 533
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 0
-BITMAP
-3300
-3300
-1980
-0880
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni0216
-ENCODING 534
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 0
-BITMAP
-0780
-0CC0
-0840
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni0217
-ENCODING 535
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 0
-BITMAP
-0F00
-1980
-1080
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR Scommaaccent
-ENCODING 536
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 22 0 -8
-BITMAP
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-0000
-0C00
-1E00
-1E00
-0E00
-0400
-0800
-1000
-ENDCHAR
-STARTCHAR scommaaccent
-ENCODING 537
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 17 0 -8
-BITMAP
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-0000
-1800
-3C00
-3C00
-1C00
-0800
-1000
-2000
-ENDCHAR
-STARTCHAR Tcommaaccent
-ENCODING 538
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 22 1 -8
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-0000
-0600
-0F00
-0F00
-0700
-0200
-0400
-0800
-ENDCHAR
-STARTCHAR tcommaaccent
-ENCODING 539
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 21 0 -8
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-00
-30
-78
-78
-38
-10
-20
-40
-ENDCHAR
-STARTCHAR uni021E
-ENCODING 542
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 19 1 0
-BITMAP
-0C60
-07C0
-0380
-0100
-0000
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-ENDCHAR
-STARTCHAR uni021F
-ENCODING 543
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 19 0 0
-BITMAP
-C600
-7C00
-3800
-1000
-0000
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR uni0226
-ENCODING 550
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 17 0 0
-BITMAP
-0300
-0300
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni0227
-ENCODING 551
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 12 0 0
-BITMAP
-0C00
-0C00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni0228
-ENCODING 552
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 -4
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0800
-0E00
-0600
-1C00
-ENDCHAR
-STARTCHAR uni0229
-ENCODING 553
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 -4
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0800
-0E00
-0600
-1C00
-ENDCHAR
-STARTCHAR uni022A
-ENCODING 554
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 20 0 0
-BITMAP
-07E0
-07E0
-0000
-0660
-0660
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni022B
-ENCODING 555
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 15 0 0
-BITMAP
-1F80
-1F80
-0000
-1980
-1980
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni022C
-ENCODING 556
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 21 0 0
-BITMAP
-07E0
-07E0
-0000
-0310
-07E0
-08C0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni022D
-ENCODING 557
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 0
-BITMAP
-3F00
-3F00
-0000
-1880
-3F00
-4600
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni022E
-ENCODING 558
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 0 0
-BITMAP
-0180
-0180
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni022F
-ENCODING 559
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 12 0 0
-BITMAP
-0600
-0600
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni0230
-ENCODING 560
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 20 0 0
-BITMAP
-07E0
-07E0
-0000
-0180
-0180
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni0231
-ENCODING 561
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 15 0 0
-BITMAP
-1F80
-1F80
-0000
-0600
-0600
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni0232
-ENCODING 562
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 17 1 0
-BITMAP
-1F80
-1F80
-0000
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR uni0233
-ENCODING 563
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 -4
-BITMAP
-3F00
-3F00
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR uni0250
-ENCODING 592
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 9 0 0
-BITMAP
-F780
-79C0
-71C0
-71C0
-7700
-7800
-70C0
-71C0
-3F80
-ENDCHAR
-STARTCHAR uni0254
-ENCODING 596
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 9 0 0
-BITMAP
-7C00
-E700
-C380
-0380
-0380
-0380
-8380
-C700
-3C00
-ENDCHAR
-STARTCHAR uni0258
-ENCODING 600
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 9 0 0
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-01C0
-81C0
-C380
-3E00
-ENDCHAR
-STARTCHAR uni0259
-ENCODING 601
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 9 0 0
-BITMAP
-3E00
-C380
-81C0
-01C0
-FFC0
-E1C0
-E1C0
-7380
-1E00
-ENDCHAR
-STARTCHAR uni025F
-ENCODING 607
-SWIDTH 389 0
-DWIDTH 7 0
-BBX 8 14 0 -5
-BITMAP
-1F
-0E
-0E
-0E
-0E
-0E
-0E
-0E
-3F
-0E
-0E
-EE
-EC
-78
-ENDCHAR
-STARTCHAR uni0265
-ENCODING 613
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 -5
-BITMAP
-F9F0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EE0
-00E0
-00E0
-00E0
-00E0
-00F0
-ENDCHAR
-STARTCHAR uni0275
-ENCODING 629
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 9 0 0
-BITMAP
-1F00
-71C0
-E0E0
-FFE0
-FFE0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni0279
-ENCODING 633
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 9 0 0
-BITMAP
-1F
-0E
-0E
-0E
-0E
-0E
-CE
-DE
-EF
-ENDCHAR
-STARTCHAR uni0287
-ENCODING 647
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 13 0 0
-BITMAP
-78
-9C
-9C
-1C
-1C
-1C
-1C
-1C
-7E
-1C
-18
-18
-10
-ENDCHAR
-STARTCHAR uni0288
-ENCODING 648
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 8 17 0 -4
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-70
-70
-70
-70
-77
-37
-1E
-ENDCHAR
-STARTCHAR uni0289
-ENCODING 649
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 9 0 0
-BITMAP
-F1E0
-70E0
-70E0
-FFF0
-FFF0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni028C
-ENCODING 652
-SWIDTH 611 0
-DWIDTH 9 0
-BBX 10 9 -1 0
-BITMAP
-0C00
-0C00
-1E00
-1E00
-2700
-2700
-4380
-4380
-E7C0
-ENDCHAR
-STARTCHAR uni028D
-ENCODING 653
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 9 -1 0
-BITMAP
-0C30
-0C30
-1E78
-1E78
-279C
-279C
-438E
-438E
-E7DF
-ENDCHAR
-STARTCHAR uni028E
-ENCODING 654
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 13 0 0
-BITMAP
-01C0
-02E0
-0460
-0400
-0E00
-0E00
-1700
-1700
-2380
-2380
-41C0
-41C0
-E3E0
-ENDCHAR
-STARTCHAR uni029E
-ENCODING 670
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 14 0 -5
-BITMAP
-FDF0
-78E0
-3CE0
-1EE0
-0FE0
-06E0
-04E0
-18E0
-7CE0
-00E0
-00E0
-00E0
-00E0
-00F0
-ENDCHAR
-STARTCHAR uni02BB
-ENCODING 699
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 4 7 0 7
-BITMAP
-10
-20
-40
-E0
-F0
-F0
-60
-ENDCHAR
-STARTCHAR afii57929
-ENCODING 700
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 4 7 0 7
-BITMAP
-60
-F0
-F0
-70
-20
-40
-80
-ENDCHAR
-STARTCHAR afii64937
-ENCODING 701
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 4 7 0 7
-BITMAP
-60
-F0
-F0
-E0
-40
-20
-10
-ENDCHAR
-STARTCHAR circumflex
-ENCODING 710
-SWIDTH 333 0
-DWIDTH 8 0
-BBX 7 4 0 10
-BITMAP
-10
-38
-7C
-C6
-ENDCHAR
-STARTCHAR caron
-ENCODING 711
-SWIDTH 333 0
-DWIDTH 10 0
-BBX 7 4 1 10
-BITMAP
-C6
-7C
-38
-10
-ENDCHAR
-STARTCHAR uni02C8
-ENCODING 712
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 2 5 1 9
-BITMAP
-C0
-C0
-C0
-C0
-C0
-ENDCHAR
-STARTCHAR macron
-ENCODING 713
-SWIDTH 333 0
-DWIDTH 8 0
-BBX 6 2 1 10
-BITMAP
-FC
-FC
-ENDCHAR
-STARTCHAR uni02CA
-ENCODING 714
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 10
-BITMAP
-18
-38
-70
-C0
-ENDCHAR
-STARTCHAR uni02CB
-ENCODING 715
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 10
-BITMAP
-C0
-E0
-70
-18
-ENDCHAR
-STARTCHAR uni02CD
-ENCODING 717
-SWIDTH 333 0
-DWIDTH 8 0
-BBX 6 2 1 -3
-BITMAP
-FC
-FC
-ENDCHAR
-STARTCHAR uni02CE
-ENCODING 718
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 -5
-BITMAP
-C0
-E0
-70
-18
-ENDCHAR
-STARTCHAR uni02CF
-ENCODING 719
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 -5
-BITMAP
-18
-38
-70
-C0
-ENDCHAR
-STARTCHAR breve
-ENCODING 728
-SWIDTH 333 0
-DWIDTH 8 0
-BBX 6 3 1 10
-BITMAP
-84
-CC
-78
-ENDCHAR
-STARTCHAR dotaccent
-ENCODING 729
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 2 2 2 10
-BITMAP
-C0
-C0
-ENDCHAR
-STARTCHAR ring
-ENCODING 730
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 4 4 1 10
-BITMAP
-60
-90
-90
-60
-ENDCHAR
-STARTCHAR ogonek
-ENCODING 731
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 4 4 1 -4
-BITMAP
-60
-C0
-D0
-60
-ENDCHAR
-STARTCHAR tilde
-ENCODING 732
-SWIDTH 333 0
-DWIDTH 10 0
-BBX 8 3 1 10
-BITMAP
-31
-7E
-8C
-ENDCHAR
-STARTCHAR hungarumlaut
-ENCODING 733
-SWIDTH 333 0
-DWIDTH 9 0
-BBX 7 4 1 10
-BITMAP
-66
-66
-CC
-88
-ENDCHAR
-STARTCHAR uni02EE
-ENCODING 750
-SWIDTH 481 0
-DWIDTH 10 0
-BBX 9 7 0 7
-BITMAP
-6300
-F780
-F780
-7380
-2100
-4200
-8400
-ENDCHAR
-STARTCHAR uni037E
-ENCODING 894
-SWIDTH 278 0
-DWIDTH 6 0
-BBX 4 12 1 -3
-BITMAP
-60
-F0
-F0
-60
-00
-60
-F0
-F0
-70
-20
-40
-80
-ENDCHAR
-STARTCHAR tonos
-ENCODING 900
-SWIDTH 333 0
-DWIDTH 7 0
-BBX 5 4 1 10
-BITMAP
-18
-38
-70
-C0
-ENDCHAR
-STARTCHAR dieresistonos
-ENCODING 901
-SWIDTH 333 0
-DWIDTH 10 0
-BBX 6 7 2 10
-BITMAP
-0C
-1C
-38
-60
-00
-CC
-CC
-ENDCHAR
-STARTCHAR anoteleia
-ENCODING 903
-SWIDTH 278 0
-DWIDTH 5 0
-BBX 4 4 0 3
-BITMAP
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR mu
-ENCODING 956
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 -4
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-7EF0
-6000
-7000
-7000
-2000
-ENDCHAR
-STARTCHAR uni1E00
-ENCODING 7680
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 19 0 -5
-BITMAP
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-0000
-0180
-0240
-0240
-0180
-ENDCHAR
-STARTCHAR uni1E01
-ENCODING 7681
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 14 0 -5
-BITMAP
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-0000
-0C00
-1200
-1200
-0C00
-ENDCHAR
-STARTCHAR uni1E02
-ENCODING 7682
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 17 1 0
-BITMAP
-0600
-0600
-0000
-FFC0
-71E0
-70E0
-70E0
-70E0
-71C0
-7F80
-70E0
-70F0
-7070
-7070
-7070
-70E0
-FF80
-ENDCHAR
-STARTCHAR uni1E03
-ENCODING 7683
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 12 17 -1 0
-BITMAP
-1800
-1800
-0000
-F000
-7000
-7000
-7000
-7000
-7780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-6F80
-ENDCHAR
-STARTCHAR uni1E04
-ENCODING 7684
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 17 1 -3
-BITMAP
-FFC0
-71E0
-70E0
-70E0
-70E0
-71C0
-7F80
-70E0
-70F0
-7070
-7070
-7070
-70E0
-FF80
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E05
-ENCODING 7685
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 12 17 -1 -3
-BITMAP
-F000
-7000
-7000
-7000
-7000
-7780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-6F80
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E06
-ENCODING 7686
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 17 1 -3
-BITMAP
-FFC0
-71E0
-70E0
-70E0
-70E0
-71C0
-7F80
-70E0
-70F0
-7070
-7070
-7070
-70E0
-FF80
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E07
-ENCODING 7687
-SWIDTH 648 0
-DWIDTH 12 0
-BBX 12 17 -1 -3
-BITMAP
-F000
-7000
-7000
-7000
-7000
-7780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-6F80
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E08
-ENCODING 7688
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 12 23 1 -4
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E000
-F010
-7010
-7820
-3C60
-0F80
-0400
-0700
-0300
-0E00
-ENDCHAR
-STARTCHAR uni1E09
-ENCODING 7689
-SWIDTH 556 0
-DWIDTH 10 0
-BBX 9 18 0 -4
-BITMAP
-0600
-0E00
-1C00
-3000
-0000
-1F00
-7380
-E180
-E000
-E000
-E000
-E080
-7180
-1E00
-1000
-1C00
-0C00
-3800
-ENDCHAR
-STARTCHAR uni1E0A
-ENCODING 7690
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 0
-BITMAP
-0300
-0300
-0000
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-ENDCHAR
-STARTCHAR uni1E0B
-ENCODING 7691
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 17 0 0
-BITMAP
-0180
-0180
-0000
-01E0
-00E0
-00E0
-00E0
-00E0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-ENDCHAR
-STARTCHAR uni1E0C
-ENCODING 7692
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E0D
-ENCODING 7693
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 17 0 -3
-BITMAP
-01E0
-00E0
-00E0
-00E0
-00E0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E0E
-ENCODING 7694
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-0000
-0FC0
-0FC0
-ENDCHAR
-STARTCHAR uni1E0F
-ENCODING 7695
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 17 0 -3
-BITMAP
-01E0
-00E0
-00E0
-00E0
-00E0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E10
-ENCODING 7696
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 -4
-BITMAP
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-0400
-0700
-0300
-0E00
-ENDCHAR
-STARTCHAR uni1E11
-ENCODING 7697
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 18 0 -4
-BITMAP
-01E0
-00E0
-00E0
-00E0
-00E0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-0400
-0700
-0300
-0E00
-ENDCHAR
-STARTCHAR uni1E12
-ENCODING 7698
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 -5
-BITMAP
-FFC0
-70F0
-7078
-7038
-703C
-701C
-701C
-701C
-701C
-703C
-7038
-7078
-70F0
-FFC0
-0000
-0200
-0700
-0F80
-18C0
-ENDCHAR
-STARTCHAR uni1E13
-ENCODING 7699
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 19 0 -5
-BITMAP
-01E0
-00E0
-00E0
-00E0
-00E0
-1EE0
-71E0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71E0
-1EF0
-0000
-0200
-0700
-0F80
-18C0
-ENDCHAR
-STARTCHAR uni1E14
-ENCODING 7700
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 22 1 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-1F80
-1F80
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni1E15
-ENCODING 7701
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 17 0 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-3F00
-3F00
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni1E16
-ENCODING 7702
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 22 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-1F80
-1F80
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni1E17
-ENCODING 7703
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 17 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-3F00
-3F00
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni1E18
-ENCODING 7704
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 19 1 -5
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0000
-0400
-0E00
-1F00
-3180
-ENDCHAR
-STARTCHAR uni1E19
-ENCODING 7705
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 14 0 -5
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0000
-0800
-1C00
-3E00
-6300
-ENDCHAR
-STARTCHAR uni1E1A
-ENCODING 7706
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 -4
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0000
-1880
-3F00
-4600
-ENDCHAR
-STARTCHAR uni1E1B
-ENCODING 7707
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 -4
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0000
-1880
-3F00
-4600
-ENDCHAR
-STARTCHAR uni1E1C
-ENCODING 7708
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 22 1 -4
-BITMAP
-2100
-3300
-1E00
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0800
-0E00
-0600
-1C00
-ENDCHAR
-STARTCHAR uni1E1D
-ENCODING 7709
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 17 0 -4
-BITMAP
-2100
-3300
-1E00
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0800
-0E00
-0600
-1C00
-ENDCHAR
-STARTCHAR uni1E1E
-ENCODING 7710
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 17 1 0
-BITMAP
-0600
-0600
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7320
-7F00
-7300
-7100
-7100
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR uni1E1F
-ENCODING 7711
-SWIDTH 389 0
-DWIDTH 7 0
-BBX 8 17 0 0
-BITMAP
-18
-18
-00
-1E
-37
-77
-70
-70
-FC
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni1E20
-ENCODING 7712
-SWIDTH 833 0
-DWIDTH 15 0
-BBX 13 17 1 0
-BITMAP
-1F80
-1F80
-0000
-0F90
-3C70
-7830
-7030
-F010
-E010
-E000
-E000
-E0F8
-F070
-7070
-7870
-3CF0
-0F90
-ENDCHAR
-STARTCHAR uni1E21
-ENCODING 7713
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 11 18 0 -4
-BITMAP
-1F80
-1F80
-0000
-0060
-00E0
-3F00
-7380
-6180
-6180
-7380
-3F00
-6000
-7F80
-3FC0
-C1C0
-C0C0
-E180
-7F00
-ENDCHAR
-STARTCHAR uni1E22
-ENCODING 7714
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 17 1 0
-BITMAP
-0300
-0300
-0000
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-ENDCHAR
-STARTCHAR uni1E23
-ENCODING 7715
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 0
-BITMAP
-1800
-1800
-0000
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR uni1E24
-ENCODING 7716
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E25
-ENCODING 7717
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 -3
-BITMAP
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E26
-ENCODING 7718
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 17 1 0
-BITMAP
-0CC0
-0CC0
-0000
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-ENDCHAR
-STARTCHAR uni1E27
-ENCODING 7719
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 0
-BITMAP
-6600
-6600
-0000
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR uni1E28
-ENCODING 7720
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 18 1 -4
-BITMAP
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-0200
-0380
-0180
-0700
-ENDCHAR
-STARTCHAR uni1E29
-ENCODING 7721
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 18 0 -4
-BITMAP
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0400
-0700
-0300
-0E00
-ENDCHAR
-STARTCHAR uni1E2A
-ENCODING 7722
-SWIDTH 870 0
-DWIDTH 16 0
-BBX 14 18 1 -4
-BITMAP
-FCFC
-7038
-7038
-7038
-7038
-7038
-7FF8
-7038
-7038
-7038
-7038
-7038
-7038
-FCFC
-0000
-0840
-0CC0
-0780
-ENDCHAR
-STARTCHAR uni1E2B
-ENCODING 7723
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 18 0 -4
-BITMAP
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-1080
-1980
-0F00
-ENDCHAR
-STARTCHAR uni1E2C
-ENCODING 7724
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 8 18 0 -4
-BITMAP
-3E
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-3E
-00
-31
-7E
-8C
-ENDCHAR
-STARTCHAR uni1E2D
-ENCODING 7725
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 8 18 -2 -4
-BITMAP
-1C
-1C
-1C
-00
-00
-3C
-1C
-1C
-1C
-1C
-1C
-1C
-1C
-3E
-00
-31
-7E
-8C
-ENDCHAR
-STARTCHAR uni1E2E
-ENCODING 7726
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 6 22 2 0
-BITMAP
-0C
-1C
-38
-60
-00
-CC
-CC
-00
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni1E2F
-ENCODING 7727
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 6 17 0 0
-BITMAP
-0C
-1C
-38
-60
-00
-CC
-CC
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni1E30
-ENCODING 7728
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-ENDCHAR
-STARTCHAR uni1E31
-ENCODING 7729
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 19 0 0
-BITMAP
-0C00
-1C00
-3800
-6000
-0000
-F000
-7000
-7000
-7000
-7000
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-ENDCHAR
-STARTCHAR uni1E32
-ENCODING 7730
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 17 1 -3
-BITMAP
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1E33
-ENCODING 7731
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 17 0 -3
-BITMAP
-F000
-7000
-7000
-7000
-7000
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E34
-ENCODING 7732
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 17 1 -3
-BITMAP
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-0000
-07E0
-07E0
-ENDCHAR
-STARTCHAR uni1E35
-ENCODING 7733
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 12 17 0 -3
-BITMAP
-F000
-7000
-7000
-7000
-7000
-73E0
-7180
-7200
-7600
-7F00
-7780
-73C0
-71E0
-FBF0
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E36
-ENCODING 7734
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 17 1 -3
-BITMAP
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E37
-ENCODING 7735
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 5 17 0 -3
-BITMAP
-F0
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E38
-ENCODING 7736
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 20 1 -3
-BITMAP
-7E00
-7E00
-0000
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E39
-ENCODING 7737
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 6 20 -1 -3
-BITMAP
-FC
-FC
-00
-78
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-7C
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E3A
-ENCODING 7738
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 17 1 -3
-BITMAP
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-0000
-3F00
-3F00
-ENDCHAR
-STARTCHAR uni1E3B
-ENCODING 7739
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 6 17 0 -3
-BITMAP
-F0
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-00
-FC
-FC
-ENDCHAR
-STARTCHAR uni1E3C
-ENCODING 7740
-SWIDTH 722 0
-DWIDTH 12 0
-BBX 11 19 1 -5
-BITMAP
-FC00
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7000
-7020
-7020
-7060
-70E0
-FFE0
-0000
-0400
-0E00
-1F00
-3180
-ENDCHAR
-STARTCHAR uni1E3D
-ENCODING 7741
-SWIDTH 352 0
-DWIDTH 6 0
-BBX 7 19 -1 -5
-BITMAP
-78
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-38
-7C
-00
-10
-38
-7C
-C6
-ENDCHAR
-STARTCHAR uni1E3E
-ENCODING 7742
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 17 19 1 0
-BITMAP
-003000
-007000
-00E000
-018000
-000000
-7C0780
-3C0F00
-3E0F00
-2E1F00
-2F1700
-2F1700
-273700
-27A700
-23E700
-23C700
-23C700
-21C700
-718700
-F88F80
-ENDCHAR
-STARTCHAR uni1E3F
-ENCODING 7743
-SWIDTH 963 0
-DWIDTH 20 0
-BBX 19 14 0 0
-BITMAP
-003000
-007000
-00E000
-018000
-000000
-F7DF80
-79F3C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-F9F3E0
-ENDCHAR
-STARTCHAR uni1E40
-ENCODING 7744
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 17 17 1 0
-BITMAP
-00C000
-00C000
-000000
-7C0780
-3C0F00
-3E0F00
-2E1F00
-2F1700
-2F1700
-273700
-27A700
-23E700
-23C700
-23C700
-21C700
-718700
-F88F80
-ENDCHAR
-STARTCHAR uni1E41
-ENCODING 7745
-SWIDTH 963 0
-DWIDTH 20 0
-BBX 19 12 0 0
-BITMAP
-00C000
-00C000
-000000
-F7DF80
-79F3C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-F9F3E0
-ENDCHAR
-STARTCHAR uni1E42
-ENCODING 7746
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 17 17 1 -3
-BITMAP
-7C0780
-3C0F00
-3E0F00
-2E1F00
-2F1700
-2F1700
-273700
-27A700
-23E700
-23C700
-23C700
-21C700
-718700
-F88F80
-000000
-00C000
-00C000
-ENDCHAR
-STARTCHAR uni1E43
-ENCODING 7747
-SWIDTH 963 0
-DWIDTH 20 0
-BBX 19 12 0 -3
-BITMAP
-F7DF80
-79F3C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-F9F3E0
-000000
-006000
-006000
-ENDCHAR
-STARTCHAR uni1E44
-ENCODING 7748
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 1 0
-BITMAP
-0300
-0300
-0000
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR uni1E45
-ENCODING 7749
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 0
-BITMAP
-0600
-0600
-0000
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-ENDCHAR
-STARTCHAR uni1E46
-ENCODING 7750
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 1 -3
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E47
-ENCODING 7751
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 -3
-BITMAP
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E48
-ENCODING 7752
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 1 -3
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-0000
-0FC0
-0FC0
-ENDCHAR
-STARTCHAR uni1E49
-ENCODING 7753
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 -3
-BITMAP
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E4A
-ENCODING 7754
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 19 1 -5
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-2F08
-2788
-2388
-21C8
-21E8
-20E8
-2078
-2078
-7038
-F818
-0000
-0100
-0380
-07C0
-0C60
-ENDCHAR
-STARTCHAR uni1E4B
-ENCODING 7755
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 -5
-BITMAP
-F7C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-0200
-0700
-0F80
-18C0
-ENDCHAR
-STARTCHAR uni1E4C
-ENCODING 7756
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 23 0 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-0310
-07E0
-08C0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1E4D
-ENCODING 7757
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-1880
-3F00
-4600
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1E4E
-ENCODING 7758
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 21 0 0
-BITMAP
-0660
-0660
-0000
-0310
-07E0
-08C0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1E4F
-ENCODING 7759
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 0
-BITMAP
-3300
-3300
-0000
-1880
-3F00
-4600
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1E50
-ENCODING 7760
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 22 0 0
-BITMAP
-0600
-0700
-0380
-00C0
-0000
-07E0
-07E0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1E51
-ENCODING 7761
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 17 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-1F80
-1F80
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1E52
-ENCODING 7762
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 22 0 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-07E0
-07E0
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1E53
-ENCODING 7763
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 17 0 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-1F80
-1F80
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1E54
-ENCODING 7764
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 12 19 1 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-FFE0
-70F0
-7070
-7070
-7070
-70F0
-71E0
-7F80
-7000
-7000
-7000
-7000
-7000
-FC00
-ENDCHAR
-STARTCHAR uni1E55
-ENCODING 7765
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 12 18 -1 -4
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-E780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-7780
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR uni1E56
-ENCODING 7766
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 12 17 1 0
-BITMAP
-0600
-0600
-0000
-FFE0
-70F0
-7070
-7070
-7070
-70F0
-71E0
-7F80
-7000
-7000
-7000
-7000
-7000
-FC00
-ENDCHAR
-STARTCHAR uni1E57
-ENCODING 7767
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 12 16 -1 -4
-BITMAP
-0600
-0600
-0000
-E780
-78E0
-7070
-7070
-7070
-7070
-7070
-78E0
-7780
-7000
-7000
-7000
-F800
-ENDCHAR
-STARTCHAR uni1E58
-ENCODING 7768
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 17 1 0
-BITMAP
-0600
-0600
-0000
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-ENDCHAR
-STARTCHAR uni1E59
-ENCODING 7769
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 12 0 0
-BITMAP
-18
-18
-00
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-ENDCHAR
-STARTCHAR uni1E5A
-ENCODING 7770
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E5B
-ENCODING 7771
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 12 0 -3
-BITMAP
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E5C
-ENCODING 7772
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 20 1 -3
-BITMAP
-0FC0
-0FC0
-0000
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E5D
-ENCODING 7773
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 15 0 -3
-BITMAP
-7E
-7E
-00
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E5E
-ENCODING 7774
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-FFE0
-70F0
-7070
-7070
-70F0
-71E0
-7F80
-71C0
-71E0
-70E0
-70E0
-70F0
-7074
-F878
-0000
-0FC0
-0FC0
-ENDCHAR
-STARTCHAR uni1E5F
-ENCODING 7775
-SWIDTH 519 0
-DWIDTH 9 0
-BBX 8 12 0 -3
-BITMAP
-F7
-7B
-73
-70
-70
-70
-70
-70
-F8
-00
-FC
-FC
-ENDCHAR
-STARTCHAR uni1E60
-ENCODING 7776
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 17 0 0
-BITMAP
-0C00
-0C00
-0000
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-ENDCHAR
-STARTCHAR uni1E61
-ENCODING 7777
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 12 0 0
-BITMAP
-1800
-1800
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR uni1E62
-ENCODING 7778
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 17 0 -3
-BITMAP
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E63
-ENCODING 7779
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 12 0 -3
-BITMAP
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR uni1E64
-ENCODING 7780
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 22 0 0
-BITMAP
-0600
-0600
-0000
-0300
-0700
-0E00
-1800
-0000
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-ENDCHAR
-STARTCHAR uni1E65
-ENCODING 7781
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 17 0 0
-BITMAP
-0C00
-0C00
-0000
-0600
-0E00
-1C00
-3000
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR uni1E66
-ENCODING 7782
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 10 17 0 0
-BITMAP
-0C00
-0C00
-0000
-6180
-3300
-1E00
-0C00
-0000
-3F80
-7180
-7880
-7E00
-3F00
-0F80
-83C0
-C780
-BF00
-ENDCHAR
-STARTCHAR uni1E67
-ENCODING 7783
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 17 0 0
-BITMAP
-1800
-1800
-0000
-C300
-6600
-3C00
-1800
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-ENDCHAR
-STARTCHAR uni1E68
-ENCODING 7784
-SWIDTH 667 0
-DWIDTH 12 0
-BBX 11 20 0 -3
-BITMAP
-0C00
-0C00
-0000
-3F40
-61C0
-C0C0
-C040
-E000
-FE00
-7FC0
-7FE0
-0FE0
-80E0
-8060
-C060
-E0C0
-BF80
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E69
-ENCODING 7785
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 15 0 -3
-BITMAP
-1800
-1800
-0000
-3D00
-6300
-E100
-FC00
-7F00
-0F80
-8380
-C300
-BE00
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR uni1E6A
-ENCODING 7786
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 17 1 0
-BITMAP
-0600
-0600
-0000
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-ENDCHAR
-STARTCHAR uni1E6B
-ENCODING 7787
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 16 0 0
-BITMAP
-30
-30
-00
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-ENDCHAR
-STARTCHAR uni1E6C
-ENCODING 7788
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 17 1 -3
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1E6D
-ENCODING 7789
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 16 0 -3
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1E6E
-ENCODING 7790
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 17 1 -3
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E6F
-ENCODING 7791
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 16 0 -3
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-00
-FC
-FC
-ENDCHAR
-STARTCHAR uni1E70
-ENCODING 7792
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 19 1 -5
-BITMAP
-FFE0
-CE60
-CE60
-8E20
-8E20
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-0E00
-1F00
-0000
-0400
-0E00
-1F00
-3180
-ENDCHAR
-STARTCHAR uni1E71
-ENCODING 7793
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 18 0 -5
-BITMAP
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-00
-10
-38
-7C
-C6
-ENDCHAR
-STARTCHAR uni1E72
-ENCODING 7794
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-0000
-1980
-1980
-ENDCHAR
-STARTCHAR uni1E73
-ENCODING 7795
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 -3
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-0000
-1980
-1980
-ENDCHAR
-STARTCHAR uni1E74
-ENCODING 7796
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 18 1 -4
-BITMAP
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-0000
-0C40
-1F80
-2300
-ENDCHAR
-STARTCHAR uni1E75
-ENCODING 7797
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 13 0 -4
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-0000
-0C40
-1F80
-2300
-ENDCHAR
-STARTCHAR uni1E76
-ENCODING 7798
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 19 1 -5
-BITMAP
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-0000
-0200
-0700
-0F80
-18C0
-ENDCHAR
-STARTCHAR uni1E77
-ENCODING 7799
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 14 0 -5
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-0000
-0200
-0700
-0F80
-18C0
-ENDCHAR
-STARTCHAR uni1E78
-ENCODING 7800
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 23 1 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0620
-0FC0
-1180
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni1E79
-ENCODING 7801
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 18 0 0
-BITMAP
-0180
-0380
-0700
-0C00
-0000
-0C40
-1F80
-2300
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni1E7A
-ENCODING 7802
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 20 1 0
-BITMAP
-0CC0
-0CC0
-0000
-0FC0
-0FC0
-0000
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-ENDCHAR
-STARTCHAR uni1E7B
-ENCODING 7803
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 15 0 0
-BITMAP
-1980
-1980
-0000
-1F80
-1F80
-0000
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni1E7C
-ENCODING 7804
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0620
-0FC0
-1180
-0000
-F87C
-7038
-7830
-3820
-3820
-3C60
-1C40
-1E40
-0EC0
-0E80
-0780
-0780
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E7D
-ENCODING 7805
-SWIDTH 611 0
-DWIDTH 9 0
-BBX 10 13 -1 0
-BITMAP
-1880
-3F00
-4600
-0000
-F9C0
-7080
-7080
-3900
-3900
-1E00
-1E00
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E7E
-ENCODING 7806
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 17 0 -3
-BITMAP
-F87C
-7038
-7830
-3820
-3820
-3C60
-1C40
-1E40
-0EC0
-0E80
-0780
-0780
-0300
-0300
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1E7F
-ENCODING 7807
-SWIDTH 611 0
-DWIDTH 9 0
-BBX 10 12 -1 -3
-BITMAP
-F9C0
-7080
-7080
-3900
-3900
-1E00
-1E00
-0C00
-0C00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR Wgrave
-ENCODING 7808
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 19 0 0
-BITMAP
-030000
-038000
-01C000
-006000
-000000
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR wgrave
-ENCODING 7809
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 14 -1 0
-BITMAP
-0600
-0700
-0380
-00C0
-0000
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR Wacute
-ENCODING 7810
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 19 0 0
-BITMAP
-003000
-007000
-00E000
-018000
-000000
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR wacute
-ENCODING 7811
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 14 -1 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR Wdieresis
-ENCODING 7812
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 17 0 0
-BITMAP
-033000
-033000
-000000
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR wdieresis
-ENCODING 7813
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 12 -1 0
-BITMAP
-0CC0
-0CC0
-0000
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR uni1E86
-ENCODING 7814
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 17 0 0
-BITMAP
-00C000
-00C000
-000000
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR uni1E87
-ENCODING 7815
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 12 -1 0
-BITMAP
-0300
-0300
-0000
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR uni1E88
-ENCODING 7816
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 17 0 -3
-BITMAP
-FBF3E0
-71E1C0
-70E180
-78E100
-38F100
-39F300
-3D7200
-1D3A00
-1F3E00
-1E3C00
-0E1C00
-0E1C00
-0C1800
-040800
-000000
-00C000
-00C000
-ENDCHAR
-STARTCHAR uni1E89
-ENCODING 7817
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 12 -1 -3
-BITMAP
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1E8A
-ENCODING 7818
-SWIDTH 722 0
-DWIDTH 17 0
-BBX 16 17 0 0
-BITMAP
-0180
-0180
-0000
-7E3F
-3C1C
-1E18
-0E30
-0F60
-07C0
-03C0
-03E0
-06F0
-0C70
-1878
-303C
-703E
-F87F
-ENDCHAR
-STARTCHAR uni1E8B
-ENCODING 7819
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 12 0 0
-BITMAP
-0C00
-0C00
-0000
-FCE0
-78C0
-3D00
-1E00
-0E00
-0F00
-1780
-63C0
-E7E0
-ENDCHAR
-STARTCHAR uni1E8C
-ENCODING 7820
-SWIDTH 722 0
-DWIDTH 17 0
-BBX 16 17 0 0
-BITMAP
-0660
-0660
-0000
-7E3F
-3C1C
-1E18
-0E30
-0F60
-07C0
-03C0
-03E0
-06F0
-0C70
-1878
-303C
-703E
-F87F
-ENDCHAR
-STARTCHAR uni1E8D
-ENCODING 7821
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 12 0 0
-BITMAP
-3300
-3300
-0000
-FCE0
-78C0
-3D00
-1E00
-0E00
-0F00
-1780
-63C0
-E7E0
-ENDCHAR
-STARTCHAR uni1E8E
-ENCODING 7822
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 17 1 0
-BITMAP
-0600
-0600
-0000
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR uni1E8F
-ENCODING 7823
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 -4
-BITMAP
-0C00
-0C00
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR uni1E90
-ENCODING 7824
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 19 1 0
-BITMAP
-0400
-0E00
-1F00
-3180
-0000
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-0F00
-1E00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-ENDCHAR
-STARTCHAR uni1E91
-ENCODING 7825
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 14 0 0
-BITMAP
-08
-1C
-3E
-63
-00
-FF
-CF
-8E
-1C
-38
-39
-71
-F3
-FF
-ENDCHAR
-STARTCHAR uni1E92
-ENCODING 7826
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 17 1 -3
-BITMAP
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-0F00
-1E00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1E93
-ENCODING 7827
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 12 0 -3
-BITMAP
-FF
-CF
-8E
-1C
-38
-39
-71
-F3
-FF
-00
-18
-18
-ENDCHAR
-STARTCHAR uni1E94
-ENCODING 7828
-SWIDTH 667 0
-DWIDTH 13 0
-BBX 11 17 1 -3
-BITMAP
-FFE0
-E1E0
-C1C0
-83C0
-8780
-0700
-0F00
-1E00
-1C00
-3C20
-7820
-7060
-F0E0
-FFE0
-0000
-3F00
-3F00
-ENDCHAR
-STARTCHAR uni1E95
-ENCODING 7829
-SWIDTH 537 0
-DWIDTH 10 0
-BBX 8 12 0 -3
-BITMAP
-FF
-CF
-8E
-1C
-38
-39
-71
-F3
-FF
-00
-7E
-7E
-ENDCHAR
-STARTCHAR uni1E96
-ENCODING 7830
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 17 0 -3
-BITMAP
-F000
-7000
-7000
-7000
-7000
-77C0
-79E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-F9F0
-0000
-1F80
-1F80
-ENDCHAR
-STARTCHAR uni1E97
-ENCODING 7831
-SWIDTH 426 0
-DWIDTH 8 0
-BBX 7 16 0 0
-BITMAP
-CC
-CC
-00
-10
-30
-30
-70
-FC
-70
-70
-70
-70
-70
-72
-72
-3C
-ENDCHAR
-STARTCHAR uni1E98
-ENCODING 7832
-SWIDTH 889 0
-DWIDTH 15 0
-BBX 16 14 -1 0
-BITMAP
-0300
-0480
-0480
-0300
-0000
-FBE7
-71C2
-71C2
-39E4
-39E4
-1E78
-1E78
-0C30
-0C30
-ENDCHAR
-STARTCHAR uni1E99
-ENCODING 7833
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 -4
-BITMAP
-0C00
-1200
-1200
-0C00
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR uni1EA0
-ENCODING 7840
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 17 0 -3
-BITMAP
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1EA1
-ENCODING 7841
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 12 0 -3
-BITMAP
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EA4
-ENCODING 7844
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 23 0 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0380
-07C0
-0C60
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni1EA5
-ENCODING 7845
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 18 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-1C00
-3E00
-6300
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni1EA6
-ENCODING 7846
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 23 0 0
-BITMAP
-0C00
-0E00
-0700
-0180
-0000
-0380
-07C0
-0C60
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni1EA7
-ENCODING 7847
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 18 0 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-1C00
-3E00
-6300
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni1EAA
-ENCODING 7850
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 22 0 0
-BITMAP
-0310
-07E0
-08C0
-0000
-0380
-07C0
-0C60
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni1EAB
-ENCODING 7851
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 17 0 0
-BITMAP
-1880
-3F00
-4600
-0000
-1C00
-3E00
-6300
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni1EAC
-ENCODING 7852
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 22 0 -3
-BITMAP
-0200
-0700
-0F80
-18C0
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1EAD
-ENCODING 7853
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 17 0 -3
-BITMAP
-0400
-0E00
-1F00
-3180
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EAE
-ENCODING 7854
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 23 0 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0840
-0CC0
-0780
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni1EAF
-ENCODING 7855
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 18 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-2100
-3300
-1E00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni1EB0
-ENCODING 7856
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 23 0 0
-BITMAP
-0C00
-0E00
-0700
-0180
-0000
-0840
-0CC0
-0780
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni1EB1
-ENCODING 7857
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 18 0 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-2100
-3300
-1E00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni1EB4
-ENCODING 7860
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 22 0 0
-BITMAP
-0620
-0FC0
-1180
-0000
-0840
-0CC0
-0780
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni1EB5
-ENCODING 7861
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 17 0 0
-BITMAP
-1880
-3F00
-4600
-0000
-2100
-3300
-1E00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-ENDCHAR
-STARTCHAR uni1EB6
-ENCODING 7862
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 21 0 -3
-BITMAP
-0840
-0CC0
-0780
-0000
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1EB7
-ENCODING 7863
-SWIDTH 611 0
-DWIDTH 11 0
-BBX 10 16 0 -3
-BITMAP
-2100
-3300
-1E00
-0000
-7F00
-E380
-C380
-0780
-3B80
-E380
-E380
-E780
-7BC0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EB8
-ENCODING 7864
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 17 1 -3
-BITMAP
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EB9
-ENCODING 7865
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 12 0 -3
-BITMAP
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EBC
-ENCODING 7868
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 18 1 0
-BITMAP
-0C40
-1F80
-2300
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni1EBD
-ENCODING 7869
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 13 0 0
-BITMAP
-1880
-3F00
-4600
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni1EBE
-ENCODING 7870
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 23 1 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-0E00
-1F00
-3180
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni1EBF
-ENCODING 7871
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 18 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-0E00
-1F00
-3180
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni1EC0
-ENCODING 7872
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 23 1 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-0E00
-1F00
-3180
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni1EC1
-ENCODING 7873
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 18 0 0
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-0E00
-1F00
-3180
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni1EC4
-ENCODING 7876
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 22 1 0
-BITMAP
-0C40
-1F80
-2300
-0000
-0E00
-1F00
-3180
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-ENDCHAR
-STARTCHAR uni1EC5
-ENCODING 7877
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 17 0 0
-BITMAP
-0C40
-1F80
-2300
-0000
-0E00
-1F00
-3180
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-ENDCHAR
-STARTCHAR uni1EC6
-ENCODING 7878
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 22 1 -3
-BITMAP
-0400
-0E00
-1F00
-3180
-0000
-FFE0
-70E0
-7060
-7120
-7120
-7300
-7F00
-7300
-7100
-7120
-7020
-7060
-70E0
-FFE0
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1EC7
-ENCODING 7879
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 10 17 0 -3
-BITMAP
-0400
-0E00
-1F00
-3180
-0000
-1E00
-7380
-E1C0
-E1C0
-FFC0
-E000
-E040
-70C0
-1F00
-0000
-0C00
-0C00
-ENDCHAR
-STARTCHAR uni1ECA
-ENCODING 7882
-SWIDTH 444 0
-DWIDTH 9 0
-BBX 5 17 2 -3
-BITMAP
-F8
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-70
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1ECB
-ENCODING 7883
-SWIDTH 370 0
-DWIDTH 6 0
-BBX 5 17 0 -3
-BITMAP
-70
-70
-70
-00
-00
-F0
-70
-70
-70
-70
-70
-70
-70
-F8
-00
-30
-30
-ENDCHAR
-STARTCHAR uni1ECC
-ENCODING 7884
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 17 0 -3
-BITMAP
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1ECD
-ENCODING 7885
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 12 0 -3
-BITMAP
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1ED0
-ENCODING 7888
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 23 0 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-0380
-07C0
-0C60
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1ED1
-ENCODING 7889
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 0
-BITMAP
-0300
-0700
-0E00
-1800
-0000
-0E00
-1F00
-3180
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1ED2
-ENCODING 7890
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 23 0 0
-BITMAP
-0600
-0700
-0380
-00C0
-0000
-0380
-07C0
-0C60
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1ED3
-ENCODING 7891
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-0E00
-1F00
-3180
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1ED6
-ENCODING 7894
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 22 0 0
-BITMAP
-0310
-07E0
-08C0
-0000
-0380
-07C0
-0C60
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-ENDCHAR
-STARTCHAR uni1ED7
-ENCODING 7895
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 17 0 0
-BITMAP
-0C40
-1F80
-2300
-0000
-0E00
-1F00
-3180
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1ED8
-ENCODING 7896
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 22 0 -3
-BITMAP
-0100
-0380
-07C0
-0C60
-0000
-0FE0
-3C78
-783C
-701C
-F01E
-E00E
-E00E
-E00E
-E00E
-F01E
-701C
-783C
-3C78
-0FE0
-0000
-0180
-0180
-ENDCHAR
-STARTCHAR uni1ED9
-ENCODING 7897
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 17 0 -3
-BITMAP
-0400
-0E00
-1F00
-3180
-0000
-1F00
-71C0
-E0E0
-E0E0
-E0E0
-E0E0
-E0E0
-71C0
-1F00
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1EDA
-ENCODING 7898
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 18 19 0 0
-BITMAP
-001800
-003800
-007000
-00C000
-000000
-0FE180
-3C7BC0
-783FC0
-701DC0
-F01E80
-E00F00
-E00E00
-E00E00
-E00E00
-F01E00
-701C00
-783C00
-3C7800
-0FE000
-ENDCHAR
-STARTCHAR uni1EDB
-ENCODING 7899
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 14 14 0 0
-BITMAP
-00C0
-01C0
-0380
-0600
-0000
-1F18
-71FC
-E0FC
-E0FC
-E0E8
-E0F0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1EDC
-ENCODING 7900
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 18 19 0 0
-BITMAP
-018000
-01C000
-00E000
-003000
-000000
-0FE180
-3C7BC0
-783FC0
-701DC0
-F01E80
-E00F00
-E00E00
-E00E00
-E00E00
-F01E00
-701C00
-783C00
-3C7800
-0FE000
-ENDCHAR
-STARTCHAR uni1EDD
-ENCODING 7901
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 14 14 0 0
-BITMAP
-0600
-0700
-0380
-00C0
-0000
-1F18
-71FC
-E0FC
-E0FC
-E0E8
-E0F0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1EE0
-ENCODING 7904
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 18 18 0 0
-BITMAP
-00C400
-01F800
-023000
-000000
-0FE180
-3C7BC0
-783FC0
-701DC0
-F01E80
-E00F00
-E00E00
-E00E00
-E00E00
-F01E00
-701C00
-783C00
-3C7800
-0FE000
-ENDCHAR
-STARTCHAR uni1EE1
-ENCODING 7905
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 14 13 0 0
-BITMAP
-0310
-07E0
-08C0
-0000
-1F18
-71FC
-E0FC
-E0FC
-E0E8
-E0F0
-E0E0
-71C0
-1F00
-ENDCHAR
-STARTCHAR uni1EE2
-ENCODING 7906
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 18 17 0 -3
-BITMAP
-0FE180
-3C7BC0
-783FC0
-701DC0
-F01E80
-E00F00
-E00E00
-E00E00
-E00E00
-F01E00
-701C00
-783C00
-3C7800
-0FE000
-000000
-018000
-018000
-ENDCHAR
-STARTCHAR uni1EE3
-ENCODING 7907
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 14 12 0 -3
-BITMAP
-1F18
-71FC
-E0FC
-E0FC
-E0E8
-E0F0
-E0E0
-71C0
-1F00
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1EE4
-ENCODING 7908
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 14 17 1 -3
-BITMAP
-F87C
-7038
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-7010
-3820
-1FC0
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1EE5
-ENCODING 7909
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 12 12 0 -3
-BITMAP
-F1E0
-70E0
-70E0
-70E0
-70E0
-70E0
-70E0
-79E0
-3EF0
-0000
-0600
-0600
-ENDCHAR
-STARTCHAR uni1EE8
-ENCODING 7912
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 17 19 1 0
-BITMAP
-003000
-007000
-00E000
-018000
-000000
-F87F00
-703F80
-701780
-701380
-701100
-701200
-701400
-701000
-701000
-701000
-701000
-701000
-382000
-1FC000
-ENDCHAR
-STARTCHAR uni1EE9
-ENCODING 7913
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 15 14 0 0
-BITMAP
-0060
-00E0
-01C0
-0300
-0000
-F1EC
-70FE
-70FE
-70EE
-70E4
-70E8
-70F0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni1EEA
-ENCODING 7914
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 17 19 1 0
-BITMAP
-030000
-038000
-01C000
-006000
-000000
-F87F00
-703F80
-701780
-701380
-701100
-701200
-701400
-701000
-701000
-701000
-701000
-701000
-382000
-1FC000
-ENDCHAR
-STARTCHAR uni1EEB
-ENCODING 7915
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 15 14 0 0
-BITMAP
-0600
-0700
-0380
-00C0
-0000
-F1EC
-70FE
-70FE
-70EE
-70E4
-70E8
-70F0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni1EEE
-ENCODING 7918
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 17 18 1 0
-BITMAP
-018800
-03F000
-046000
-000000
-F87F00
-703F80
-701780
-701380
-701100
-701200
-701400
-701000
-701000
-701000
-701000
-701000
-382000
-1FC000
-ENDCHAR
-STARTCHAR uni1EEF
-ENCODING 7919
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 15 13 0 0
-BITMAP
-0310
-07E0
-08C0
-0000
-F1EC
-70FE
-70FE
-70EE
-70E4
-70E8
-70F0
-79E0
-3EF0
-ENDCHAR
-STARTCHAR uni1EF0
-ENCODING 7920
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 17 17 1 -3
-BITMAP
-F87F00
-703F80
-701780
-701380
-701100
-701200
-701400
-701000
-701000
-701000
-701000
-701000
-382000
-1FC000
-000000
-030000
-030000
-ENDCHAR
-STARTCHAR uni1EF1
-ENCODING 7921
-SWIDTH 685 0
-DWIDTH 13 0
-BBX 15 12 0 -3
-BITMAP
-F1EC
-70FE
-70FE
-70EE
-70E4
-70E8
-70F0
-79E0
-3EF0
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR Ygrave
-ENCODING 7922
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 19 1 0
-BITMAP
-1800
-1C00
-0E00
-0300
-0000
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR ygrave
-ENCODING 7923
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 18 0 -4
-BITMAP
-3000
-3800
-1C00
-0600
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR uni1EF4
-ENCODING 7924
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 17 1 -3
-BITMAP
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-0000
-0300
-0300
-ENDCHAR
-STARTCHAR uni1EF5
-ENCODING 7925
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 16 0 -7
-BITMAP
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-0000
-1800
-1800
-ENDCHAR
-STARTCHAR uni1EF8
-ENCODING 7928
-SWIDTH 722 0
-DWIDTH 15 0
-BBX 13 18 1 0
-BITMAP
-0C40
-1F80
-2300
-0000
-F878
-7030
-7820
-3860
-3C40
-1CC0
-1F80
-0F80
-0F00
-0700
-0700
-0700
-0700
-0F80
-ENDCHAR
-STARTCHAR uni1EF9
-ENCODING 7929
-SWIDTH 611 0
-DWIDTH 12 0
-BBX 11 17 0 -4
-BITMAP
-1880
-3F00
-4600
-0000
-F8E0
-7040
-7040
-3880
-3880
-1D00
-1D00
-0E00
-0E00
-0400
-C400
-E800
-7000
-ENDCHAR
-STARTCHAR uni2000
-ENCODING 8192
-SWIDTH 500 0
-DWIDTH 9 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2001
-ENCODING 8193
-SWIDTH 1000 0
-DWIDTH 19 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2002
-ENCODING 8194
-SWIDTH 500 0
-DWIDTH 9 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2003
-ENCODING 8195
-SWIDTH 1000 0
-DWIDTH 19 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2004
-ENCODING 8196
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2005
-ENCODING 8197
-SWIDTH 250 0
-DWIDTH 5 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2006
-ENCODING 8198
-SWIDTH 167 0
-DWIDTH 3 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2007
-ENCODING 8199
-SWIDTH 574 0
-DWIDTH 11 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2008
-ENCODING 8200
-SWIDTH 278 0
-DWIDTH 5 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2009
-ENCODING 8201
-SWIDTH 200 0
-DWIDTH 4 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni200A
-ENCODING 8202
-SWIDTH 100 0
-DWIDTH 2 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni200B
-ENCODING 8203
-SWIDTH 0 0
-DWIDTH 0 0
-BBX 1 1 0 0
-BITMAP
-00
-ENDCHAR
-STARTCHAR uni2010
-ENCODING 8208
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 5 2 0 4
-BITMAP
-F8
-F8
-ENDCHAR
-STARTCHAR uni2011
-ENCODING 8209
-SWIDTH 333 0
-DWIDTH 6 0
-BBX 5 2 0 4
-BITMAP
-F8
-F8
-ENDCHAR
-STARTCHAR figuredash
-ENCODING 8210
-SWIDTH 500 0
-DWIDTH 9 0
-BBX 9 2 0 4
-BITMAP
-FF80
-FF80
-ENDCHAR
-STARTCHAR endash
-ENCODING 8211
-SWIDTH 500 0
-DWIDTH 9 0
-BBX 9 2 0 4
-BITMAP
-FF80
-FF80
-ENDCHAR
-STARTCHAR emdash
-ENCODING 8212
-SWIDTH 1000 0
-DWIDTH 18 0
-BBX 18 2 0 4
-BITMAP
-FFFFC0
-FFFFC0
-ENDCHAR
-STARTCHAR afii00208
-ENCODING 8213
-SWIDTH 1000 0
-DWIDTH 18 0
-BBX 18 2 0 4
-BITMAP
-FFFFC0
-FFFFC0
-ENDCHAR
-STARTCHAR quoteleft
-ENCODING 8216
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 4 7 0 7
-BITMAP
-10
-20
-40
-E0
-F0
-F0
-60
-ENDCHAR
-STARTCHAR quoteright
-ENCODING 8217
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 4 7 0 7
-BITMAP
-60
-F0
-F0
-70
-20
-40
-80
-ENDCHAR
-STARTCHAR quotesinglbase
-ENCODING 8218
-SWIDTH 241 0
-DWIDTH 6 0
-BBX 4 7 1 -3
-BITMAP
-60
-F0
-F0
-70
-20
-40
-80
-ENDCHAR
-STARTCHAR quotereversed
-ENCODING 8219
-SWIDTH 241 0
-DWIDTH 5 0
-BBX 4 7 0 7
-BITMAP
-60
-F0
-F0
-E0
-40
-20
-10
-ENDCHAR
-STARTCHAR quotedblleft
-ENCODING 8220
-SWIDTH 481 0
-DWIDTH 10 0
-BBX 9 7 0 7
-BITMAP
-1080
-2100
-4200
-E700
-F780
-F780
-6300
-ENDCHAR
-STARTCHAR quotedblright
-ENCODING 8221
-SWIDTH 481 0
-DWIDTH 10 0
-BBX 9 7 0 7
-BITMAP
-6300
-F780
-F780
-7380
-2100
-4200
-8400
-ENDCHAR
-STARTCHAR quotedblbase
-ENCODING 8222
-SWIDTH 481 0
-DWIDTH 11 0
-BBX 9 7 1 -3
-BITMAP
-6300
-F780
-F780
-7380
-2100
-4200
-8400
-ENDCHAR
-STARTCHAR uni201F
-ENCODING 8223
-SWIDTH 481 0
-DWIDTH 10 0
-BBX 9 7 0 7
-BITMAP
-6300
-F780
-F780
-E700
-4200
-2100
-1080
-ENDCHAR
-STARTCHAR dagger
-ENCODING 8224
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 16 0 -2
-BITMAP
-1C00
-1C00
-0800
-C980
-FF80
-C980
-0800
-1C00
-1C00
-0800
-0800
-0800
-0800
-0800
-0800
-0800
-ENDCHAR
-STARTCHAR daggerdbl
-ENCODING 8225
-SWIDTH 500 0
-DWIDTH 10 0
-BBX 9 16 0 -2
-BITMAP
-1C00
-1C00
-0800
-C980
-FF80
-C980
-0800
-1C00
-1C00
-0800
-C980
-FF80
-C980
-0800
-1C00
-1C00
-ENDCHAR
-STARTCHAR bullet
-ENCODING 8226
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 6 6 2 4
-BITMAP
-78
-FC
-FC
-FC
-FC
-78
-ENDCHAR
-STARTCHAR ellipsis
-ENCODING 8230
-SWIDTH 1000 0
-DWIDTH 18 0
-BBX 16 4 1 0
-BITMAP
-6186
-F3CF
-F3CF
-6186
-ENDCHAR
-STARTCHAR perthousand
-ENCODING 8240
-SWIDTH 1000 0
-DWIDTH 22 0
-BBX 21 15 0 -1
-BITMAP
-38C000
-674000
-C4C000
-C48000
-C58000
-C90000
-730000
-023870
-0664C8
-04C588
-0CC588
-08C588
-18C990
-1070E0
-100000
-ENDCHAR
-STARTCHAR guilsinglleft
-ENCODING 8249
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 4 5 0 3
-BITMAP
-30
-60
-C0
-60
-30
-ENDCHAR
-STARTCHAR guilsinglright
-ENCODING 8250
-SWIDTH 333 0
-DWIDTH 5 0
-BBX 4 5 0 3
-BITMAP
-C0
-60
-30
-60
-C0
-ENDCHAR
-STARTCHAR fraction
-ENCODING 8260
-SWIDTH 167 0
-DWIDTH 3 0
-BBX 8 14 -3 0
-BITMAP
-03
-03
-06
-06
-0C
-0C
-18
-18
-30
-30
-60
-60
-C0
-C0
-ENDCHAR
-STARTCHAR oneinferior
-ENCODING 8321
-SWIDTH 344 0
-DWIDTH 6 0
-BBX 6 8 0 -4
-BITMAP
-30
-F0
-30
-30
-30
-30
-30
-FC
-ENDCHAR
-STARTCHAR twoinferior
-ENCODING 8322
-SWIDTH 344 0
-DWIDTH 6 0
-BBX 6 8 0 -4
-BITMAP
-78
-CC
-CC
-18
-30
-60
-C4
-FC
-ENDCHAR
-STARTCHAR threeinferior
-ENCODING 8323
-SWIDTH 344 0
-DWIDTH 6 0
-BBX 6 8 0 -4
-BITMAP
-78
-CC
-0C
-38
-0C
-CC
-CC
-78
-ENDCHAR
-STARTCHAR uni20A5
-ENCODING 8357
-SWIDTH 963 0
-DWIDTH 20 0
-BBX 19 14 0 -2
-BITMAP
-001800
-001800
-001800
-F7FF80
-79F3C0
-70F1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-70E1C0
-F9F3E0
-018000
-018000
-ENDCHAR
-STARTCHAR uni20A6
-ENCODING 8358
-SWIDTH 833 0
-DWIDTH 16 0
-BBX 15 14 1 0
-BITMAP
-F83E
-7C1C
-3C08
-3E08
-3FF8
-3FF8
-2388
-21C8
-3FF8
-3FF8
-2078
-2078
-7038
-F818
-ENDCHAR
-STARTCHAR uni20A9
-ENCODING 8361
-SWIDTH 981 0
-DWIDTH 19 0
-BBX 19 14 0 0
-BITMAP
-FBF3E0
-71E1C0
-70E180
-78E100
-3FFD00
-3FFF00
-3D7200
-1D3A00
-1FFE00
-1FFC00
-0E1C00
-0E1C00
-0C1800
-040800
-ENDCHAR
-STARTCHAR Euro
-ENCODING 8364
-SWIDTH 778 0
-DWIDTH 14 0
-BBX 14 14 -1 0
-BITMAP
-03E4
-0F1C
-1E0C
-1C0C
-FF84
-FF84
-3800
-3800
-FF80
-FF84
-1C04
-1E08
-0F18
-03E0
-ENDCHAR
-STARTCHAR uni20AD
-ENCODING 8365
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 14 1 0
-BITMAP
-FC7C
-7030
-7060
-70C0
-7180
-7300
-FFFE
-FFFE
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-ENDCHAR
-STARTCHAR uni2103
-ENCODING 8451
-SWIDTH 1158 0
-DWIDTH 21 0
-BBX 20 14 0 0
-BITMAP
-780F90
-CC3C70
-847830
-847030
-CCF010
-78E010
-00E000
-00E000
-00E000
-00F010
-007010
-007820
-003C60
-000F80
-ENDCHAR
-STARTCHAR uni2109
-ENCODING 8457
-SWIDTH 1102 0
-DWIDTH 20 0
-BBX 19 14 0 0
-BITMAP
-78FFE0
-CC70E0
-847060
-847120
-CC7120
-787320
-007F00
-007300
-007100
-007100
-007000
-007000
-007000
-00F800
-ENDCHAR
-STARTCHAR trademark
-ENCODING 8482
-SWIDTH 1000 0
-DWIDTH 20 0
-BBX 19 8 0 6
-BITMAP
-FFF1E0
-9971C0
-185AC0
-185AC0
-185AC0
-184CC0
-184CC0
-3CEDE0
-ENDCHAR
-STARTCHAR uni212A
-ENCODING 8490
-SWIDTH 815 0
-DWIDTH 16 0
-BBX 15 14 1 0
-BITMAP
-FC7C
-7030
-7060
-70C0
-7180
-7300
-7780
-7FC0
-7BC0
-71E0
-70F0
-70F8
-707C
-FCFE
-ENDCHAR
-STARTCHAR uni212B
-ENCODING 8491
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 18 0 0
-BITMAP
-0300
-0480
-0480
-0300
-0300
-0300
-0780
-0780
-0F80
-09C0
-09C0
-19E0
-10E0
-3FE0
-20F0
-6070
-4078
-E0FC
-ENDCHAR
-STARTCHAR uni2132
-ENCODING 8498
-SWIDTH 722 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-03E0
-01C0
-01C0
-01C0
-11C0
-11C0
-19C0
-1FC0
-99C0
-91C0
-91C0
-C1C0
-E1C0
-FFE0
-ENDCHAR
-STARTCHAR universal
-ENCODING 8704
-SWIDTH 759 0
-DWIDTH 14 0
-BBX 14 14 0 0
-BITMAP
-E0FC
-4078
-6070
-20F0
-3FE0
-10E0
-19E0
-09C0
-09C0
-0F80
-0780
-0780
-0300
-0300
-ENDCHAR
-STARTCHAR existential
-ENCODING 8707
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-E1C0
-C1C0
-91C0
-91C0
-19C0
-1FC0
-19C0
-11C0
-91C0
-81C0
-C1C0
-E1C0
-FFE0
-ENDCHAR
-STARTCHAR uni2204
-ENCODING 8708
-SWIDTH 759 0
-DWIDTH 13 0
-BBX 11 14 1 0
-BITMAP
-FFE0
-E1C0
-C1C0
-93C0
-93C0
-1BC0
-1FC0
-1FC0
-17C0
-9DC0
-8DC0
-CDC0
-F9C0
-FFE0
-ENDCHAR
-STARTCHAR minus
-ENCODING 8722
-SWIDTH 606 0
-DWIDTH 10 0
-BBX 9 2 0 4
-BITMAP
-FF80
-FF80
-ENDCHAR
-STARTCHAR fraction
-ENCODING 8725
-SWIDTH 167 0
-DWIDTH 3 0
-BBX 8 14 -3 0
-BITMAP
-03
-03
-06
-06
-0C
-0C
-18
-18
-30
-30
-60
-60
-C0
-C0
-ENDCHAR
-STARTCHAR periodcentered
-ENCODING 8729
-SWIDTH 278 0
-DWIDTH 5 0
-BBX 4 4 0 3
-BITMAP
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR uni2236
-ENCODING 8758
-SWIDTH 278 0
-DWIDTH 6 0
-BBX 4 9 1 0
-BITMAP
-60
-F0
-F0
-60
-00
-60
-F0
-F0
-60
-ENDCHAR
-STARTCHAR uni2259
-ENCODING 8793
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 11 1 2
-BITMAP
-0800
-1C00
-3E00
-6300
-0000
-FF80
-FF80
-0000
-0000
-FF80
-FF80
-ENDCHAR
-STARTCHAR uni225A
-ENCODING 8794
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 11 1 2
-BITMAP
-6300
-3E00
-1C00
-0800
-0000
-FF80
-FF80
-0000
-0000
-FF80
-FF80
-ENDCHAR
-STARTCHAR notequal
-ENCODING 8800
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 14 1 -2
-BITMAP
-0300
-0300
-0300
-0600
-FF80
-FF80
-0C00
-0C00
-FF80
-FF80
-1800
-1800
-3000
-3000
-ENDCHAR
-STARTCHAR equivalence
-ENCODING 8801
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 8 0 1
-BITMAP
-FF80
-FF80
-0000
-FF80
-FF80
-0000
-FF80
-FF80
-ENDCHAR
-STARTCHAR uni2262
-ENCODING 8802
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 9 14 0 -2
-BITMAP
-0300
-0300
-0300
-FF80
-FF80
-0600
-FF80
-FF80
-0C00
-FF80
-FF80
-1800
-3000
-3000
-ENDCHAR
-STARTCHAR lessequal
-ENCODING 8804
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 13 0 -3
-BITMAP
-00C0
-03C0
-0F00
-3C00
-F000
-F000
-3C00
-0F00
-03C0
-00C0
-0000
-FFC0
-FFC0
-ENDCHAR
-STARTCHAR greaterequal
-ENCODING 8805
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 13 0 -3
-BITMAP
-C000
-F000
-3C00
-0F00
-03C0
-03C0
-0F00
-3C00
-F000
-C000
-0000
-FFC0
-FFC0
-ENDCHAR
-STARTCHAR uni226E
-ENCODING 8814
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 14 0 -2
-BITMAP
-0300
-0300
-03C0
-07C0
-0F00
-3E00
-FC00
-FC00
-3C00
-1F00
-1BC0
-18C0
-3000
-3000
-ENDCHAR
-STARTCHAR uni226F
-ENCODING 8815
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 14 0 -2
-BITMAP
-0300
-0300
-C300
-F600
-3E00
-0F00
-0FC0
-0FC0
-0F00
-3C00
-F800
-D800
-3000
-3000
-ENDCHAR
-STARTCHAR uni2270
-ENCODING 8816
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 14 0 -3
-BITMAP
-0300
-03C0
-03C0
-0F00
-3E00
-F600
-FC00
-3C00
-0F00
-1BC0
-18C0
-1800
-FFC0
-FFC0
-ENDCHAR
-STARTCHAR uni2271
-ENCODING 8817
-SWIDTH 606 0
-DWIDTH 11 0
-BBX 10 14 0 -3
-BITMAP
-0300
-C300
-F300
-3E00
-0F00
-07C0
-0FC0
-0F00
-3C00
-F800
-D800
-1800
-FFC0
-FFC0
-ENDCHAR
-STARTCHAR fi
-ENCODING -1
-SWIDTH 685 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-0F80
-39C0
-31C0
-7000
-7000
-FFC0
-71C0
-71C0
-71C0
-71C0
-71C0
-71C0
-71C0
-FBE0
-ENDCHAR
-STARTCHAR fl
-ENCODING -1
-SWIDTH 685 0
-DWIDTH 12 0
-BBX 11 14 0 0
-BITMAP
-1EC0
-33C0
-71C0
-71C0
-71C0
-FFC0
-71C0
-71C0
-71C0
-71C0
-71C0
-71C0
-71C0
-FBE0
-ENDCHAR
-ENDFONT
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id:$
- *
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief BattFS: a filesystem for embedded platforms (implementation).
- */
-
-#include "battfs.h"
-
-#include <cfg/debug.h>
-#include <cfg/macros.h> /* MIN, MAX */
-#include <mware/byteorder.h> /* cpu_to_xx */
-
-
-#include <string.h> /* memset, memmove */
-
-
-/**
- * Convert from memory representation to disk structure.
- * \note filesystem is in little-endian format.
- */
-INLINE void battfs_to_disk(struct BattFsPageHeader *hdr, uint8_t *buf)
-{
- STATIC_ASSERT(BATTFS_HEADER_LEN == 12);
- buf[0] = hdr->inode;
-
- buf[1] = hdr->fill;
- buf[2] = hdr->fill >> 8;
-
- buf[3] = hdr->pgoff;
- buf[4] = hdr->pgoff >> 8;
-
- /*
- * Mark is at least 1 bit longer than page address.
- * Needed to take care of wraparonds.
- */
- buf[5] = hdr->mark;
- buf[6] = hdr->mark >> 8;
-
- /*
- * First bit used by mark, last 2 bits used by seq.
- * Since only 2 pages with the same inode and pgoff
- * can exist at the same time, 2 bit for seq are enough.
- * Unused bits are set to 1.
- */
- buf[7] = ((hdr->mark >> 16) & 0x01) | (hdr->seq << 6) | ~(BV(7) | BV(6) | BV(0));
-
- /*
- * This field must be the before the last one!
- */
- buf[8] = hdr->fcs_free;
- buf[9] = hdr->fcs_free >> 8;
-
- /*
- * This field must be the last one!
- * This is needed because if the page is only partially
- * written, we can use this to detect it.
- */
- buf[10] = hdr->fcs;
- buf[11] = hdr->fcs >> 8;
-}
-
-/**
- * Convert from disk structure to memory representation.
- * \note filesystem is in little-endian format.
- */
-INLINE void disk_to_battfs(uint8_t *buf, struct BattFsPageHeader *hdr)
-{
- STATIC_ASSERT(BATTFS_HEADER_LEN == 12);
- hdr->inode = buf[0];
- hdr->fill = buf[2] << 8 | buf[1];
- hdr->pgoff = buf[4] << 8 | buf[3];
- hdr->mark = (mark_t)(buf[7] & 0x01) << 16 | buf[6] << 8 | buf[5];
- hdr->seq = buf[7] >> 6;
- hdr->fcs_free = buf[9] << 8 | buf[8];
- hdr->fcs = buf[11] << 8 | buf[10];
-}
-
-/**
- * Compute the fcs of the header.
- */
-static fcs_t computeFcs(struct BattFsPageHeader *hdr)
-{
- uint8_t buf[BATTFS_HEADER_LEN];
- fcs_t cks;
-
- battfs_to_disk(hdr, buf);
- rotating_init(&cks);
- /* fcs is at the end of whole header */
- rotating_update(buf, BATTFS_HEADER_LEN - sizeof(fcs_t), &cks);
- return cks;
-}
-
-/**
- * Compute the fcs of the header marked as free.
- */
-static fcs_t computeFcsFree(struct BattFsPageHeader *hdr)
-{
- uint8_t buf[BATTFS_HEADER_LEN];
- fcs_t cks;
-
- battfs_to_disk(hdr, buf);
- rotating_init(&cks);
- /* fcs_free is just before fcs of whole header */
- rotating_update(buf, BATTFS_HEADER_LEN - 2 * sizeof(fcs_t), &cks);
- return cks;
-}
-
-
-/**
- * Read header of page \a page.
- * \return true on success, false otherwise.
- * \note \a hdr is dirtyed even on errors.
- */
-static bool battfs_readHeader(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr)
-{
- uint8_t buf[BATTFS_HEADER_LEN];
- /*
- * Read header from disk.
- * Header is actually a footer, and so
- * resides at page end.
- */
- if (disk->read(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN)
- != BATTFS_HEADER_LEN)
- {
- TRACEMSG("Error: page[%d]\n", page);
- return false;
- }
-
- /* Fill header */
- disk_to_battfs(buf, hdr);
-
- return true;
-}
-
-/**
- * Write header of page \a page.
- * \return true on success, false otherwise.
- * \note \a hdr is dirtyed even on errors.
- */
-static bool battfs_writeHeader(struct BattFsSuper *disk, pgcnt_t page, struct BattFsPageHeader *hdr)
-{
- uint8_t buf[BATTFS_HEADER_LEN];
-
- /* Fill buffer */
- battfs_to_disk(hdr, buf);
-
- /*
- * write header to disk.
- * Header is actually a footer, and so
- * resides at page end.
- */
- if (disk->write(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN)
- != BATTFS_HEADER_LEN)
- {
- TRACEMSG("Error: page[%d]\n", page);
- return false;
- }
- return true;
-}
-
-/**
- * Count the number of pages from
- * inode 0 to \a inode in \a filelen_table.
- */
-static pgcnt_t countPages(pgoff_t *filelen_table, inode_t inode)
-{
- pgcnt_t cnt = 0;
-
- for (inode_t i = 0; i < inode; i++)
- cnt += filelen_table[i];
-
- return cnt;
-}
-
-/**
- * Move all pages in page allocation array from \a src to \a src + \a offset.
- * The number of pages moved is page_count - MAX(dst, src).
- */
-static void movePages(struct BattFsSuper *disk, pgcnt_t src, int offset)
-{
- pgcnt_t dst = src + offset;
- memmove(&disk->page_array[dst], &disk->page_array[src], (disk->page_count - MAX(dst, src)) * sizeof(pgcnt_t));
-
- if (offset < 0)
- {
- /* Fill empty space in array with sentinel */
- for (pgcnt_t page = disk->page_count + offset; page < disk->page_count; page++)
- disk->page_array[page] = PAGE_UNSET_SENTINEL;
- }
-}
-
-/**
- * Insert \a page into page allocation array of \a disk,
- * using \a mark to compute position.
- */
-static void insertFreePage(struct BattFsSuper *disk, mark_t mark, pgcnt_t page)
-{
- ASSERT(mark - disk->free_start < disk->free_next - disk->free_start);
-
- pgcnt_t free_pos = disk->page_count - disk->free_next + mark;
- ASSERT(free_pos < disk->page_count);
-
- TRACEMSG("mark:%u, page:%u, free_start:%u, free_next:%u, free_pos:%u\n",
- mark, page, disk->free_start, disk->free_next, free_pos);
-
- ASSERT(disk->page_array[free_pos] == PAGE_UNSET_SENTINEL);
- disk->page_array[free_pos] = page;
-}
-
-/**
- * Mark \a page of \a disk as free.
- * \note free_next of \a disk is used as \a page free marker
- * and is increased by 1.
- */
-static bool battfs_markFree(struct BattFsSuper *disk, struct BattFsPageHeader *hdr, pgcnt_t page)
-{
- uint8_t buf[BATTFS_HEADER_LEN];
-
- hdr->mark = disk->free_next;
- hdr->fcs_free = computeFcsFree(hdr);
- battfs_to_disk(hdr, buf);
-
- if (!disk->write(disk, page, disk->page_size - BATTFS_HEADER_LEN, buf, BATTFS_HEADER_LEN))
- {
- TRACEMSG("error marking page [%d]\n", page);
- return false;
- }
- else
- {
- disk->free_next++;
- return true;
- }
-}
-
-/**
- * Determine free_start and free_next blocks for \a disk
- * using \a minl, \a maxl, \a minh, \a maxh.
- *
- * Mark_t is a type that has at least 1 bit more than
- * pgaddr_t. So all free blocks can be numbered using
- * at most half numbers of a mark_t type.
- * The free blocks algorithm increments by 1 the disk->free_next
- * every time a page becomes free. So the free block sequence is
- * guaranteed to be countiguous.
- * Only wrap arounds may happen, but due to half size sequence limitation,
- * there are only 4 possible situations:
- *
- * \verbatim
- * |------lower half------|-------upper half-------|
- *
- * 1) |------minl*****maxl---|------------------------|
- * 2) |------minl********maxl|minh******maxh----------|
- * 3) |----------------------|----minh*******maxh-----|
- * 4) |minl******maxl--------|------------minh****maxh|
- * \endverbatim
- *
- * Situations 1 and 3 are easy to detect, while 2 and 4 require more care.
- */
-static void findFreeStartNext(struct BattFsSuper *disk, mark_t minl, mark_t maxl, mark_t minh, mark_t maxh)
-{
- /* Determine free_start & free_next */
- if (maxl >= minl)
- {
- /* Valid interval found in lower half */
- if (maxh >= minh)
- {
- /* Valid interval also found in upper half */
- if (maxl == minh - 1)
- {
- /* Interval starts in lower half and ends in upper */
- disk->free_start = minl;
- disk->free_next = maxh;
- }
- else
- {
- /* Interval starts in upper half and ends in lower */
- ASSERT(minl == 0);
- ASSERT(maxh == (MAX_PAGE_ADDR | MARK_HALF_SIZE));
-
- disk->free_start = minh;
- disk->free_next = maxl;
- }
- }
- else
- {
- /*
- * Upper interval is invalid.
- * Use lower values.
- */
-
- disk->free_start = minl;
- disk->free_next = maxl;
- }
- }
- else if (maxh >= minh)
- {
- /*
- * Lower interval is invalid.
- * Use upper values.
- */
- disk->free_start = minh;
- disk->free_next = maxh;
- }
- else
- {
- /*
- * No valid interval found.
- * Hopefully the disk is brand new (or full).
- */
- TRACEMSG("No valid marked free block found, new disk or disk full\n");
- disk->free_start = 0;
- disk->free_next = -1; //to be increased later
- }
-
- /* free_next should contain the first usable address */
- disk->free_next++;
-
- TRACEMSG("Free markers:\n minl %u\n maxl %u\n minh %u\n maxh %u\n free_start %u\n free_next %u\n",
- minl, maxl, minh, maxh, disk->free_start, disk->free_next);
-}
-
-/**
- * Count number of pages per file on \a disk.
- * This information is registered in \a filelen_table.
- * Array index represent file inode, while value contained
- * is the number of pages used by that file.
- *
- * \return true if ok, false on disk read errors.
- * \note The whole disk is scanned once.
- */
-static bool countDiskFilePages(struct BattFsSuper *disk, pgoff_t *filelen_table)
-{
- BattFsPageHeader hdr;
- mark_t minl, maxl, minh, maxh;
-
- /* Initialize min and max counters to keep trace od free blocks */
- minl = MAX_PAGE_ADDR;
- maxl = 0;
- minh = MAX_PAGE_ADDR | MARK_HALF_SIZE;
- maxh = 0 | MARK_HALF_SIZE;
-
-
- /* Count the number of disk page per file */
- for (pgcnt_t page = 0; page < disk->page_count; page++)
- {
- if (!battfs_readHeader(disk, page, &hdr))
- return false;
-
- /* Check header FCS */
- if (hdr.fcs == computeFcs(&hdr))
- {
- ASSERT(hdr.mark == MARK_PAGE_VALID);
- ASSERT(hdr.fcs_free == FCS_FREE_VALID);
- ASSERT(hdr.fill <= disk->page_size - BATTFS_HEADER_LEN);
-
- /* Page is valid and is owned by a file */
- filelen_table[hdr.inode]++;
-
- /* Keep trace of free space */
- disk->free_bytes += disk->page_size - BATTFS_HEADER_LEN - hdr.fill;
- }
- else
- {
- /* Increase free space */
- disk->free_bytes += disk->page_size - BATTFS_HEADER_LEN;
-
- /* Check if page is marked free */
- if (hdr.fcs_free == computeFcsFree(&hdr))
- {
- /*
- * This page is a valid and marked free page.
- * Update min and max free page markers.
- */
- if (hdr.mark < MARK_HALF_SIZE)
- {
- minl = MIN(minl, hdr.mark);
- maxl = MAX(maxl, hdr.mark);
- }
- else
- {
- minh = MIN(minh, hdr.mark);
- maxh = MAX(maxh, hdr.mark);
- }
- }
- else
- TRACEMSG("page [%d] invalid, keeping as free\n", page);
- }
- }
- findFreeStartNext(disk, minl, maxl, minh, maxh);
- return true;
-}
-
-/**
- * Fill page allocation array of \a disk
- * using file lenghts in \a filelen_table.
- *
- * The page allocation array is an array containings all file infos.
- * Is ordered by file, and within each file is ordered by page offset
- * inside file.
- * e.g. : at page array[0] you will find page address of the first page
- * of the first file (if present).
- * Free blocks are allocated after the last file, starting from invalid ones
- * and continuing with the marked free ones.
- *
- * \return true if ok, false on disk read errors.
- * \note The whole disk is scanned once.
- */
-static bool fillPageArray(struct BattFsSuper *disk, pgoff_t *filelen_table)
-{
- BattFsPageHeader hdr;
- /* Fill page allocation array */
- for (pgcnt_t page = 0; page < disk->page_count; page++)
- {
- if (!battfs_readHeader(disk, page, &hdr))
- return false;
-
- /* Check header FCS */
- if (hdr.fcs == computeFcs(&hdr))
- {
- /* Page is valid and is owned by a file */
- ASSERT(hdr.mark == MARK_PAGE_VALID);
- ASSERT(hdr.fcs_free == FCS_FREE_VALID);
-
- /* Compute array position */
- pgcnt_t array_pos = countPages(filelen_table, hdr.inode);
- array_pos += hdr.pgoff;
-
- /* Check if position is already used by another page of the same file */
- if (LIKELY(disk->page_array[array_pos] == PAGE_UNSET_SENTINEL))
- disk->page_array[array_pos] = page;
- else
- {
- BattFsPageHeader hdr_old;
-
- if (!battfs_readHeader(disk, disk->page_array[array_pos], &hdr_old))
- return false;
-
- /* Check header FCS */
- ASSERT(hdr_old.fcs == computeFcs(&hdr_old));
-
- /* Only the very same page with a different seq number can be here */
- ASSERT(hdr.inode == hdr_old.inode);
- ASSERT(hdr.pgoff == hdr_old.pgoff);
- ASSERT(hdr.mark == hdr_old.mark);
- ASSERT(hdr.fcs_free == hdr_old.fcs_free);
- ASSERT(hdr.seq != hdr_old.seq);
-
- pgcnt_t new_page, old_page;
- fill_t old_fill;
-
- /* Fancy check to handle seq wraparound (2 bits only) */
- if (((hdr.seq - hdr_old.seq) & 0x03) < 2)
- {
- /* Current header is newer than the previuos one */
- old_page = disk->page_array[array_pos];
- new_page = page;
- old_fill = hdr_old.fill;
- }
- else
- {
- /* Previous header is newer than the current one */
- old_page = page;
- new_page = disk->page_array[array_pos];
- old_fill = hdr.fill;
- }
-
- /* Set new page */
- disk->page_array[array_pos] = new_page;
-
- /* Add free space */
- disk->free_bytes += old_fill;
-
- /* Shift all array one position to the left, overwriting duplicate page */
- array_pos -= hdr.pgoff;
- array_pos += filelen_table[hdr.inode];
- movePages(disk, array_pos, -1);
-
- /* Decrease file page count */
- filelen_table[hdr.inode]--;
-
- /* Add old page to free pages pool */
- if (!battfs_markFree(disk, &hdr, old_page))
- return false;
-
- insertFreePage(disk, hdr.mark, old_page);
- }
- }
- else
- {
- /* Check if page is free */
- if (hdr.fcs_free != computeFcsFree(&hdr))
- /* Page is not a valid marked page, insert at list beginning */
- hdr.mark = --disk->free_start;
-
- insertFreePage(disk, hdr.mark, page);
- }
- }
- return true;
-}
-
-/**
- * Initialize and mount disk described by
- * \a disk.
- * \return false on errors, true otherwise.
- */
-bool battfs_init(struct BattFsSuper *disk)
-{
- pgoff_t filelen_table[BATTFS_MAX_FILES];
-
- /* Sanity check */
- ASSERT(disk->open);
-
- /* Init disk device */
- if (!disk->open(disk))
- {
- TRACEMSG("open error\n");
- return false;
- }
-
- /* Disk open must set all of these */
- ASSERT(disk->read);
- ASSERT(disk->write);
- ASSERT(disk->erase);
- ASSERT(disk->close);
- ASSERT(disk->page_size);
- ASSERT(disk->page_count);
- ASSERT(disk->page_count < PAGE_UNSET_SENTINEL - 1);
- ASSERT(disk->page_array);
-
- memset(filelen_table, 0, BATTFS_MAX_FILES * sizeof(pgoff_t));
-
- disk->free_bytes = 0;
- disk->disk_size = (disk_size_t)(disk->page_size - BATTFS_HEADER_LEN) * disk->page_count;
-
- /* Count pages per file */
- if (!countDiskFilePages(disk, filelen_table))
- {
- TRACEMSG("error counting file pages\n");
- return false;
- }
-
- /* Once here, we have filelen_table filled with file lengths */
-
- /* Fill page array with sentinel */
- for (pgcnt_t page = 0; page < disk->page_count; page++)
- disk->page_array[page] = PAGE_UNSET_SENTINEL;
-
- /* Fill page allocation array using filelen_table */
- if (!fillPageArray(disk, filelen_table))
- {
- TRACEMSG("error filling page array\n");
- return false;
- }
-
- /* Init list for opened files. */
- LIST_INIT(&disk->file_opened_list);
- return true;
-}
-
-/**
- * Flush file \a fd.
- * \return 0 if ok, EOF on errors.
- */
-static int battfs_flush(struct KFile *fd)
-{
- (void)fd;
- #warning TODO
- return 0;
-}
-
-/**
- * Close file \a fd.
- * \return 0 if ok, EOF on errors.
- */
-static int battfs_fileclose(struct KFile *fd)
-{
- KFileBattFs *fdb = KFILEBATTFS(fd);
-
- battfs_flush(fd);
- REMOVE(&fdb->link);
- return 0;
-}
-
-/**
- * Read from file \a fd \a size bytes in \a buf.
- * \return The number of bytes read.
- */
-static size_t battfs_read(struct KFile *fd, void *_buf, size_t size)
-{
- KFileBattFs *fdb = KFILEBATTFS(fd);
- uint8_t *buf = (uint8_t *)_buf;
-
- size_t total_read = 0;
- pgoff_t pg_offset;
- pgaddr_t addr_offset;
- pgaddr_t read_len;
-
- size = MIN(size, fd->size - fd->seek_pos);
-
- while (size)
- {
- pg_offset = fd->seek_pos / (fdb->disk->page_size - BATTFS_HEADER_LEN);
- addr_offset = fd->seek_pos % (fdb->disk->page_size - BATTFS_HEADER_LEN);
- read_len = MIN(size, (size_t)(fdb->disk->page_size - BATTFS_HEADER_LEN - addr_offset));
-
- /* Read from disk */
- if (fdb->disk->read(fdb->disk, fdb->start[pg_offset], addr_offset, buf, read_len) != read_len)
- {
- #warning TODO set error?
- }
-
- size -= read_len;
- fd->seek_pos += read_len;
- total_read += read_len;
- buf += read_len;
- }
- return total_read;
-}
-
-
-/**
- * Search file \a inode in \a disk using a binary search.
- * \return pointer to file start in disk->page_array
- * if file exists, NULL otherwise.
- */
-static pgcnt_t *findFile(BattFsSuper *disk, inode_t inode)
-{
- BattFsPageHeader hdr;
- pgcnt_t first = 0, page, last = disk->page_count -1;
- fcs_t fcs;
-
- while (first <= last)
- {
- page = (first + last) / 2;
-
- if (!battfs_readHeader(disk, disk->page_array[page], &hdr))
- return NULL;
-
- fcs = computeFcs(&hdr);
- if (hdr.fcs == fcs && hdr.inode == inode)
- return (&disk->page_array[page]) - hdr.pgoff;
- else if (hdr.fcs == fcs && hdr.inode < inode)
- first = page + 1;
- else
- last = page - 1;
- }
-
- return NULL;
-}
-
-/**
- * \return true if file \a inode exists on \a disk, false otherwise.
- */
-bool battfs_fileExists(BattFsSuper *disk, inode_t inode)
-{
- return findFile(disk, inode) != NULL;
-}
-
-/**
- * Count size of file \a inode on \a disk, starting at pointer \a start
- * in disk->page_array. Size is written in \a size.
- * \return true if all s ok, false on disk read errors.
- */
-static bool countFileSize(BattFsSuper *disk, pgcnt_t *start, inode_t inode, file_size_t *size)
-{
- *size = 0;
- BattFsPageHeader hdr;
-
- for (;;)
- {
- if (!battfs_readHeader(disk, *start++, &hdr))
- return false;
- if (hdr.fcs == computeFcs(&hdr) && hdr.inode == inode)
- *size += hdr.fill;
- else
- return true;
- }
-}
-
-/**
- * Open file \a inode from \a disk in \a mode.
- * File context is stored in \a fd.
- * \return true if ok, false otherwise.
- */
-bool battfs_fileopen(BattFsSuper *disk, KFileBattFs *fd, inode_t inode, filemode_t mode)
-{
- Node *n;
-
- memset(fd, 0, sizeof(*fd));
-
- /* Search file start point in disk page array */
- fd->start = findFile(disk, inode);
- if (fd->start == NULL)
- {
- if (!(mode & BATTFS_CREATE))
- return false;
-
- /* File does not exist, create it */
- BattFsPageHeader hdr;
- hdr.inode = inode;
- hdr.seq = 0;
- hdr.fill = 0;
- hdr.pgoff = 0;
- hdr.mark = MARK_PAGE_VALID;
- hdr.fcs_free = FCS_FREE_VALID;
- hdr.fcs = computeFcs(&hdr);
- #warning TODO: get a free block and write on disk!
- }
-
- /* Fill file size */
- if (!countFileSize(disk, fd->start, inode, &fd->fd.size))
- return false;
-
- /* Reset seek position */
- fd->fd.seek_pos = 0;
-
- /* Insert file handle in list, ordered by inode, ascending. */
- FOREACH_NODE(n, &disk->file_opened_list)
- {
- KFileBattFs *file = containerof(n, KFileBattFs, link);
- if (file->inode >= inode)
- break;
- }
- INSERT_BEFORE(&fd->link, n);
-
- /* Fill in data */
- fd->inode = inode;
- fd->mode = mode;
- fd->disk = disk;
-
- fd->fd.close = battfs_fileclose;
- fd->fd.flush = battfs_flush;
- fd->fd.read = battfs_read;
- fd->fd.reopen = kfile_genericReopen;
- fd->fd.seek = kfile_genericSeek;
-
-#warning TODO battfs_write, battfs_error, battfs_clearerr
-#if 0
- fd->fd.write = battfs_write;
- fd->fd.error = battfs_error;
- fd->fd.clearerr = battfs_clearerr;
-#endif
-
- DB(fd->fd._type = KFT_BATTFS);
-
- return true;
-}
-
-/**
- * Close \a disk.
- */
-bool battfs_close(struct BattFsSuper *disk)
-{
- Node *n;
- int res = 0;
-
- /* Close all open files */
- FOREACH_NODE(n, &disk->file_opened_list)
- {
- KFileBattFs *file = containerof(n, KFileBattFs, link);
- res += battfs_fileclose(&file->fd);
- }
-
- /* Close disk */
- return disk->close(disk) && (res == 0);
-}
-
-
-bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff, mark_t mark)
-{
- BattFsPageHeader hdr;
-
- hdr.inode = inode;
- hdr.seq = seq;
- hdr.fill = fill;
- hdr.pgoff = pgoff;
- hdr.mark = MARK_PAGE_VALID;
- hdr.fcs_free = FCS_FREE_VALID;
- hdr.fcs = computeFcs(&hdr);
- if (mark != MARK_PAGE_VALID)
- {
- hdr.mark = mark;
- hdr.fcs_free = computeFcsFree(&hdr);
- }
-
- if (!battfs_writeHeader(disk, page, &hdr))
- {
- TRACEMSG("error writing hdr\n");
- return false;
- }
-
- return true;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief BattFS: a filesystem for embedded platforms (interface).
- * TODO: Add detailed filesystem description.
- */
-
-#ifndef FS_BATTFS_H
-#define FS_BATTFS_H
-
-#include <cfg/compiler.h> // uintXX_t; STATIC_ASSERT
-#include <cpu/types.h> // CPU_BITS_PER_CHAR
-#include <algo/rotating_hash.h>
-#include <mware/list.h>
-#include <kern/kfile.h>
-
-typedef uint16_t fill_t; ///< Type for keeping trace of space filled inside a page
-typedef fill_t pgaddr_t; ///< Type for addressing space inside a page
-typedef uint16_t pgcnt_t; ///< Type for counting pages on disk
-typedef pgcnt_t pgoff_t; ///< Type for counting pages inside a file
-typedef uint32_t mark_t; ///< Type for marking pages as free
-typedef uint8_t inode_t; ///< Type for file inodes
-typedef uint8_t seq_t; ///< Type for page seq number
-typedef rotating_t fcs_t; ///< Type for header FCS.
-
-/**
- * Size required for free block allocation is at least 1 bit more
- * than page addressing.
- */
-STATIC_ASSERT(sizeof(mark_t) > sizeof(pgcnt_t));
-
-/**
- * BattFS page header, used to represent a page
- * header in memory.
- * To see how this is stored on disk:
- * \see battfs_to_disk
- * \see disk_to_battfs
- */
-typedef struct BattFsPageHeader
-{
- inode_t inode; ///< File inode (file identifier).
- seq_t seq; ///< Page sequence number.
- fill_t fill; ///< Filled bytes in page.
- pgoff_t pgoff; ///< Page offset inside file.
- mark_t mark; ///< Marker used to keep trace of free/used pages.
-
- /**
- * FCS (Frame Check Sequence) of the page header once the page
- * as been marked as free.
- */
- fcs_t fcs_free;
-
- /**
- * FCS (Frame Check Sequence) of the page header.
- */
- fcs_t fcs;
-} BattFsPageHeader;
-
-/**
- * Size of the header once saved on disk.
- * \see battfs_to_disk
- * \see disk_to_battfs
- */
-#define BATTFS_HEADER_LEN 12
-
-/**
- * Marks for valid pages.
- * Simply set to 1 all field bits.
- * \{
- */
-#define MARK_PAGE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t) + 1)) - 1)
-#define FCS_FREE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(fcs_t))) - 1)
-/* \} */
-
-
-/**
- * Half-size of free page marker.
- * Used to keep trace of free marker wrap-arounds.
- */
-#define MARK_HALF_SIZE (1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t) + 1))
-
-/**
- * Maximum page address.
- */
-#define MAX_PAGE_ADDR ((1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t))) - 1)
-
-/**
- * Max number of files.
- */
-#define BATTFS_MAX_FILES (1 << (CPU_BITS_PER_CHAR * sizeof(inode_t)))
-
-/* Fwd decl */
-struct BattFsSuper;
-
-/**
- * Sentinel used to keep trace of unset pages in disk->page_array.
- */
-#define PAGE_UNSET_SENTINEL ((1 << (CPU_BITS_PER_CHAR * sizeof(pgcnt_t))) - 1)
-
-/**
- * Type interface for disk init function.
- * \return true if all is ok, false otherwise.
- */
-typedef bool (*disk_open_t) (struct BattFsSuper *d);
-
-/**
- * Type interface for disk page read function.
- * \a page is the page address, \a addr the address inside the page,
- * \a size the lenght to be read.
- * \return the number of bytes read.
- */
-typedef size_t (*disk_page_read_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t);
-
-/**
- * Type interface for disk page write function.
- * \a page is the page address, \a addr the address inside the page,
- * \a size the lenght to be written.
- * \return the number of bytes written.
- */
-typedef size_t (*disk_page_write_t) (struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, const void *buf, size_t);
-
-/**
- * Type interface for disk page erase function.
- * \a page is the page address.
- * \return true if all is ok, false otherwise.
- */
-typedef bool (*disk_page_erase_t) (struct BattFsSuper *d, pgcnt_t page);
-
-/**
- * Type interface for disk deinit function.
- * \return true if all is ok, false otherwise.
- */
-typedef bool (*disk_close_t) (struct BattFsSuper *d);
-
-
-typedef uint32_t disk_size_t; ///< Type for disk sizes.
-
-/**
- * Context used to describe a disk.
- * This context structure will be used to access disk.
- * Must be initialized by hw memory driver.
- */
-typedef struct BattFsSuper
-{
- disk_open_t open; ///< Disk init.
- disk_page_read_t read; ///< Page read.
- disk_page_write_t write; ///< Page write.
- disk_page_erase_t erase; ///< Page erase.
- disk_close_t close; ///< Disk deinit.
-
- pgaddr_t page_size; ///< Size of a disk page, in bytes.
- pgcnt_t page_count; ///< Number of pages on disk.
-
- /**
- * Page allocation array.
- * This array must be allocated somewhere and
- * must have enough space for page_count elements.
- * Is used by the filesystem to represent
- * the entire disk in memory.
- */
- pgcnt_t *page_array;
-
- /**
- * Lowest free page counter.
- * This is the counter of the first availble free page.
- */
- mark_t free_start;
-
- /**
- * Highest free page counter.
- * This value is the next to be used to mark a block as free.
- */
- mark_t free_next;
-
- disk_size_t disk_size; ///< Size of the disk, in bytes (page_count * page_size).
- disk_size_t free_bytes; ///< Free space on the disk.
-
- List file_opened_list; ///< List used to keep trace of open files.
- /* TODO add other fields. */
-} BattFsSuper;
-
-typedef uint8_t filemode_t; ///< Type for file open modes.
-typedef uint32_t file_size_t; ///< Type for file sizes.
-
-/**
- * Modes for battfs_fileopen.
- * \{
- */
-#define BATTFS_CREATE BV(0) ///< Create file if does not exist
-#define BATTFS_RD BV(1) ///< Open file for reading
-#define BATTFS_WR BV(2) ///< Open file fir writing
-/*/}*/
-
-
-/**
- * Describe a BattFs file usign a KFile.
- */
-typedef struct KFileBattFs
-{
- KFile fd; ///< KFile context
- Node link; ///< Link for inserting in opened file list
- inode_t inode; ///< inode of the opened file
- BattFsSuper *disk; ///< Disk context
- filemode_t mode; ///< File open mode
- pgcnt_t *start; ///< Pointer to page_array file start position.
-} KFileBattFs;
-
-/**
- * Id for battfs file descriptors.
- */
-#define KFT_BATTFS MAKE_ID('B', 'T', 'F', 'S')
-
-/**
- * Macro used to cast a KFile to a KFileBattFs.
- * Also perform dynamic type check.
- */
-INLINE KFileBattFs * KFILEBATTFS(KFile *fd)
-{
- ASSERT(fd->_type == KFT_BATTFS);
- return (KFileBattFs *)fd;
-}
-
-bool battfs_init(struct BattFsSuper *d);
-bool battfs_close(struct BattFsSuper *disk);
-
-bool battfs_fileExists(BattFsSuper *disk, inode_t inode);
-bool battfs_fileopen(BattFsSuper *disk, KFileBattFs *fd, inode_t inode, filemode_t mode);
-
-bool battfs_writeTestBlock(struct BattFsSuper *disk, pgcnt_t page, inode_t inode, seq_t seq, fill_t fill, pgoff_t pgoff, mark_t mark);
-
-#endif /* FS_BATTFS_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Bitmap manipulation routines.
- */
-
-#include "gfx.h"
-#include "gfx_p.h"
-
-#include <cfg/debug.h> /* ASSERT() */
-#include <cpu/attr.h> /* CPU_HARVARD */
-#include <cfg/macros.h> /* MIN() */
-#include <appconfig.h> /* CONFIG_GFX_CLIPPING */
-
-#include <string.h> /* memset() */
-
-#if CONFIG_GFX_TEXT
-#include <gfx/font.h> /* default_font */
-#endif
-
-
-/**
- * Initialize a Bitmap structure with the provided parameters.
- *
- * \note The pen position is reset to the origin.
- */
-void gfx_bitmapInit(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h)
-{
- bm->raster = raster;
- bm->width = w;
- bm->height = h;
- #if (CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB)
- bm->stride = (w + 7) / 8;
- #elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
- bm->stride = w;
- #else
- #error Unknown value of CONFIG_BITMAP_FMT
- #endif /* CONFIG_BITMAP_FMT */
- bm->penX = 0;
- bm->penY = 0;
-
-#if CONFIG_GFX_TEXT
- gfx_setFont(bm, &default_font);
- bm->styles = 0;
-#endif
-
-#if CONFIG_GFX_CLIPPING
- bm->cr.xmin = 0;
- bm->cr.ymin = 0;
- bm->cr.xmax = w;
- bm->cr.ymax = h;
-#endif /* CONFIG_GFX_CLIPPING */
-}
-
-
-/**
- * Clear the whole bitmap surface to the background color.
- *
- * \note This function does \b not update the current pen position.
- * \note This function bypasses the current clipping area.
- */
-void gfx_bitmapClear(Bitmap *bm)
-{
- memset(bm->raster, 0, RAST_SIZE(bm->width, bm->height));
-}
-
-
-#if CPU_HARVARD
-
-#include <avr/pgmspace.h> /* FIXME: memcpy_P() */
-
-/**
- * Copy a raster picture located in program memory in the bitmap.
- * The size of the raster to copy *must* be the same of the raster bitmap.
- *
- * \note This function does \b not update the current pen position
- */
-void gfx_blit_P(Bitmap *bm, const pgm_uint8_t *raster)
-{
- memcpy_P(bm->raster, raster, RAST_SIZE(bm->width, bm->height));
-}
-#endif /* CPU_HARVARD */
-
-#if CONFIG_GFX_CLIPPING
- /**
- * Clip destination coordinates inside a clipping range.
- *
- * This macro helps a drawing operation to adjust its
- * destination X and Y coordinates inside the destination
- * clipping range.
- *
- * The source start coordinate is adjusted as well
- * when destination start clipping occurs.
- */
- #define gfx_clip(dmin, dmax, smin, cmin, cmax) \
- do { \
- if ((dmin) < (cmin)) \
- { \
- (smin) += (cmin) - (dmin); \
- (dmin) = (cmin); \
- } \
- (dmax) = MIN((dmax), (cmax)); \
- } while(0)
-
-#else /* !CONFIG_GFX_CLIPPING */
-
- #define gfx_clip(dmin, dmax, smin, cmin, cmax) do { } while (0)
-
-#endif /* !CONFIG_GFX_CLIPPING */
-
-
-/**
- * Copy a rectangular area of a bitmap on another bitmap.
- *
- * Blitting is a common copy operation involving two bitmaps.
- * A rectangular area of the source bitmap is copied bit-wise
- * to a different position in the destination bitmap.
- *
- * \note Using the same bitmap for \a src and \a dst is unsupported.
- *
- * \param dst Bitmap where the operation writes.
- * \param rect The (xmin;ymin) coordinates provide the top/left offset
- * for drawing in the destination bitmap. If the source
- * bitmap is larger than the rectangle, drawing is clipped.
- * \param src Bitmap containing the source pixels.
- * \param srcx Starting X offset in the source bitmap.
- * \param srcy Starting Y offset in the source bitmap.
- */
-void gfx_blit(Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy)
-{
- coord_t dxmin, dymin, dxmax, dymax;
- coord_t dx, dy, sx, sy;
-
- /*
- * Pre-clip coordinates inside src->width/height.
- */
- dxmin = rect->xmin;
- dymin = rect->ymin;
- dxmax = MIN(rect->xmax, rect->xmin + src->width);
- dymax = MIN(rect->ymax, rect->ymin + src->height);
-
- /* Perform regular clipping */
- gfx_clip(dxmin, dxmax, srcx, dst->cr.xmin, dst->cr.xmax);
- gfx_clip(dymin, dymax, srcy, dst->cr.ymin, dst->cr.ymax);
-
- //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax);
- //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax);
-
- /* TODO: make it not as dog slow as this */
- for (dx = dxmin, sx = srcx; dx < dxmax; ++dx, ++sx)
- for (dy = dymin, sy = srcy; dy < dymax; ++dy, ++sy)
- BM_DRAWPIXEL(dst, dx, dy, BM_READPIXEL(src, sx, sy));
-}
-
-/**
- * Blit a raster to a Bitmap.
- *
- * \todo Merge this function into gfx_blit()
- *
- * \see gfx_blit()
- */
-void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin,
- const uint8_t *raster, coord_t w, coord_t h, coord_t stride)
-{
- coord_t dxmax = dxmin + w, dymax = dymin + h;
- coord_t sxmin = 0, symin = 0;
- coord_t dx, dy, sx, sy;
-
- /* Perform regular clipping */
- gfx_clip(dxmin, dxmax, sxmin, dst->cr.xmin, dst->cr.xmax);
- gfx_clip(dymin, dymax, symin, dst->cr.ymin, dst->cr.ymax);
-
- //kprintf("dxmin=%d, sxmin=%d, dxmax=%d; ", dxmin, sxmin, dxmax);
- //kprintf("dymin=%d, symin=%d, dymax=%d\n", dymin, symin, dymax);
-
- /* TODO: make it not as dog slow as this */
- for (dx = dxmin, sx = sxmin; dx < dxmax; ++dx, ++sx)
- for (dy = dymin, sy = symin; dy < dymax; ++dy, ++sy)
- BM_DRAWPIXEL(dst, dx, dy, RAST_READPIXEL(raster, sx, sy, stride));
-}
-
-/**
- * Blit an Image to a Bitmap.
- *
- * \see gfx_blit()
- */
-void gfx_blitImage(Bitmap *dst, coord_t dxmin, coord_t dymin, const Image *image)
-{
- ASSERT(image);
-
- gfx_blitRaster(dst, dxmin, dymin,
- image->raster, image->width, image->height, image->stride);
-}
-
-
-#if CONFIG_GFX_CLIPPING || CONFIG_GFX_VCOORDS
-
-/**
- * Set the bitmap clipping rectangle to the specified coordinates.
- *
- * All drawing performed on the bitmap will be clipped inside this
- * rectangle.
- *
- * The clipping rectangle is also used as a bounding box for the
- * logical view of the virtual coordinate system.
- *
- * \note Following the convention used for all other operations, the
- * top-left pixels of the rectangle are included, while the
- * bottom-right pixels are considered outside the clipping region.
- *
- * \see gfx_setViewRect
- */
-void gfx_setClipRect(Bitmap *bm, coord_t minx, coord_t miny, coord_t maxx, coord_t maxy)
-{
- ASSERT(minx < maxx);
- ASSERT(miny < maxy);
- ASSERT(miny >= 0);
- ASSERT(minx >= 0);
- ASSERT(maxx <= bm->width);
- ASSERT(maxy <= bm->height);
-
- bm->cr.xmin = minx;
- bm->cr.ymin = miny;
- bm->cr.xmax = maxx;
- bm->cr.ymax = maxy;
-
-// kprintf("cr.xmin = %d, cr.ymin = %d, cr.xmax = %d, cr.ymax = %d\n",
-// bm->cr.xMin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);
-}
-
-#endif /* CONFIG_GFX_CLIPPING */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Simple charts on top of mware/gfx routines (implementation).
- *
- * Sample usage:
- *
- * \code
- * bm = chart_init(0, ymax, N_POINTS_CURVE, ymin);
- *
- * chart_drawCurve(bm, curve_y, curve_points + 1);
- * gfx_setViewRect(bm, xmin, ymax, xmax, ymin);
- * chart_drawDots(bm, samples_x, samples_y, samples_cnt);
- *
- * print_bitmap(bm);
- * \endcode
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.3 2005/11/27 23:33:29 bernie
- *#* Reorder includes.
- *#*
- *#* Revision 1.2 2005/11/04 18:17:45 bernie
- *#* Fix header guards and includes for new location of gfx module.
- *#*
- *#* Revision 1.1 2005/11/04 18:11:35 bernie
- *#* Move graphics stuff from mware/ to gfx/.
- *#*
- *#* Revision 1.7 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.6 2004/11/16 21:04:23 bernie
- *#* Update to new naming scheme in mware/gfx.c.
- *#*
- *#* Revision 1.5 2004/09/14 20:56:39 bernie
- *#* Make more generic and adapt to new gfx functions.
- *#*
- *#* Revision 1.3 2004/08/11 19:39:12 bernie
- *#* Use chart_x_t and chart_y_t for the input dataset.
- *#*
- *#* Revision 1.1 2004/08/04 03:16:30 bernie
- *#* Import simple chart drawing code.
- *#*
- *#*/
-
-#include "charts.h"
-#include <gfx/gfx.h>
-
-
-#ifndef CONFIG_CHART_ARROWS
-#define CONFIG_CHART_ARROWS 0
-#endif
-
-
-void chart_init(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord_t ymax)
-{
- /* Clear the chart area */
- gfx_rectClear(bm, xmin, ymin, xmax, ymax);
-
- gfx_setClipRect(bm, xmin + CHART_BORDERLEFT, ymin + CHART_BORDERTOP,
- xmax - CHART_BORDERRIGHT, ymax - CHART_BORDERBOTTOM);
-
- chart_drawAxis(bm);
-}
-
-
-void chart_setScale(Bitmap *bm, chart_x_t xmin, chart_y_t ymin, chart_x_t xmax, chart_y_t ymax)
-{
- gfx_setViewRect(bm, xmin, ymin, xmax, ymax);
-}
-
-
-/**
- * Draw the chart axes
- */
-void chart_drawAxis(Bitmap *bm)
-{
-#if CONFIG_CHART_ARROWS
-
- /* Draw axis */
- gfx_moveTo(bm, bm->cr.xmin, bm->cr.ymin + 4);
- gfx_lineTo(bm, bm->cr.xmin, bm->cr.ymax - 1);
- gfx_lineTo(bm, bm->cr.xmax - 4 - 1, bm->cr.ymax - 1);
-
- /* Draw up arrow */
- gfx_moveTo(bm, bm->cr.xmin - 2, bm->cr.ymin + 3);
- gfx_lineTo(bm, bm->cr.xmin + 2, bm->cr.ymin + 3);
- gfx_lineTo(bm, bm->cr.xmin, bm->cr.ymin);
- gfx_lineTo(bm, bm->cr.xmin - 2, bm->cr.ymin + 3);
-
- /* Draw right arrow */
- gfx_moveTo(bm, bm->cr.xmax - 4, bm->cr.ymax - 3);
- gfx_lineTo(bm, bm->cr.xmax - 4, bm->cr.ymax + 1);
- gfx_lineTo(bm, bm->cr.xmax - 1, bm->cr.ymax - 1);
- gfx_lineTo(bm, bm->cr.xmax - 4, bm->cr.ymax - 3);
-
-#else /* CONFIG_CHART_ARROWS */
-
- /* Draw a box around the chart */
- gfx_rectDraw(bm, bm->cr.xmin, bm->cr.ymin, bm->cr.xmax, bm->cr.ymax);
-
-#endif /* CONFIG_CHART_ARROWS */
-
- //CHECK_WALL(wall_before_raster, WALL_SIZE);
- //CHECK_WALL(wall_after_raster, WALL_SIZE);
-}
-
-
-/**
- * Draw a set of \a curve_cnt connected segments, whose Y coordinates
- * are identified by the \a curve_y array and X-coordinates are
- * are evenly spaced by one virtual unit.
- */
-void chart_drawCurve(Bitmap *bm, const chart_y_t *curve_y, int curve_cnt)
-{
- int i;
-
- gfx_moveTo(bm, gfx_transformX(bm, 0), gfx_transformY(bm, curve_y[0]));
-
- for (i = 1; i < curve_cnt; i++)
- gfx_lineTo(bm, gfx_transformX(bm, i), gfx_transformY(bm, curve_y[i]));
-
- //CHECK_WALL(wall_before_raster, WALL_SIZE);
- //CHECK_WALL(wall_after_raster, WALL_SIZE);
-}
-
-
-/**
- * Disegna dei dot in corrispondenza delle coppie (dotsx[i];dotsy[i])
- * Se dotsx e' NULL, i punti vengono disegnati ad intervalli regolari.
- */
-void chart_drawDots(Bitmap *bm, const chart_x_t *dots_x, const chart_y_t *dots_y, int cnt)
-{
- int i;
- coord_t x, y;
-
- for (i = 0; i < cnt; i++)
- {
- if (dots_x)
- x = gfx_transformX(bm, dots_x[i]);
- else
- x = gfx_transformX(bm, i);
-
- y = gfx_transformY(bm, dots_y[i]);
-
- /* Draw tick over the curve */
- gfx_rectFill(bm,
- x - TICKS_WIDTH / 2, y - TICKS_HEIGHT / 2,
- x + (TICKS_WIDTH + 1) / 2, y + (TICKS_HEIGHT + 1) / 2);
-
- /* Draw vertical line from the curve to the X-axis */
- //gfx_drawLine(bm, x, y, x, bm->cr.ymax - 1);
- }
-
- //CHECK_WALL(wall_before_raster, WALL_SIZE);
- //CHECK_WALL(wall_after_raster, WALL_SIZE);
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Simple charts on top of mware/gfx routines (interface).
- *
- * Configuration:
- * - \c CONFIG_CHART_TYPE_X: type for the input dataset of X-coordinates
- * - \c CONFIG_CHART_TYPE_Y: type for the input dataset of Y-coordinates
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.5 2006/08/01 12:23:03 bernie
- *#* Indentation fix.
- *#*
- *#* Revision 1.4 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.3 2005/11/27 23:36:18 bernie
- *#* Use appconfig.h instead of cfg/config.h.
- *#*
- *#* Revision 1.2 2005/11/04 18:17:45 bernie
- *#* Fix header guards and includes for new location of gfx module.
- *#*
- *#* Revision 1.1 2005/11/04 18:11:35 bernie
- *#* Move graphics stuff from mware/ to gfx/.
- *#*
- *#* Revision 1.7 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.6 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.5 2004/09/14 20:56:39 bernie
- *#* Make more generic and adapt to new gfx functions.
- *#*
- *#* Revision 1.3 2004/08/11 19:39:12 bernie
- *#* Use chart_x_t and chart_y_t for the input dataset.
- *#*
- *#* Revision 1.1 2004/08/04 03:16:30 bernie
- *#* Import simple chart drawing code.
- *#*
- *#*/
-#ifndef GFX_CHARTS_H
-#define GFX_CHARTS_H
-
-#include <gfx/gfx.h> /* vcoord_t */
-#include <appconfig.h> /* CONFIG_ stuff */
-
-/**
- * \name Width/height of the small ticks drawn over the axes
- * \{
- */
-#define TICKS_HEIGHT 2
-#define TICKS_WIDTH 2
-/*\}*/
-
-/**
- * \name Chart frame dimensions
- * \{
- */
-#define CHART_BORDERTOP 0
-#define CHART_BORDERBOTTOM 0
-#define CHART_BORDERLEFT 0
-#define CHART_BORDERRIGHT 0
-/*\}*/
-
-#ifndef CONFIG_CHART_TYPE_X
-#define CONFIG_CHART_TYPE_X vcoord_t
-#endif
-#ifndef CONFIG_CHART_TYPE_Y
-#define CONFIG_CHART_TYPE_Y vcoord_t
-#endif
-
-
-typedef CONFIG_CHART_TYPE_X chart_x_t;
-typedef CONFIG_CHART_TYPE_Y chart_y_t;
-
-
-/* Public function protos */
-void chart_init(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord_t ymax);
-void chart_setScale(Bitmap *bm, chart_x_t xmin, chart_y_t ymin, chart_x_t xmax, chart_y_t ymax);
-void chart_drawAxis(Bitmap *bm);
-void chart_drawCurve(Bitmap *bm, const chart_y_t *curve_y, int curve_cnt);
-void chart_drawDots(Bitmap *bm, const chart_x_t *dots_x, const chart_y_t *dots_y, int cnt);
-
-#endif /* GFX_CHARTS_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- * \author Massimiliano Corsini <chad@develer.com>
- *
- *
- * \brief Low-level drawing routines.
- *
- * This file contains the implementation of the low-level drawing routines
- * to draw fill rectangle, fill triangle and so on.
- *
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.1 2006/07/19 13:00:01 bernie
- *#* Import into DevLib.
- *#*
- *#* Revision 1.10 2005/10/15 15:03:43 rasky
- *#* Remove per-pixel clipping from line().
- *#* Use clipLine() also for a-scope.
- *#*
- *#* Revision 1.9 2005/10/14 15:21:32 eldes
- *#* Implement the cohen-sutherland clipping on the buffer
- *#*
- *#* Revision 1.8 2005/09/27 13:28:10 rasky
- *#* Add clipping capabilities to line()
- *#* Fix off-by-one computation of rectangles of drawing.
- *#*
- *#* Revision 1.7 2005/09/27 10:41:35 rasky
- *#* Import line-drawing routine from Devlib
- *#*
- *#* Revision 1.6 2005/09/19 16:36:05 chad
- *#* Fix doxygen autobrief
- *#*
- *#* Revision 1.5 2005/07/06 12:51:47 chad
- *#* Make the fillRectangle() independent of the order of the points of the rectangle
- *#*
- *#* Revision 1.4 2005/06/17 15:06:36 chad
- *#* Remove conversion warning
- *#*
- *#* Revision 1.3 2005/06/17 15:04:47 chad
- *#* Add line clipping capability
- *#*
- *#* Revision 1.2 2005/06/15 14:04:43 chad
- *#* Add line routine
- *#*
- *#* Revision 1.1 2005/06/15 13:34:34 chad
- *#* Low-level drawing routines
- *#*
- *#*/
-
-// Qt-specific headers
-#include <qpoint.h>
-
-
-/**
- * Low-level routine to draw a line.
- *
- * This routine is based on the Bresenham Line-Drawing Algorithm.
- *
- * The \a stride represents the width of the image buffer.
- * (\a x1, \a y1) are the coordinates of the starting point.
- * (\a x2, \a y2) are the coordinates of the ending point.
- *
- * The line has no anti-alias, and clipping is not performed. The line
- * must be fully contained in the buffer (use clipLine() if you need
- * to clip it).
- */
-void line(unsigned char *buf,
- unsigned long bufw, unsigned long bufh, unsigned long stride,
- int x1, int y1, int x2, int y2, unsigned char color)
-{
- int x, y, e, len, adx, ady, signx, signy;
-
- if (x2 > x1)
- {
- /* left to right */
- signx = +1;
- adx = x2 - x1;
- }
- else
- {
- /* right to left */
- signx = -1;
- adx = x1 - x2;
- }
-
- if (y2 > y1)
- {
- /* top to bottom */
- signy = +1;
- ady = y2 - y1;
- }
- else
- {
- /* bottom to top */
- signy = -1;
- ady = y1 - y2;
- }
-
- x = x1;
- y = y1;
-
- if (adx > ady)
- {
- /* X-major line (octants 1/4/5/8) */
- len = adx;
- e = -adx;
- while (len--)
- {
- /* Sanity check */
- assert(y >= 0 && y < static_cast<int>(bufh) &&
- x >= 0 && x < static_cast<int>(bufw));
- buf[y * stride + x] = color;
- x += signx;
- e += ady;
- if (e >= 0)
- {
- y += signy;
- e -= adx;
- }
- }
- }
- else
- {
- /* Y-major line (octants 2/3/6/7) */
- len = ady;
- e = -ady;
- while (len--)
- {
- /* Sanity check */
- assert(y >= 0 && y < static_cast<int>(bufh) &&
- x >= 0 && x < static_cast<int>(bufw));
- buf[y * stride + x] = color;
- y += signy;
- e += adx;
- if (e >= 0)
- {
- x += signx;
- e -= ady;
- }
- }
- }
-}
-
-/// Helper routine for clipLine().
-static int region(int x, int y, int w, int h)
-{
- int code = 0;
-
- if (y >= h)
- code |= 1; // top
- else if (y < 0)
- code |= 2; // bottom
-
- if (x >= w)
- code |= 4; // right
- else if (x < 0)
- code |= 8; // left
-
- return code;
-}
-
-/**
- * Low-level routine to draw a line, clipped to the buffer extents.
- *
- * This routine executes the clipping, and then invokes line().
- * Parameters are the same of line(). The clipping is performed
- * using the Cohen-Sutherland algorithm, which is very fast.
- */
-void clipLine(unsigned char *buf,
- unsigned long w, unsigned long h, unsigned long stride,
- int x1, int y1, int x2, int y2, unsigned char color)
-{
- int code1 = region(x1, y1, w, h);
- int code2 = region(x2, y2, w, h);
-
- // Loop while there is at least one point outside
- while (code1 | code2)
- {
- // Check for line totally outside
- if (code1 & code2)
- return;
-
- int c = code1 ? code1 : code2;
- int x, y;
-
- if (c & 1) // top
- {
- x = x1 + (x2 - x1) * (h - y1) / (y2 - y1);
- y = h - 1;
- }
- else if (c & 2) //bottom
- {
- x = x1 + (x2 - x1) * -y1 / (y2 - y1);
- y = 0;
- }
- else if (c & 4) //right
- {
- y = y1 + (y2 - y1) * (w - x1) / (x2 - x1);
- x = w - 1;
- }
- else //left
- {
- y = y1 + (y2 - y1) * -x1 / (x2 - x1);
- x = 0;
- }
-
- if (c == code1) // first endpoint was clipped
- {
- x1 = x; y1 = y;
- code1 = region(x1, y1, w, h);
- }
- else //second endpoint was clipped
- {
- x2 = x; y2 = y;
- code2 = region(x2, y2, w, h);
- }
- }
-
- line(buf, w, h, stride, x1, y1, x2, y2, color);
-}
-
-
-/**
- * Low-level routine to draw a filled rectangle.
- *
- * The triangle is filled with the given color.
- *
- * The \a stride represents the width of the image buffer.
- * The points \a p1 and \a p2 are two opposite corners of the
- * rectangle.
- */
-void fillRectangle(unsigned char *buf, unsigned long stride,
- QPoint p1, QPoint p2, unsigned char color)
-{
- QPoint ul; // upper-left corner
- QPoint lr; // lower-right corner
-
- if (p2.x() > p1.x())
- {
- ul.setX(p1.x());
- lr.setX(p2.x());
- }
- else
- {
- ul.setX(p2.x());
- lr.setX(p1.x());
- }
-
- if (p2.y() > p1.y())
- {
- ul.setY(p1.y());
- lr.setY(p2.y());
- }
- else
- {
- ul.setY(p2.y());
- lr.setY(p1.y());
- }
-
- int width = lr.x() - ul.x();
- unsigned long offset = ul.x() + ul.y()*stride;
-
- for (int h = ul.y(); h < lr.y(); h++)
- {
- memset(buf+offset, color, width);
- offset += stride;
- }
-}
-
-/**
- * Low-level routines to draw a filled triangle.
- *
- * The triangle is filled with the given \a color.
- * The \a stride represents the width of the image buffer (\a buf).
- *
- * The routine use fixed-point arithmetic.
- */
-void fillTriangle(unsigned char* buf, unsigned long stride,
- QPoint v1, QPoint v2, QPoint v3, unsigned char color)
-{
- int altezza[3];
-
- // Sort by vertical coordinate
- if (v1.y() > v2.y())
- std::swap(v1, v2);
- if (v1.y() > v3.y())
- std::swap(v1, v3);
- if (v2.y() > v3.y())
- std::swap(v2, v3);
-
- altezza[0] = v3.y() - v1.y();
- if (!altezza[0])
- return;
-
- int sezioni = 2;
- int sezione = 1;
-
- buf += v1.y() * stride;
-
- altezza[1] = v2.y() - v1.y();
- altezza[2] = v3.y() - v2.y();
-
- int sinistra = v1.x();
- int destra = sinistra;
-
- if (v1.y() == v2.y())
- {
- if (v1.x() < v2.x())
- destra = v2.x();
- else
- sinistra = v2.x();
- }
-
- sinistra <<= 16;
- destra <<= 16;
-
- int stmp1, stmp2, stmp3;
-
- stmp1 = (altezza[1] << 16) / altezza[0];
- int lunghezza = stmp1 * (v3.x() - v1.x()) + ((v1.x() - v2.x()) << 16);
-
- if (!lunghezza )
- return;
-
- int delta_sinistra[2];
- int delta_destra[2];
-
- stmp1 = ((v3.x() - v1.x()) << 16) / altezza[0];
-
- if (altezza[1])
- stmp2 = ((v2.x() - v1.x()) << 16) / altezza[1];
- if (altezza[2])
- stmp3 = ((v3.x() - v2.x()) << 16) / altezza[2];
-
- if (lunghezza < 0) // Il secondo vertice ~J a destra
- {
- delta_sinistra[0] = stmp1;
- delta_sinistra[1] = stmp1;
- delta_destra[0] = stmp2;
- delta_destra[1] = stmp3;
- }
- else // Il secondo vertice ~J a sinistra
- {
- delta_sinistra[0] = stmp2;
- delta_sinistra[1] = stmp3;
- delta_destra[0] = stmp1;
- delta_destra[1] = stmp1;
- }
-
- int len2 = lunghezza;
-
- do
- {
- while (altezza [sezione])
- {
- unsigned char* curpos = buf + ((sinistra )>> 16);
- lunghezza = ((destra ) >> 16) - ((sinistra ) >> 16);
- assert(lunghezza >= 0);
- if (lunghezza)
- memset(curpos, color, lunghezza);
- buf += stride;
- destra += delta_destra[sezione - 1];
- sinistra += delta_sinistra[sezione - 1];
- altezza[sezione]--;
- }
- if (len2 < 0)
- destra = v2.x() << 16;
- else
- sinistra = v2.x() << 16;
- sezione++;
- } while (--sezioni);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Font 8x6 IBM-PC 8bit
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2006/05/27 22:31:34 bernie
- *#* Switch to a smaller default fount.
- *#*
- *#* Revision 1.5 2006/03/13 02:06:04 bernie
- *#* FONT_HAS_GLYPH(): New macro.
- *#*
- *#* Revision 1.4 2006/02/15 09:10:15 bernie
- *#* Implement prop fonts; Fix algo styles.
- *#*
- *#* Revision 1.3 2006/02/10 12:29:05 bernie
- *#* Add multiple font support in bitmaps.
- *#*
- *#* Revision 1.2 2005/11/04 18:17:45 bernie
- *#* Fix header guards and includes for new location of gfx module.
- *#*
- *#* Revision 1.1 2005/11/04 18:11:35 bernie
- *#* Move graphics stuff from mware/ to gfx/.
- *#*
- *#* Revision 1.6 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.5 2005/03/01 23:26:45 bernie
- *#* Use new CPU-neutral program-memory API.
- *#*
- *#* Revision 1.4 2004/12/31 16:42:55 bernie
- *#* Sanitize for non-Harvard processors.
- *#*
- *#* Revision 1.3 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 15:43:16 bernie
- *#* Import mware modules.
- *#*
- *#* Revision 1.2 2004/03/24 15:48:53 bernie
- *#* Remove Copyright messages from Doxygen output
- *#*
- *#* Revision 1.1 2004/01/13 12:15:28 aleph
- *#* Move font table in program memory; add font.h
- *#*
- *#*/
-#ifndef GFX_FONT_H
-#define GFX_FONT_H
-
-#include <cfg/compiler.h> /* uint8_t */
-#include <mware/pgm.h> /* PROGMEM */
-
-typedef struct Font
-{
- /**
- * Pointer to glyph data.
- *
- * Data is an array of at most 256 glyphs packed together.
- * Raster format must be the same of the bitmap.
- */
- const PROGMEM uint8_t *glyph;
-
- uint8_t width; /**< Pixel width of character cell. */
- uint8_t height; /**< Pixel height of character cell. */
-
- uint8_t first; /**< First encoded character in glyph array. */
- uint8_t last; /**< Last encoded character in glyph array (inclusive). */
-
- /** Array of glyph offsets in bytes. NULL for fixed-width fonts. */
- const PROGMEM uint16_t *offset;
- const PROGMEM uint8_t *widths;
-
-} Font;
-
-
-/** Return true if glyph \a c is available in \a font. */
-#define FONT_HAS_GLYPH(font, c) ((c) >= (font)->first && (c) <= (font)->last)
-
-
-/** The default font. */
-#define default_font font_luBS14
-extern const struct Font default_font;
-
-#endif /* GFX_FONT_H */
+++ /dev/null
-/* Generated by convbdf on Fri Feb 10 01:05:15 CET 2006. */
-#include "font.h"
-
-/* Font information:
-
- name: -Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1
- pixel size: 20
- ascent: 16
- descent: 4
-*/
-
-/* Font character bitmap data. */
-static const PROGMEM uint8_t font_10x20_glyphs[] = {
-
-/* Character (0x00):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | *** *** |
- | * * |
- | * * |
- | |
- | |
- | * * |
- | * * |
- | * * |
- | |
- | |
- | * * |
- | * * |
- | *** *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0073, 0x0080,
-0x0040, 0x0080,
-0x0040, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0040, 0x0080,
-0x0040, 0x0080,
-0x0040, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0040, 0x0080,
-0x0040, 0x0080,
-0x0073, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x01):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | **** |
- | ****** |
- | ******** |
- | ******** |
- | ****** |
- | **** |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x003f, 0x0000,
-0x007f, 0x0080,
-0x007f, 0x0080,
-0x003f, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x02):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- | * * * * * |
- |* * * * * |
- +----------------+ */
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-0x0055, 0x0040,
-0x00aa, 0x0080,
-
-/* Character (0x03):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x007e, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x0000, 0x0000,
-0x001f, 0x0080,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x04):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | ***** |
- | ** |
- | ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | ***** |
- | ** |
- | ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007c, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0078, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x000f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000f, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x05):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | **** |
- | ** ** |
- | ** |
- | ** |
- | ** ** |
- | **** |
- | |
- | ***** |
- | ** ** |
- | ** ** |
- | ***** |
- | **** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003c, 0x0000,
-0x0066, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0066, 0x0000,
-0x003c, 0x0000,
-0x0000, 0x0000,
-0x001f, 0x0000,
-0x0019, 0x0080,
-0x0019, 0x0080,
-0x001f, 0x0000,
-0x001e, 0x0000,
-0x001b, 0x0000,
-0x0019, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x06):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ***** |
- | |
- | ***** |
- | ** |
- | ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x003e, 0x0000,
-0x0000, 0x0000,
-0x000f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000f, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x07):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | **** |
- | ** ** |
- | ** ** |
- | **** |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x08):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | ******** |
- | ** |
- | ** |
- | |
- | ******** |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x09):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | ** ** |
- | *** ** |
- | ****** |
- | ****** |
- | ** *** |
- | ** ** |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ***** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0066, 0x0000,
-0x0076, 0x0000,
-0x007e, 0x0000,
-0x007e, 0x0000,
-0x006e, 0x0000,
-0x0066, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x0a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | **** |
- | ** |
- | ** |
- | |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x003c, 0x0000,
-0x003c, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0000, 0x0000,
-0x001f, 0x0080,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x0b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x00f8, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x0c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |***** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00f8, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x0d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ****** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000f, 0x00c0,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x0e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | ****** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x000f, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x0f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |********** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x00ff, 0x00c0,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x10):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- |********** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x00ff, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x11):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- |********** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x12):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |********** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x13):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |********** |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x14):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |********** |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x00c0,
-
-/* Character (0x15):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | ****** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x000f, 0x00c0,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x16):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |***** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x00f8, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x17):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- |********** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x00ff, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x18):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- |********** |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x00c0,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x19):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- | * |
- +----------------+ */
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-0x0008, 0x0000,
-
-/* Character (0x1a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | *** |
- |*** |
- | *** |
- | *** |
- | *** |
- | |
- | |
- |********* |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0003, 0x0080,
-0x000e, 0x0000,
-0x0038, 0x0000,
-0x00e0, 0x0000,
-0x0038, 0x0000,
-0x000e, 0x0000,
-0x0003, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x1b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- |*** |
- | *** |
- | *** |
- | *** |
- | *** |
- | *** |
- |*** |
- | |
- | |
- |********* |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00e0, 0x0000,
-0x0038, 0x0000,
-0x000e, 0x0000,
-0x0003, 0x0080,
-0x000e, 0x0000,
-0x0038, 0x0000,
-0x00e0, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x00ff, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x1c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ******** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x1d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ******** |
- | ** |
- | ** |
- | ******** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x007f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x1e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ***** |
- | * * ** ** |
- | *** *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000f, 0x0000,
-0x0019, 0x0080,
-0x0019, 0x0080,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x007e, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x007c, 0x0000,
-0x0056, 0x00c0,
-0x0073, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x1f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | *** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x20):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x21):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x22):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | * * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0012, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x23):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ******** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ******** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000d, 0x0080,
-0x000d, 0x0080,
-0x000d, 0x0080,
-0x003f, 0x00c0,
-0x001b, 0x0000,
-0x001b, 0x0000,
-0x001b, 0x0000,
-0x007f, 0x0080,
-0x0036, 0x0000,
-0x0036, 0x0000,
-0x0036, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x24):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ****** |
- | ** ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** ** |
- | ****** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x003f, 0x0000,
-0x006d, 0x0080,
-0x006c, 0x0000,
-0x006c, 0x0000,
-0x006c, 0x0000,
-0x003f, 0x0000,
-0x000d, 0x0080,
-0x000d, 0x0080,
-0x000d, 0x0080,
-0x006d, 0x0080,
-0x003f, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x25):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | *** ** |
- | ** ** ** |
- | ** **** |
- | *** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** *** |
- | **** ** |
- | ** ** ** |
- | ** *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0039, 0x0080,
-0x006d, 0x0080,
-0x006f, 0x0000,
-0x003b, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x001b, 0x0080,
-0x001e, 0x00c0,
-0x0036, 0x00c0,
-0x0033, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x26):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | *** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | ** |
- | *** |
- | ** ** |
- | ** ** ** |
- | ** *** |
- | ** ** |
- | *** **** |
- | **** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001c, 0x0000,
-0x0036, 0x0000,
-0x0036, 0x0000,
-0x0036, 0x0000,
-0x003c, 0x0000,
-0x0018, 0x0000,
-0x0038, 0x0000,
-0x006c, 0x0000,
-0x0066, 0x00c0,
-0x0063, 0x0080,
-0x0063, 0x0000,
-0x0077, 0x0080,
-0x003c, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x27):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | * |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0008, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x28):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0006, 0x0000,
-0x0003, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x29):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0030, 0x0000,
-0x0018, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x2a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | **** |
- | ******** |
- | **** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x007f, 0x0080,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x2b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ******** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x2c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | *** |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x001c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x2d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ******** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x2e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x2f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x30):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x31):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | *** |
- | **** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x001c, 0x0000,
-0x003c, 0x0000,
-0x006c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x32):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | *** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x000e, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x33):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | *** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x000e, 0x0000,
-0x0003, 0x0000,
-0x0001, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x34):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | * |
- | ** |
- | *** |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0001, 0x0000,
-0x0003, 0x0000,
-0x0007, 0x0000,
-0x000f, 0x0000,
-0x001b, 0x0000,
-0x0033, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x007f, 0x0080,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x35):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** *** |
- | *** ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x006e, 0x0000,
-0x0073, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x36):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** * |
- | ** |
- | ** |
- | ** *** |
- | *** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x006e, 0x0000,
-0x0073, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x37):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x38):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x39):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** *** |
- | *** ** |
- | ** |
- | ** |
- | * ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0080,
-0x001d, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0021, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x3a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x3b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | |
- | |
- | |
- | |
- | *** |
- | *** |
- | *** |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000e, 0x0000,
-0x000e, 0x0000,
-0x001c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x3c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | * |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | * |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0001, 0x0000,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0060, 0x0000,
-0x0030, 0x0000,
-0x0018, 0x0000,
-0x000c, 0x0000,
-0x0006, 0x0000,
-0x0003, 0x0000,
-0x0001, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x3d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ******** |
- | |
- | |
- | |
- | |
- | ******** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x3e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | * |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | * |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0020, 0x0000,
-0x0030, 0x0000,
-0x0018, 0x0000,
-0x000c, 0x0000,
-0x0006, 0x0000,
-0x0003, 0x0000,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0020, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x3f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x40):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** **** |
- | ** ***** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** **** |
- | ** ** |
- | ** |
- | ** ** |
- | ***** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0067, 0x0080,
-0x006f, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006f, 0x0000,
-0x0066, 0x0000,
-0x0060, 0x0000,
-0x0031, 0x0080,
-0x001f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x41):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ******** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x007f, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x42):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ***** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007c, 0x0000,
-0x0066, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0066, 0x0000,
-0x007e, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0063, 0x0000,
-0x007e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x43):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x44):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007e, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0063, 0x0000,
-0x007e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x45):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x007e, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x46):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x007e, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x47):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | ** **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** *** |
- | **** * |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0067, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0080,
-0x001e, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x48):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ******** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x007f, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x49):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x4a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000f, 0x00c0,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0036, 0x0000,
-0x001c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x4b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ***** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x007c, 0x0000,
-0x0066, 0x0000,
-0x0066, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x4c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x4d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | *** *** |
- | *** *** |
- | ******** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0073, 0x0080,
-0x0073, 0x0080,
-0x007f, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x4e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | *** ** |
- | *** ** |
- | **** ** |
- | **** ** |
- | ** ** ** |
- | ** ** ** |
- | ** **** |
- | ** **** |
- | ** *** |
- | ** *** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0071, 0x0080,
-0x0071, 0x0080,
-0x0079, 0x0080,
-0x0079, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x0067, 0x0080,
-0x0067, 0x0080,
-0x0063, 0x0080,
-0x0063, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x4f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x50):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007e, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0063, 0x0000,
-0x007e, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x51):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** ** |
- | ** **** |
- | ** ** |
- | ***** |
- | ** |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x006d, 0x0080,
-0x0067, 0x0080,
-0x0033, 0x0000,
-0x001f, 0x0000,
-0x0001, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x52):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007e, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0063, 0x0000,
-0x007e, 0x0000,
-0x0066, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x53):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0030, 0x0000,
-0x001e, 0x0000,
-0x0003, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x54):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x55):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x56):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | **** |
- | **** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x001e, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x57):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | *** *** |
- | *** *** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x0073, 0x0080,
-0x0073, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x58):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | **** |
- | ** |
- | **** |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x59):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x5a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ******** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x5b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ****** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003f, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x003f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x5c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0006, 0x0000,
-0x0006, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x5d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ****** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003f, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x0003, 0x0000,
-0x003f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x5e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | **** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x5f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ********* |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x007f, 0x00c0,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x60):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0018, 0x0000,
-0x000c, 0x0000,
-0x0006, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x61):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ***** |
- | ** ** |
- | ** |
- | ******* |
- | ** ** |
- | ** ** |
- | ** ** |
- | ***** * |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001f, 0x0000,
-0x0031, 0x0080,
-0x0001, 0x0080,
-0x003f, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x003e, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x62):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** *** |
- | *** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | *** ** |
- | ** *** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x006e, 0x0000,
-0x0073, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0073, 0x0000,
-0x006e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x63):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ***** |
- | ** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ***** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001f, 0x0000,
-0x0031, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0031, 0x0080,
-0x001f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x64):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | *** ** |
- | ** *** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** *** |
- | *** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x001d, 0x0080,
-0x0033, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0080,
-0x001d, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x65):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ******** |
- | ** |
- | ** |
- | ** ** |
- | ***** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x007f, 0x0080,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0031, 0x0080,
-0x001f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x66):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** |
- | ** |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000f, 0x0000,
-0x0019, 0x0080,
-0x0019, 0x0080,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x007e, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x67):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ***** * |
- | ** *** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ***** |
- | ** |
- | ****** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ****** |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003e, 0x0080,
-0x0063, 0x0080,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x0063, 0x0000,
-0x003e, 0x0000,
-0x0060, 0x0000,
-0x003f, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x003f, 0x0000,
-
-/* Character (0x68):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** *** |
- | *** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x006e, 0x0000,
-0x0073, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x69):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x003c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x6a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ***** |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0000, 0x0000,
-0x0007, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0031, 0x0080,
-0x0031, 0x0080,
-0x0031, 0x0080,
-0x001f, 0x0000,
-
-/* Character (0x6b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | ***** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0063, 0x0000,
-0x0066, 0x0000,
-0x006c, 0x0000,
-0x0078, 0x0000,
-0x007c, 0x0000,
-0x0066, 0x0000,
-0x0063, 0x0000,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x6c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x007f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x6d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | * ** ** |
- | ******** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x005b, 0x0000,
-0x007f, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x6e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** *** |
- | *** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x006e, 0x0000,
-0x0073, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x6f):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | **** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x70):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** *** |
- | *** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | *** ** |
- | ** *** |
- | ** |
- | ** |
- | ** |
- | ** |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x006e, 0x0000,
-0x0073, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0073, 0x0000,
-0x006e, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-0x0060, 0x0000,
-
-/* Character (0x71):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | *** ** |
- | ** *** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** *** |
- | *** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x001d, 0x0080,
-0x0033, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0080,
-0x001d, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0001, 0x0080,
-
-/* Character (0x72):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** **** |
- | *** ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x006f, 0x0000,
-0x0039, 0x0080,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0030, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x73):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ****** |
- | ** ** |
- | ** |
- | ****** |
- | ** |
- | ** |
- | ** ** |
- | ****** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003f, 0x0000,
-0x0061, 0x0080,
-0x0060, 0x0000,
-0x003f, 0x0000,
-0x0001, 0x0080,
-0x0001, 0x0080,
-0x0061, 0x0080,
-0x003f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x74):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ****** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x007e, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0018, 0x0000,
-0x0019, 0x0080,
-0x000f, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x75):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** *** |
- | *** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0080,
-0x001d, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x76):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | **** |
- | **** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x77):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** ** |
- | ** ** ** |
- | ** ** ** |
- | ******** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x006d, 0x0080,
-0x007f, 0x0080,
-0x0033, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x78):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | **** |
- | ** |
- | ** |
- | **** |
- | ** ** |
- | ** ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x001e, 0x0000,
-0x0033, 0x0000,
-0x0061, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x79):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** ** |
- | ** *** |
- | *** ** |
- | ** |
- | ** ** |
- | ** ** |
- | **** |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0080,
-0x001d, 0x0080,
-0x0001, 0x0080,
-0x0061, 0x0080,
-0x0033, 0x0000,
-0x001e, 0x0000,
-
-/* Character (0x7a):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | ******* |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ******* |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x003f, 0x0080,
-0x0001, 0x0080,
-0x0003, 0x0000,
-0x0006, 0x0000,
-0x000c, 0x0000,
-0x0018, 0x0000,
-0x0030, 0x0000,
-0x003f, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x7b):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0007, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0078, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0007, 0x0080,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x7c):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x7d):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | **** |
- | ** |
- | ** |
- | ** |
- | ** |
- | ** |
- | **** |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0078, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0007, 0x0080,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x000c, 0x0000,
-0x0078, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-
-/* Character (0x7e):
- bbw=10, bbh=20, bbx=0, bby=-4, width=10
- +----------------+
- | |
- | |
- | |
- | *** ** |
- | ** ** ** |
- | ** *** |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +----------------+ */
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0039, 0x0080,
-0x006d, 0x0080,
-0x0067, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-0x0000, 0x0000,
-};
-
-/* Exported structure definition. */
-Font font_10x20 = {
- font_10x20_glyphs,
- 10,
- 20
-};
+++ /dev/null
-/**
- * \file
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief General pourpose graphics routines
- */
-
-#ifndef GFX_GFX_H
-#define GFX_GFX_H
-
-#include <cfg/compiler.h>
-#include <cpu/attr.h> /* CPU_HARVARD */
-
-#include <appconfig.h> /* CONFIG_GFX_* */
-
-/**
- * \name Known pixel formats for bitmap representation.
- * \{
- */
-#define BITMAP_FMT_PLANAR_H_MSB 1 /**< Planar pixels, horizontal bytes, MSB left. */
-#define BITMAP_FMT_PLANAR_V_LSB 2 /**< Planar pixels, vertical bytes, LSB top. */
-/* \} */
-
-#if !defined(CONFIG_BITMAP_FMT) || (CONFIG_BITMAP_FMT != BITMAP_FMT_PLANAR_H_MSB && CONFIG_BITMAP_FMT != BITMAP_FMT_PLANAR_V_LSB)
- #error CONFIG_BITMAP_FMT must be defined to either BITMAP_FMT_PLANAR_H_LSB or BITMAP_FMT_PLANAR_V_LSB
-#endif
-#if !defined(CONFIG_GFX_CLIPPING) || (CONFIG_GFX_CLIPPING != 0 && CONFIG_GFX_CLIPPING != 1)
- #error CONFIG_GFX_CLIPPING must be defined to either 0 or 1
-#endif
-#if !defined(CONFIG_GFX_TEXT) || (CONFIG_GFX_TEXT != 0 && CONFIG_GFX_TEXT != 1)
- #error CONFIG_GFX_TEXT must be defined to either 0 or 1
-#endif
-
-EXTERN_C_BEGIN
-
-/** Common type for coordinates expressed in pixel units */
-typedef int coord_t;
-typedef unsigned int ucoord_t;
-
-#if CONFIG_GFX_VCOORDS
-/** Common type for coordinates expressed in logical units */
-typedef float vcoord_t;
-#endif /* CONFIG_GFX_VCOORDS */
-
-
-/**
- * Describe a rectangular area with coordinates expressed in pixels.
- *
- * The rectangle is represented in terms of its top/left and
- * right/bottom borders.
- *
- * In some cases, rectangles are assumed to obey to the
- * following invariants:
- *
- * xmin <= xmax
- * ymin <= ymax
- *
- * Oddly, the xmin and ymin coordinates are inclusive, while the
- * xmax and ymax coordinates are non-inclusive. This design
- * decision makes several computations simpler and lets you
- * specify empty (0x0) rectangles without breaking the
- * invariants.
- *
- * Computing the size of a rectangle can be done by simply
- * subtracting the maximum X or Y coordinate from the minimum
- * X or Y coordinate.
- */
-typedef struct Rect { coord_t xmin, ymin, xmax, ymax; } Rect;
-
-/**
- * Return the width of a rectangle in pixels.
- *
- * \note The argument \a r is evaluated twice.
- */
-#define RECT_WIDTH(r) ((r)->xmax - (r)->xmin)
-
-/**
- * Return the height of a rectangle in pixels.
- *
- * \note The argument \a r is evaluated twice.
- */
-#define RECT_HEIGHT(r) ((r)->ymax - (r)->ymin)
-
-/* Fwd decl */
-struct Font;
-
-/**
- * Control structure to draw in a bitmap
- *
- * \todo For better ortogonality, split this structure into
- * an Image and a plain drawing context called Painter.
- */
-typedef struct Bitmap
-{
- uint8_t *raster; /**< Pointer to byte array to hold the data */
- coord_t width, height; /**< Width/Height in pixels */
- coord_t stride; /**< Bytes per row. */
- coord_t penX, penY; /**< Current pen position MoveTo()/LineTo() */
-
-#if CONFIG_GFX_CLIPPING || CONFIG_GFX_VCOORDS
- Rect cr; /**< Clip drawing inside this rectangle */
-#endif
-
-#if CONFIG_GFX_TEXT
- const struct Font *font;/**< Current font for text rendering. */
-
- /**
- * Algorithmic text style flags.
- *
- * The text rendering routine can apply a few simple transformations
- * to the current font in order to generate common styles such as
- * bold, italic and underline from plain glyphs.
- *
- * \see text_style()
- */
- uint8_t styles;
-#endif /* CONFIG_GFX_TEXT */
-
-#if CONFIG_GFX_VCOORDS
- /**
- * \name Logical coordinate system
- * \{
- */
- vcoord_t orgX, orgY;
- vcoord_t scaleX, scaleY;
- /*\}*/
-#endif /* CONFIG_GFX_VCOORDS */
-
-} Bitmap;
-
-/**
- * Hold image pixels.
- *
- * \todo Use this as Bitmap and change Bitmap to Drawable.
- */
-typedef struct Image
-{
- const uint8_t *raster; /**< Pointer to byte array to hold the data. */
- coord_t width; /**< Raster width in pixels. */
- coord_t height; /**< Raster height in pixels. */
- coord_t stride; /**< Bytes per row. */
-} Image;
-
-#if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
- /**
- * Compute the size in bytes of a raster suitable for
- * holding a bitmap of \a width x \a height pixels.
- */
- #define RAST_SIZE(width, height) ( ((width) + 7 / 8) * (height) )
-
-#elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
- /**
- * Compute the size in bytes of a raster suitable for
- * holding a bitmap of \a width x \a height pixels.
- */
- #define RAST_SIZE(width, height) ( (width) * (((height) + 7) / 8) )
-#else
- #error Unknown value of CONFIG_BITMAP_FMT
-#endif /* CONFIG_BITMAP_FMT */
-
-/* Function prototypes */
-void gfx_bitmapInit (Bitmap *bm, uint8_t *raster, coord_t w, coord_t h);
-void gfx_bitmapClear(Bitmap *bm);
-void gfx_blit (Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy);
-void gfx_blitRaster (Bitmap *dst, coord_t dx, coord_t dy, const uint8_t *raster, coord_t w, coord_t h, coord_t stride);
-void gfx_blitImage (Bitmap *dst, coord_t dx, coord_t dy, const Image *image);
-void gfx_line (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
-void gfx_rectDraw (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
-void gfx_rectFillC (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t color);
-void gfx_rectFill (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
-void gfx_rectClear (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
-void gfx_moveTo (Bitmap *bm, coord_t x, coord_t y);
-void gfx_lineTo (Bitmap *bm, coord_t x, coord_t y);
-void gfx_setClipRect(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord_t ymax);
-
-#if CPU_HARVARD
- #include <mware/pgm.h>
- void gfx_blit_P(Bitmap *bm, const pgm_uint8_t *raster);
-#endif
-
-#if CONFIG_GFX_TEXT
-INLINE void gfx_setFont(Bitmap *bm, const struct Font *font)
-{
- bm->font = font;
-}
-#endif
-
-#if CONFIG_GFX_VCOORDS
-void gfx_setViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2);
-coord_t gfx_transformX(Bitmap *bm, vcoord_t x);
-coord_t gfx_transformY(Bitmap *bm, vcoord_t y);
-void gfx_vline(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2);
-#endif /* CONFIG_GFX_VCOORDS */
-
-EXTERN_C_END
-
-#endif /* GFX_GFX_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Graphics private header.
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2006/05/27 17:17:34 bernie
- *#* Optimize away divisions in RAST_ADDR/MASK macros.
- *#*
- *#* Revision 1.5 2006/05/25 23:35:40 bernie
- *#* Cleanup.
- *#*
- *#* Revision 1.4 2006/03/22 09:50:37 bernie
- *#* Use the same format for fonts and rasters.
- *#*
- *#* Revision 1.3 2006/02/15 09:10:15 bernie
- *#* Implement prop fonts; Fix algo styles.
- *#*
- *#* Revision 1.2 2006/02/10 12:28:33 bernie
- *#* Add font support in bitmaps; Make bitmap formats public.
- *#*
- *#* Revision 1.1 2006/01/26 00:32:49 bernie
- *#* Graphics private header.
- *#*
- *#*/
-
-#ifndef GFX_GFX_P_H
-#define GFX_GFX_P_H
-
-#include <gfx/gfx.h>
-
-#if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
-
- /* We use ucoord_t to let the compiler optimize away the division/modulo. */
- #define RAST_ADDR(raster, x, y, stride) \
- ((raster) + (ucoord_t)(y) * (ucoord_t)(stride) + (ucoord_t)(x) / 8)
- #define RAST_MASK(raster, x, y) \
- (1 << (7 - (ucoord_t)(x) % 8))
-
-#elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
-
- /* We use ucoord_t to let the compiler optimize away the division/modulo. */
- #define RAST_ADDR(raster, x, y, stride) \
- ((raster) + ((ucoord_t)(y) / 8) * (ucoord_t)(stride) + (ucoord_t)(x))
- #define RAST_MASK(raster, x, y) \
- (1 << ((ucoord_t)(y) % 8))
-
-#else
- #error Unknown value of CONFIG_BITMAP_FMT
-#endif /* CONFIG_BITMAP_FMT */
-
-#define BM_ADDR(bm, x, y) RAST_ADDR((bm)->raster, (x), (y), (bm)->stride)
-#define BM_MASK(bm, x, y) RAST_MASK((bm)->raster, (x), (y))
-
-/**
- * Plot a pixel in bitmap \a bm.
- *
- * \note bm is evaluated twice.
- * \see BM_CLEAR BM_DRAWPIXEL
- */
-#define BM_PLOT(bm, x, y) \
- ( *BM_ADDR(bm, x, y) |= BM_MASK(bm, x, y) )
-
-/**
- * Clear a pixel in bitmap \a bm.
- *
- * \note bm is evaluated twice.
- * \see BM_PLOT BM_DRAWPIXEL
- */
-#define BM_CLEAR(bm, x, y) \
- ( *BM_ADDR(bm, x, y) &= ~BM_MASK(bm, x, y) )
-
-/**
- * Set a pixel in bitmap \a bm to the specified color.
- *
- * \note bm is evaluated twice.
- * \note This macro is somewhat slower than BM_PLOT and BM_CLEAR.
- * \see BM_PLOT BM_CLEAR
- */
-#define BM_DRAWPIXEL(bm, x, y, fg_pen) \
- do { \
- uint8_t *p = BM_ADDR(bm, x, y); \
- uint8_t mask = BM_MASK(bm, x, y); \
- *p = (*p & ~mask) | ((fg_pen) ? mask : 0); \
- } while (0)
-
-/**
- * Get the value of the pixel in bitmap \a bm.
- *
- * \return The returned value is either 0 or 1.
- *
- * \note bm is evaluated twice.
- * \see BM_DRAWPIXEL
- */
-#define BM_READPIXEL(bm, x, y) \
- ( *BM_ADDR(bm, x, y) & BM_MASK(bm, x, y) ? 1 : 0 )
-
-#define RAST_READPIXEL(raster, x, y, stride) \
- ( *RAST_ADDR(raster, x, y, stride) & RAST_MASK(raster, x, y) ? 1 : 0 )
-
-#endif /* GFX_GFX_P_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Line drawing graphics routines
- */
-
-#include "gfx.h"
-#include "gfx_p.h"
-
-#include <cfg/debug.h> /* ASSERT() */
-#include <cfg/macros.h> /* SWAP() */
-#include <appconfig.h> /* CONFIG_GFX_CLIPPING */
-
-/* Configuration sanity checks */
-#if !defined(CONFIG_GFX_CLIPPING) || (CONFIG_GFX_CLIPPING != 0 && CONFIG_GFX_CLIPPING != 1)
- #error CONFIG_GFX_CLIPPING must be defined to either 0 or 1
-#endif
-#if !defined(CONFIG_GFX_VCOORDS) || (CONFIG_GFX_VCOORDS != 0 && CONFIG_GFX_VCOORDS != 1)
- #error CONFIG_GFX_VCOORDS must be defined to either 0 or 1
-#endif
-
-/**
- * Draw a sloped line without performing clipping.
- *
- * Parameters are the same of gfx_line().
- * This routine is based on the Bresenham Line-Drawing Algorithm.
- *
- * \note Passing coordinates outside the bitmap boundaries will
- * result in memory trashing.
- *
- * \todo Optimize for vertical and horiziontal lines.
- *
- * \sa gfx_line()
- */
-static void gfx_lineUnclipped(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
-{
- int x, y, e, len, adx, ady, signx, signy;
-
- if (x2 > x1)
- {
- /* left to right */
- signx = +1;
- adx = x2 - x1;
- }
- else
- {
- /* right to left */
- signx = -1;
- adx = x1 - x2;
- }
-
- if (y2 > y1)
- {
- /* top to bottom */
- signy = +1;
- ady = y2 - y1;
- }
- else
- {
- /* bottom to top */
- signy = -1;
- ady = y1 - y2;
- }
-
- x = x1;
- y = y1;
-
- if (adx > ady)
- {
- /* X-major line (octants 1/4/5/8) */
-
- len = adx;
- e = -adx;
- while (len--)
- {
- /* Sanity check */
- ASSERT((x >= 0) && (x < bm->width) && (y >= 0) && (y < bm->height));
- BM_PLOT(bm, x, y);
- x += signx;
- e += ady;
- if (e >= 0)
- {
- y += signy;
- e -= adx;
- }
- }
- }
- else
- {
- /* Y-major line (octants 2/3/6/7) */
-
- len = ady;
- e = -ady;
- while (len--)
- {
- /* Sanity check */
- ASSERT ((x >= 0) && (x < bm->width) && (y >= 0) && (y < bm->height));
- BM_PLOT(bm, x, y);
- y += signy;
- e += adx;
- if (e >= 0)
- {
- x += signx;
- e -= ady;
- }
- }
- }
-}
-
-#if CONFIG_GFX_CLIPPING
-
-/// Helper routine for gfx_line().
-static int gfx_findRegion(int x, int y, Rect *cr)
-{
- int code = 0;
-
- if (y >= cr->ymax)
- code |= 1; /* below */
- else if (y < cr->ymin)
- code |= 2; /* above */
-
- if (x >= cr->xmax)
- code |= 4; /* right */
- else if (x < cr->xmin)
- code |= 8; /* left */
-
- return code;
-}
-
-#endif /* CONFIG_CLIPPING */
-
-/**
- * Draw a sloped line segment.
- *
- * Draw a sloped line segment identified by the provided
- * start and end coordinates on the bitmap \a bm.
- *
- * The line endpoints are clipped inside the current bitmap
- * clipping rectangle using the Cohen-Sutherland algorithm,
- * which is very fast.
- *
- * \note The point at coordinates \a x2 \a y2 is not drawn.
- *
- * \note This function does \b not update the current pen position.
- *
- * \todo Compute updated Bresenham error term.
- */
-void gfx_line(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
-{
-#if CONFIG_GFX_CLIPPING
- int clip1 = gfx_findRegion(x1, y1, &bm->cr);
- int clip2 = gfx_findRegion(x2, y2, &bm->cr);
-
- /* Loop while there is at least one point outside */
- while (clip1 | clip2)
- {
- /* Check for line totally outside */
- if (clip1 & clip2)
- return;
-
- int c = clip1 ? clip1 : clip2;
- int x, y;
-
- if (c & 1) /* Below */
- {
- x = x1 + (x2 - x1) * (bm->cr.ymax - y1) / (y2 - y1);
- y = bm->cr.ymax - 1;
- }
- else if (c & 2) /* Above */
- {
- x = x1 + (x2 - x1) * (bm->cr.ymin - y1) / (y2 - y1);
- y = bm->cr.ymin;
- }
- else if (c & 4) /* Right */
- {
- y = y1 + (y2 - y1) * (bm->cr.xmax - x1) / (x2 - x1);
- x = bm->cr.xmax - 1;
- }
- else /* Left */
- {
- y = y1 + (y2 - y1) * (bm->cr.xmin - x1) / (x2 - x1);
- x = bm->cr.xmin;
- }
-
- if (c == clip1) /* First endpoint was clipped */
- {
- // TODO: adjust Bresenham error term
- //coord_t clipdx = ABS(x - x1);
- //coord_t clipdy = ABS(y - y1);
- //e += (clipdy * e2) + ((clipdx - clipdy) * e1);
-
- x1 = x;
- y1 = y;
- clip1 = gfx_findRegion(x1, y1, &bm->cr);
- }
- else /* Second endpoint was clipped */
- {
- x2 = x;
- y2 = y;
- clip2 = gfx_findRegion(x2, y2, &bm->cr);
- }
- }
-#endif /* CONFIG_GFX_CLIPPING */
-
- gfx_lineUnclipped(bm, x1, y1, x2, y2);
-}
-
-/**
- * Move the current pen position to the specified coordinates.
- *
- * The pen position is used for drawing operations such as
- * gfx_lineTo(), which can be used to draw polygons.
- */
-void gfx_moveTo(Bitmap *bm, coord_t x, coord_t y)
-{
- bm->penX = x;
- bm->penY = y;
-}
-
-/**
- * Draw a line from the current pen position to the new coordinates.
- *
- * \note This function moves the current pen position to the
- * new coordinates.
- *
- * \sa gfx_line()
- */
-void gfx_lineTo(Bitmap *bm, coord_t x, coord_t y)
-{
- gfx_line(bm, bm->penX, bm->penY, x, y);
- gfx_moveTo(bm, x, y);
-}
-
-
-/**
- * Draw the perimeter of an hollow rectangle.
- *
- * \note The bottom-right corner of the rectangle is drawn at (x2-1;y2-1).
- * \note This function does \b not update the current pen position.
- */
-void gfx_rectDraw(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
-{
- /* Sort coords (needed for correct bottom-right semantics) */
- if (x1 > x2) SWAP(x1, x2);
- if (y1 > y2) SWAP(y1, y2);
-
- /* Draw rectangle */
- gfx_line(bm, x1, y1, x2-1, y1);
- gfx_line(bm, x2-1, y1, x2-1, y2-1);
- gfx_line(bm, x2-1, y2-1, x1, y2-1);
- gfx_line(bm, x1, y2-1, x1, y1);
-}
-
-
-/**
- * Fill a rectangular area with \a color.
- *
- * \note The bottom-right border of the rectangle is not drawn.
- *
- * \note This function does \b not update the current pen position.
- */
-void gfx_rectFillC(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t color)
-{
- coord_t x, y;
-
- /* Sort coords */
- if (x1 > x2) SWAP(x1, x2);
- if (y1 > y2) SWAP(y1, y2);
-
-#if CONFIG_GFX_CLIPPING
- /* Clip rect to bitmap clip region */
- if (x1 < bm->cr.xmin) x1 = bm->cr.xmin;
- if (x2 < bm->cr.xmin) x2 = bm->cr.xmin;
- if (x1 > bm->cr.xmax) x1 = bm->cr.xmax;
- if (x2 > bm->cr.xmax) x2 = bm->cr.xmax;
- if (y1 < bm->cr.ymin) y1 = bm->cr.ymin;
- if (y2 < bm->cr.ymin) y2 = bm->cr.ymin;
- if (y1 > bm->cr.ymax) y1 = bm->cr.ymax;
- if (y2 > bm->cr.ymax) y2 = bm->cr.ymax;
-#endif /* CONFIG_GFX_CLIPPING */
-
- /* NOTE: Code paths are duplicated for efficiency */
- if (color) /* fill */
- {
- for (x = x1; x < x2; x++)
- for (y = y1; y < y2; y++)
- BM_PLOT(bm, x, y);
- }
- else /* clear */
- {
- for (x = x1; x < x2; x++)
- for (y = y1; y < y2; y++)
- BM_CLEAR(bm, x, y);
- }
-}
-
-
-/**
- * Draw a filled rectangle.
- *
- * \note The bottom-right border of the rectangle is not drawn.
- *
- * \note This function does \b not update the current pen position.
- */
-void gfx_rectFill(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
-{
- gfx_rectFillC(bm, x1, y1, x2, y2, 0xFF);
-}
-
-
-/**
- * Clear a rectangular area.
- *
- * \note The bottom-right border of the rectangle is not cleared.
- *
- * \note This function does \b not update the current pen position.
- */
-void gfx_rectClear(Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2)
-{
- gfx_rectFillC(bm, x1, y1, x2, y2, 0x00);
-}
-
-
-#if CONFIG_GFX_VCOORDS
-/**
- * Imposta gli estremi del sistema di coordinate cartesiane rispetto
- * al rettangolo di clipping della bitmap.
- */
-void gfx_setViewRect(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2)
-{
- ASSERT(x1 != x2);
- ASSERT(y1 != y2);
-
- bm->orgX = x1;
- bm->orgY = y1;
- bm->scaleX = (vcoord_t)(bm->cr.xmax - bm->cr.xmin - 1) / (vcoord_t)(x2 - x1);
- bm->scaleY = (vcoord_t)(bm->cr.ymax - bm->cr.ymin - 1) / (vcoord_t)(y2 - y1);
-
-/* DB(kprintf("orgX = %f, orgY = %f, scaleX = %f, scaleY = %f\n",
- bm->orgX, bm->orgY, bm->scaleX, bm->scaleY);)
-*/
-}
-
-
-/**
- * Transform a coordinate from the current reference system to a
- * pixel offset within the bitmap.
- */
-coord_t gfx_transformX(Bitmap *bm, vcoord_t x)
-{
- return bm->cr.xmin + (coord_t)((x - bm->orgX) * bm->scaleX);
-}
-
-/**
- * Transform a coordinate from the current reference system to a
- * pixel offset within the bitmap.
- */
-coord_t gfx_transformY(Bitmap *bm, vcoord_t y)
-{
- return bm->cr.ymin + (coord_t)((y - bm->orgY) * bm->scaleY);
-}
-
-
-/**
- * Draw a line from (x1;y1) to (x2;y2).
- */
-void gfx_vline(Bitmap *bm, vcoord_t x1, vcoord_t y1, vcoord_t x2, vcoord_t y2)
-{
- gfx_line(bm,
- gfx_transformX(bm, x1), gfx_transformY(bm, y1),
- gfx_transformY(bm, x2), gfx_transformY(bm, y2));
-}
-#endif /* CONFIG_GFX_VCOORDS */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Text graphic routines
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.13 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.12 2006/05/25 23:35:22 bernie
- *#* Implement correct and faster clipping for algo text.
- *#*
- *#* Revision 1.11 2006/05/15 07:21:06 bernie
- *#* Doxygen fix.
- *#*
- *#* Revision 1.10 2006/04/27 05:39:23 bernie
- *#* Enhance text rendering to arbitrary x,y coords.
- *#*
- *#* Revision 1.9 2006/04/11 00:08:24 bernie
- *#* text_offset(): New function, but I'm not quite confident with the design.
- *#*
- *#* Revision 1.8 2006/03/22 09:50:37 bernie
- *#* Use the same format for fonts and rasters.
- *#*
- *#* Revision 1.7 2006/03/20 17:51:55 bernie
- *#* Cleanups.
- *#*
- *#* Revision 1.6 2006/03/13 02:05:54 bernie
- *#* Mark slow paths as UNLIKELY.
- *#*
- *#* Revision 1.5 2006/03/07 22:18:04 bernie
- *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute.
- *#*
- *#* Revision 1.4 2006/02/15 09:10:15 bernie
- *#* Implement prop fonts; Fix algo styles.
- *#*
- *#* Revision 1.3 2006/02/10 12:31:55 bernie
- *#* Add multiple font support in bitmaps.
- *#*
- *#* Revision 1.2 2005/11/04 18:17:45 bernie
- *#* Fix header guards and includes for new location of gfx module.
- *#*
- *#* Revision 1.1 2005/11/04 18:11:35 bernie
- *#* Move graphics stuff from mware/ to gfx/.
- *#*
- *#* Revision 1.13 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.12 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.11 2005/01/20 18:46:31 aleph
- *#* Fix progmem includes.
- *#*
- *#* Revision 1.10 2005/01/08 09:20:12 bernie
- *#* Really make it work on both architectures.
- *#*
- *#* Revision 1.9 2004/12/31 16:44:29 bernie
- *#* Sanitize for non-Harvard processors.
- *#*
- *#* Revision 1.8 2004/11/16 21:16:28 bernie
- *#* Update to new naming scheme in mware/gfx.c.
- *#*
- *#* Revision 1.7 2004/09/20 03:28:28 bernie
- *#* Fix header.
- *#*
- *#* Revision 1.6 2004/09/14 20:57:15 bernie
- *#* Use debug.h instead of kdebug.h.
- *#*
- *#* Revision 1.5 2004/09/06 21:51:26 bernie
- *#* Extend interface to allow any algorithmic style.
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 15:43:16 bernie
- *#* Import mware modules.
- *#*
- *#* Revision 1.17 2004/05/15 16:57:01 aleph
- *#* Fixes for non-DEBUG build
- *#*
- *#* Revision 1.16 2004/04/03 20:42:49 aleph
- *#* Add text_clear()
- *#*
- *#* Revision 1.15 2004/03/24 15:03:45 bernie
- *#* Use explicit include paths; clean Doxygen comments
- *#*
- *#* Revision 1.14 2004/03/19 16:52:28 bernie
- *#* Move printf() like functions from text.c to text_format.c and add PROGMEM versions.
- *#*
- *#* Revision 1.13 2004/03/17 18:23:32 bernie
- *#* Oops.
- *#*
- *#* Revision 1.12 2004/03/17 18:03:22 bernie
- *#* Make diagnostic message shorter
- *#*
- *#* Revision 1.11 2004/03/13 22:52:54 aleph
- *#* documentation fixes
- *#*/
-
-#include <gfx/gfx.h>
-#include <gfx/font.h>
-#include <gfx/text.h>
-#include <gfx/text.h>
-
-#include <gfx/gfx_p.h> // FIXME: BM_DRAWPIXEL
-
-#include <cfg/debug.h>
-
-
-/**
- * ANSI escape sequences flag: true for ESC state on.
- *
- * \todo Move to Bitmap.flags.
- */
-static bool ansi_mode = false;
-
-/**
- * Move (imaginary) cursor to coordinates specified.
- */
-void text_setCoord(struct Bitmap *bm, int x, int y)
-{
- bm->penX = x;
- bm->penY = y;
-}
-
-
-/**
- * Move (imaginary) cursor to column and row specified.
- * Next text write will start a that row and col.
- */
-void text_moveTo(struct Bitmap *bm, int row, int col)
-{
- ASSERT(col >= 0);
- ASSERT(col < bm->width / bm->font->width);
- ASSERT(row >= 0);
- ASSERT(row < bm->height / bm->font->height);
-
- text_setCoord(bm, col * bm->font->width, row * bm->font->height);
-}
-
-
-/**
- * Render char \a c on Bitmap \a bm.
- */
-static int text_putglyph(char c, struct Bitmap *bm)
-{
- const uint8_t * PROGMEM glyph; /* font is in progmem */
- uint8_t glyph_width, glyph_height, glyph_height_bytes;
- unsigned char index = (unsigned char)c;
-
- /* Check for out of range char and replace with '?' or first char in font. */
- if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
- {
- kprintf("Illegal char '%c' (0x%02x)\n", index, index);
- if (FONT_HAS_GLYPH(bm->font, '?'))
- index = '?';
- else
- index = bm->font->first;
- }
-
- /* Make character relative to font start */
- index -= bm->font->first;
-
- glyph_height = bm->font->height;
- // FIXME: for vertical fonts only
- glyph_height_bytes = (glyph_height + 7) / 8;
-
- if (bm->font->offset)
- {
- /* Proportional font */
- glyph_width = bm->font->widths[index]; /* TODO: optimize away */
- glyph = bm->font->glyph + bm->font->offset[index];
- }
- else
- {
- /*
- * Fixed-width font: compute the first column of pixels
- * of the selected glyph using the character code to index
- * the glyph array.
- */
- glyph_width = bm->font->width;
-
- //For horizontal fonts
- //glyph = bm->font->glyph + index * (((glyph_width + 7) / 8) * glyph_height);
- glyph = bm->font->glyph + index * glyph_height_bytes * glyph_width;
- }
-
- /* Slow path for styled glyphs */
- if (UNLIKELY(bm->styles))
- {
- uint8_t styles = bm->styles;
- uint8_t prev_dots = 0, italic_prev_dots = 0;
- uint8_t dots;
- uint8_t row, col, row_bit;
-
- /*
- * To avoid repeating clipping and other expensive computations,
- * we cluster calls to gfx_blitRaster() using a small buffer.
- */
- #define CONFIG_TEXT_RENDER_OPTIMIZE 1
- #if CONFIG_TEXT_RENDER_OPTIMIZE
- #define RENDER_BUF_WIDTH 12
- #define RENDER_BUF_HEIGHT 8
- uint8_t render_buf[RAST_SIZE(RENDER_BUF_WIDTH, RENDER_BUF_HEIGHT)];
- uint8_t render_xpos = 0;
- #endif
-
- /* This style alone could be handled by the fast path too */
- if (bm->styles & STYLEF_CONDENSED)
- --glyph_width;
-
- if (bm->styles & STYLEF_EXPANDED)
- glyph_width *= 2;
-
- for (row = 0, row_bit = 0; row < glyph_height_bytes; ++row, row_bit += 8)
- {
- /* For each dot column in the glyph... */
- for (col = 0; col < glyph_width; ++col)
- {
- uint8_t src_col = col;
-
- /* Expanded style: advances only once every two columns. */
- if (styles & STYLEF_EXPANDED)
- src_col /= 2;
-
- /* Fetch a column of dots from glyph. */
- dots = PGM_READ_CHAR(RAST_ADDR(glyph, src_col, row_bit, glyph_width));
-
- /* Italic: get lower 4 dots from previous column */
- if (styles & STYLEF_ITALIC)
- {
- uint8_t new_dots = dots;
- dots = (dots & 0xF0) | italic_prev_dots;
- italic_prev_dots = new_dots & 0x0F;
- }
-
- /* Bold: "or" pixels with the previous column */
- if (styles & STYLEF_BOLD)
- {
- uint8_t new_dots = dots;
- dots |= prev_dots;
- prev_dots = new_dots;
- }
-
- /* Underlined: turn on base pixel */
- if ((styles & STYLEF_UNDERLINE)
- && (row == glyph_height_bytes - 1))
- dots |= (1 << (glyph_height - row_bit - 1));
-
- /* Inverted: invert pixels */
- if (styles & STYLEF_INVERT)
- dots = ~dots;
-
- /* Output dots */
- #if CONFIG_TEXT_RENDER_OPTIMIZE
- render_buf[render_xpos++] = dots;
- if (render_xpos == RENDER_BUF_WIDTH)
- {
- gfx_blitRaster(bm, bm->penX + col - render_xpos + 1, bm->penY + row_bit,
- render_buf, render_xpos,
- MIN((uint8_t)RENDER_BUF_HEIGHT, (uint8_t)(glyph_height - row_bit)),
- RENDER_BUF_WIDTH);
- render_xpos = 0;
- }
- #else
- gfx_blitRaster(bm, bm->penX + col, bm->penY + row_bit,
- &dots, 1, MIN((uint8_t)8, glyph_height - row_bit), 1);
- #endif
- }
-
- #if CONFIG_TEXT_RENDER_OPTIMIZE
- /* Flush out rest of render buffer */
- if (render_xpos != 0)
- {
- gfx_blitRaster(bm, bm->penX + col - render_xpos, bm->penY + row_bit,
- render_buf, render_xpos,
- MIN((uint8_t)RENDER_BUF_HEIGHT, (uint8_t)(glyph_height - row_bit)),
- RENDER_BUF_WIDTH);
- render_xpos = 0;
- }
- #endif
- }
- }
- else
- {
- /* No style: fast vanilla copy of glyph to bitmap */
- gfx_blitRaster(bm, bm->penX, bm->penY, glyph, glyph_width, glyph_height, glyph_width);
- }
-
- /* Update current pen position */
- bm->penX += glyph_width;
-
- return c;
-}
-
-
-/**
- * Render char \c c, with (currently) limited ANSI escapes
- * emulation support and '\n' for newline.
- */
-int text_putchar(char c, struct Bitmap *bm)
-{
- /* Handle ANSI escape sequences */
- if (UNLIKELY(ansi_mode))
- {
- switch (c)
- {
- case ANSI_ESC_CLEARSCREEN:
- gfx_bitmapClear(bm);
- bm->penX = 0;
- bm->penY = 0;
- text_style(bm, 0, STYLEF_MASK);
- break;
- DB(default:
- kprintf("Unknown ANSI esc code: %x\n", c);)
- }
- ansi_mode = false;
- }
- else if (c == '\033') /* Enter ANSI ESC mode */
- {
- ansi_mode = true;
- }
- else if (c == '\n') /* Go one line down on a line-feed */
- {
- if (bm->penY + bm->font->height < bm->height)
- {
- bm->penY += bm->font->height;
- bm->penX = 0;
- }
- }
- else
- {
- text_putglyph(c, bm);
- }
- return c;
-}
-
-
-/**
- * Clear the screen and reset cursor position
- */
-void text_clear(struct Bitmap *bmp)
-{
- text_putchar('\x1b', bmp);
- text_putchar('c', bmp);
-}
-
-
-void text_clearLine(struct Bitmap *bm, int line)
-{
- gfx_rectClear(bm, 0, line * bm->font->height, bm->width, (line + 1) * bm->font->height);
-}
-
-
-/**
- * Set/clear algorithmic font style bits.
- *
- * \param bm Pointer to Bitmap to affect.
- * \param flags Style flags to set
- * \param mask Mask of flags to modify
- * \return Old style flags
- *
- * Examples:
- * Turn on bold, leave other styles alone
- * \code text_style(bm, STYLEF_BOLD, STYLEF_BOLD); \endcode
- *
- * Turn off bold and turn on italic, leave others as they are
- * \code text_style(bm, STYLEF_ITALIC, STYLEF_BOLD | STYLEF_ITALIC); \endcode
- *
- * Query current style without chaning it
- * \code style = text_style(bm, 0, 0); \endcode
- *
- * Reset all styles (plain text)
- * \code text_style(bm, 0, STYLE_MASK); \endcode
- */
-uint8_t text_style(struct Bitmap *bm, uint8_t flags, uint8_t mask)
-{
- uint8_t old = bm->styles;
- bm->styles = (bm->styles & ~mask) | flags;
- return old;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Text graphic routines (interface)
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- * \version $Id$
- */
-
-#ifndef GFX_TEXT_H
-#define GFX_TEXT_H
-
-#include <cfg/compiler.h>
-#include <cfg/macros.h> /* BV() */
-#include <cpu/attr.h> /* CPU_HARVARD */
-#include <gfx/gfx.h> /* coord_t */
-
-#include <stdarg.h>
-
-/**
- * \name Style flags
- * \see text_style()
- * \{
- */
-#define STYLEF_BOLD BV(0)
-#define STYLEF_ITALIC BV(1)
-#define STYLEF_UNDERLINE BV(2)
-#define STYLEF_INVERT BV(3)
-#define STYLEF_EXPANDED BV(4)
-#define STYLEF_CONDENSED BV(5)
-#define STYLEF_STRIKEOUT BV(6) /*<! Not implemented */
-#define STYLEF_TALL BV(7) /*<! Not implemented */
-
-#define STYLEF_MASK \
- (STYLEF_BOLD | STYLEF_ITALIC | STYLEF_UNDERLINE \
- | STYLEF_INVERT | STYLEF_EXPANDED | STYLEF_CONDENSED \
- | STYLEF_STRIKEOUT | STYLEF_TALL)
-/*\}*/
-
-/**
- * \name Formatting flags for text rendering
- * \see text_xprintf()
- * \{
- */
-#define TEXT_NORMAL 0 /**< Normal mode */
-#define TEXT_FILL BV(13) /**< Fill rest of line with spaces */
-#define TEXT_CENTER BV(14) /**< Center string in line */
-#define TEXT_RIGHT BV(15) /**< Right aligned */
-/*\}*/
-
-/** Escape sequences codes */
-#define ANSI_ESC_CLEARSCREEN 'c'
-
-
-/* Fwd decl */
-struct Bitmap;
-
-/* Low-level text functions (mware/text.c) */
-void text_moveTo(struct Bitmap *bm, int row, int col);
-void text_setCoord(struct Bitmap *bm, int x, int y);
-int text_putchar(char c, struct Bitmap *bm);
-uint8_t text_style(struct Bitmap *bm, uint8_t flags, uint8_t mask);
-void text_clear(struct Bitmap *bm);
-void text_clearLine(struct Bitmap *bm, int line);
-
-/* Text formatting functions (mware/text_format.c) */
-int text_puts(const char *str, struct Bitmap *bm);
-int text_vprintf(struct Bitmap *bm, const char *fmt, va_list ap);
-int text_printf(struct Bitmap *bm, const char *fmt, ...) FORMAT(__printf__, 2, 3);
-int text_xyvprintf(struct Bitmap *bm, coord_t x, coord_t y, uint16_t mode, const char *fmt, va_list ap);
-int text_xyprintf(struct Bitmap *bm, coord_t x, coord_t col, uint16_t mode, const char *fmt, ...) FORMAT(__printf__, 5, 6);
-int text_xprintf(struct Bitmap *bm, uint8_t row, uint8_t col, uint16_t mode, const char *fmt, ...) FORMAT(__printf__, 5, 6);
-int text_vwidthf(struct Bitmap *bm, const char * fmt, va_list ap);
-int text_widthf(struct Bitmap *bm, const char * fmt, ...) FORMAT(__printf__, 2, 3);
-
-/* Text formatting functions for program-memory strings (mware/text_format.c) */
-#if CPU_HARVARD
-#include <mware/pgm.h>
-int text_puts_P(const char * PROGMEM str, struct Bitmap *bm);
-int text_vprintf_P(struct Bitmap *bm, const char * PROGMEM fmt, va_list ap);
-int text_printf_P(struct Bitmap *bm, const char * PROGMEM fmt, ...) FORMAT(__printf__, 2, 3);
-int text_xprintf_P(struct Bitmap *bm, uint8_t row, uint8_t col, uint16_t mode, const char * PROGMEM fmt, ...) FORMAT(__printf__, 5, 6);
-int text_vwidthf_P(struct Bitmap *bm, const char * PROGMEM fmt, va_list ap);
-int text_widthf_P(struct Bitmap *bm, const char * PROGMEM fmt, ...);
-#endif /* CPU_HARVARD */
-
-#endif /* GFX_TEXT_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief printf-family routines for text output
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.10 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.9 2006/04/27 05:39:24 bernie
- *#* Enhance text rendering to arbitrary x,y coords.
- *#*
- *#* Revision 1.8 2006/03/22 09:50:11 bernie
- *#* Don't use C99 stuff.
- *#*
- *#* Revision 1.7 2006/03/20 17:51:55 bernie
- *#* Cleanups.
- *#*
- *#* Revision 1.6 2006/03/13 02:05:54 bernie
- *#* Mark slow paths as UNLIKELY.
- *#*
- *#* Revision 1.5 2006/03/07 22:18:04 bernie
- *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute.
- *#*
- *#* Revision 1.4 2006/02/10 12:31:33 bernie
- *#* Add multiple font support in bitmaps.
- *#*
- *#* Revision 1.3 2005/11/27 23:31:58 bernie
- *#* Reorder includes.
- *#*
- *#* Revision 1.2 2005/11/04 18:17:45 bernie
- *#* Fix header guards and includes for new location of gfx module.
- *#*
- *#* Revision 1.1 2005/11/04 18:11:35 bernie
- *#* Move graphics stuff from mware/ to gfx/.
- *#*
- *#* Revision 1.10 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.9 2004/12/31 17:47:45 bernie
- *#* Rename UNUSED() to UNUSED_ARG().
- *#*
- *#* Revision 1.8 2004/11/16 21:16:56 bernie
- *#* Update to new naming scheme in mware/gfx.c.
- *#*
- *#* Revision 1.7 2004/10/03 19:05:04 bernie
- *#* text_widthf(), text_vwidthf(): New functions.
- *#*
- *#* Revision 1.6 2004/09/14 20:59:04 bernie
- *#* text_xprintf(): Support all styles; Pixel-wise text centering.
- *#*
- *#* Revision 1.5 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.4 2004/08/05 18:46:44 bernie
- *#* Documentation improvements.
- *#*
- *#* Revision 1.3 2004/08/03 15:57:18 aleph
- *#* Add include to fix warning for vsprintf()
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 15:43:16 bernie
- *#* Import mware modules.
- *#*
- *#* Revision 1.2 2004/03/26 18:50:50 bernie
- *#* Move _PROGMEM stuff to compiler.h
- *#*
- *#* Revision 1.1 2004/03/19 16:52:28 bernie
- *#* Move printf() like functions from text.c to text_format.c and add PROGMEM versions.
- *#*
- *#*/
-
-#include "text.h"
-
-#include <mware/formatwr.h> /* _formatted_write() */
-#include <gfx/font.h>
-#include <gfx/gfx.h>
-
-#include <stdio.h> /* vsprintf() */
-#include <stdarg.h>
-#include <string.h> /* strlen() */
-
-/**
- * Render string \a str in Bitmap \a bm at current cursor position
- *
- * \note Text formatting functions are also available with an _P suffix
- * accepting the source string from program memory. This feature
- * is only available (and useful) on Harvard microprocessors such
- * as the AVR.
- *
- * \see text_putchar()
- */
-int PGM_FUNC(text_puts)(const char * PGM_ATTR str, struct Bitmap *bm)
-{
- char c;
-
- while ((c = PGM_READ_CHAR(str++)))
- text_putchar(c, bm);
-
- return 0;
-}
-
-
-/**
- * vprintf()-like formatter to render text in a Bitmap.
- *
- * Perform vprintf()-like formatting on the \a fmt format string using the
- * variable-argument list \a ap.
- * Render the resulting string in Bitmap \a bm starting at the current
- * cursor position.
- *
- * \see text_puts() text_putchar() text_printf()
- */
-int PGM_FUNC(text_vprintf)(struct Bitmap *bm, const char * PGM_ATTR fmt, va_list ap)
-{
- return PGM_FUNC(_formatted_write)(fmt, (void (*)(char, void *))text_putchar, bm, ap);
-}
-
-/**
- * printf()-like formatter to render text in a Bitmap.
- *
- * Perform printf()-like formatting on the \a fmt format string.
- * Render the resulting string in Bitmap \a bm starting at the
- * current cursor position.
- *
- * \see text_puts() text_putchar() text_vprintf()
- */
-int PGM_FUNC(text_printf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
-{
- int len;
-
- va_list ap;
- va_start(ap, fmt);
- len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
- va_end(ap);
-
- return len;
-}
-
-/**
- * Render text with vprintf()-like formatting at a specified pixel position.
- *
- * \see text_xyprintf()
- */
-int PGM_FUNC(text_xyvprintf)(struct Bitmap *bm,
- coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, va_list ap)
-{
- int len;
- uint8_t oldstyle = 0;
-
- text_setCoord(bm, x, y);
-
- if (style & STYLEF_MASK)
- oldstyle = text_style(bm, style, STYLEF_MASK);
-
- if (style & (TEXT_CENTER | TEXT_RIGHT))
- {
- uint8_t pad = bm->width - PGM_FUNC(text_vwidthf)(bm, fmt, ap);
-
- if (style & TEXT_CENTER)
- pad /= 2;
-
- if (style & TEXT_FILL)
- gfx_rectFillC(bm, 0, y, pad, y + bm->font->height,
- (style & STYLEF_INVERT) ? 0xFF : 0x00);
-
- text_setCoord(bm, pad, y);
- }
-
- len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
-
- if (style & TEXT_FILL)
- gfx_rectFillC(bm, bm->penX, y, bm->width, y + bm->font->height,
- (style & STYLEF_INVERT) ? 0xFF : 0x00);
-
- /* Restore old style */
- if (style & STYLEF_MASK)
- text_style(bm, oldstyle, STYLEF_MASK);
-
- return len;
-}
-
-
-/**
- * Render text with printf()-like formatting at a specified pixel position.
- *
- * \param bm Bitmap where to render the text
- * \param x [pixels] Initial X coordinate of text.
- * \param y [pixels] Coordinate of top border of text.
- * \param style Formatting style to use. In addition to any STYLEF_
- * flag, it can be TEXT_NORMAL, TEXT_FILL, TEXT_INVERT or
- * TEXT_RIGHT, or a combination of these flags ORed together.
- * \param fmt String possibly containing printf() formatting commands.
- *
- * \see text_puts() text_putchar() text_printf() text_vprintf()
- * \see text_moveTo() text_style()
- */
-int PGM_FUNC(text_xyprintf)(struct Bitmap *bm,
- coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, ...)
-{
- int len;
- va_list ap;
-
- va_start(ap, fmt);
- len = PGM_FUNC(text_xyvprintf)(bm, x, y, style, fmt, ap);
- va_end(ap);
-
- return len;
-}
-
-
-/**
- * Render text with printf()-like formatting at a specified row/column position.
- *
- * \see text_xyprintf()
- */
-int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
- uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
-{
- int len;
- va_list ap;
-
- va_start(ap, fmt);
- len = PGM_FUNC(text_xyvprintf)(
- bm, col * bm->font->width, row * bm->font->height,
- style, fmt, ap);
- va_end(ap);
-
- return len;
-}
-
-
-struct TextWidthData
-{
- Bitmap *bitmap;
- coord_t width;
-};
-
-/**
- * Compute width in pixels of a character.
- *
- * Compute the on screen width of a character, taking the
- * current style and font into account.
- *
- * The width is accumulated in the WidthData structure
- * passed as second argument.
- *
- * This is a formatted_write() callback used by text_vwidthf()
- * to compute the length of a formatted string.
- */
-static int text_charWidth(int c, struct TextWidthData *twd)
-{
- unsigned char index = (unsigned char)c;
- Bitmap *bm = twd->bitmap;
- coord_t glyph_width;
-
-
- if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
- {
- if (!FONT_HAS_GLYPH(bm->font, '?'))
- index = '?';
- else
- index = bm->font->first;
- }
-
- /* Make character relative to font start */
- index -= bm->font->first;
-
- if (bm->font->offset)
- /* Proportional font */
- glyph_width = bm->font->widths[index]; /* TODO: optimize away */
- else
- /* Fixed width font */
- glyph_width = bm->font->width;
-
- if (bm->styles & STYLEF_CONDENSED)
- --glyph_width;
-
- if (bm->styles & STYLEF_EXPANDED)
- glyph_width *= 2;
-
- twd->width += glyph_width;
-
- return c;
-}
-
-/**
- * Return the width in pixels of a vprintf()-formatted string.
- */
-int PGM_FUNC(text_vwidthf)(
- UNUSED_ARG(struct Bitmap *, bm),
- const char * PGM_ATTR fmt,
- va_list ap)
-{
- /* Fixed font with no styles affecting the width? */
- if (!bm->font->offset && !(bm->styles & (STYLEF_CONDENSED | STYLEF_EXPANDED)))
- return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width;
- else
- {
- struct TextWidthData twd;
- twd.bitmap = bm;
- twd.width = 0;
- _formatted_write(fmt, (void (*)(char, void *))text_charWidth, &twd, ap);
- return twd.width;
- }
-}
-
-
-/**
- * Return the width in pixels of a printf()-formatted string.
- */
-int PGM_FUNC(text_widthf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
-{
- int width;
-
- va_list ap;
- va_start(ap, fmt);
- width = PGM_FUNC(text_vwidthf)(bm, fmt, ap);
- va_end(ap);
-
- return width;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Very simple hierarchical windowing system.
- *
- * All functions in this module are to be intended as methods
- * of the Window class. Please see its documentation
- * for a module-wise introduction.
- *
- * \see struct Window
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/08/01 17:26:04 batt
- *#* Update docs.
- *#*
- *#* Revision 1.1 2006/08/01 15:43:01 batt
- *#* Add in board_kd current edited channel visualization.
- *#*
- *#* Revision 1.4 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.3 2006/02/10 12:25:41 bernie
- *#* Add missing header.
- *#*
- *#* Revision 1.2 2006/01/26 00:36:48 bernie
- *#* Const correctness for some new functions.
- *#*
- *#* Revision 1.1 2006/01/23 23:14:29 bernie
- *#* Implement simple, but impressive windowing system.
- *#*
- *#*/
-
-#include "win.h"
-#include <mware/list.h>
-
-/**
- * Map the contents of all child-windows into the bitmap of \a w.
- *
- * \note Recursively drawing children into their parent
- * effectively damages the parent buffer.
- */
-void win_compose(Window *w)
-{
- Window *child;
-
- /*
- * Walk over all children, in back to front order and tell them
- * to compose into us.
- */
- REVERSE_FOREACH_NODE(child, &w->children)
- {
- /* Recursively compose child first. */
- win_compose(child);
-
- /* Draw child into our bitmap. */
- if (w->bitmap)
- gfx_blit(w->bitmap, &child->geom, child->bitmap, 0, 0);
- }
-}
-
-/**
- * Map window \a w into \a parent.
- *
- * The new window becomes the topmost window.
- *
- * \note Opening a window twice is illegal.
- *
- * \see win_close()
- */
-void win_open(Window *w, Window *parent)
-{
- ASSERT(!w->parent);
- w->parent = parent;
- ADDHEAD(&parent->children, &w->link);
-}
-
-/**
- * Detach window from its parent.
- *
- * Closing a window causes it to become orphan of its
- * parent. Its content will no longer appear in its
- * parent after the next refresh cycle.
- *
- * \note Closing a window that has not been previously
- * opened is illegal.
- *
- * \see win_open()
- */
-void win_close(Window *w)
-{
- ASSERT(w->parent);
- REMOVE(&w->link);
- w->parent = NULL;
-}
-
-/**
- * Move window to the topmost position relative to its sibling.
- *
- * \see win_move(), win_resize(), win_setGeometry()
- */
-void win_raise(Window *w)
-{
- ASSERT(w->parent);
- REMOVE(&w->link);
- ADDHEAD(&w->parent->children, &w->link);
-}
-
-/**
- * Set window position and size at the same time.
- *
- * This function is equivalent to subsequent calls to win_move()
- * and win_resize() using the coordinates provided by the
- * \a new_geom rectangle.
- *
- * \note The xmax and ymax members of \a new_geom are non-inclusive,
- * as usual for the Rect interface.
- *
- * \see win_move()
- * \see win_resize()
- */
-void win_setGeometry(Window *w, const Rect *new_geom)
-{
- // requires C99?
- // memcpy(&w->geom, new_geom, sizeof(w->geom));
- w->geom = *new_geom;
-}
-
-/**
- * Move window to specified position.
- *
- * Move the window top-left corner to the pixel coordinates
- * \a left and \a top, which are relative to the parent window.
- *
- * \note A window can also be moved outside the borders
- * of its parent, or at negative coordinates.
- *
- * \note It is allowed to move an orphan window.
- */
-void win_move(Window *w, coord_t left, coord_t top)
-{
- Rect r;
-
- r.xmin = left;
- r.ymin = top;
- r.xmax = r.xmin + RECT_WIDTH(&w->geom);
- r.ymax = r.ymin + RECT_WIDTH(&w->geom);
-
- win_setGeometry(w, &r);
-}
-
-/**
- * Resize the rectangle of a window.
- *
- * The window shrinks or grows to the specified size.
- *
- * \note Growing a window beyond the size of its
- * backing bitmap results in unspecified behavior.
- *
- * \note It is allowed to resize an orphan window.
- */
-void win_resize(Window *w, coord_t width, coord_t height)
-{
- Rect r;
-
- r.xmin = w->geom.xmin;
- r.ymin = w->geom.ymin;
- r.xmax = r.xmin + width;
- r.ymax = r.ymin + height;
-
- win_setGeometry(w, &r);
-}
-
-/**
- * Initialize a new window structure.
- *
- * The new window initial position is set to (0,0).
- * The size is set to the size of the installed bitmap,
- * or (0,0) if there's no backing store.
- *
- * \arg bm The bitmap to install as backing store
- * for drawing into the window, or NULL if
- * the window is not drawable.
- */
-void win_create(Window *w, Bitmap *bm)
-{
- w->parent = NULL;
- w->bitmap = bm;
- w->geom.xmin = 0;
- w->geom.ymin = 0;
- if (bm)
- {
- w->geom.xmax = bm->width;
- w->geom.ymax = bm->height;
- }
- LIST_INIT(&w->children);
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Very simple hierarchical windowing system.
- *
- * All functions in this module are to be intended as methods
- * of the Window class. Please see its documentation
- * for a module-wise introduction.
- *
- * \see struct Window
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.3 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.2 2006/01/26 00:36:48 bernie
- *#* Const correctness for some new functions.
- *#*
- *#* Revision 1.1 2006/01/23 23:14:29 bernie
- *#* Implement simple, but impressive windowing system.
- *#*
- *#*/
-
-#ifndef GFX_WIN_H
-#define GFX_WIN_H
-
-#include <mware/list.h> /* Node, List */
-#include <gfx/gfx.h> /* coord_t */
-
-
-EXTERN_C_BEGIN
-
-/**
- * Window handle and context structure.
- *
- * A window is a small rectangular area on the
- * screen backed by its own bitmap where you
- * can draw.
- *
- * A window can contain any number of children
- * sub-windows that can be depth arranged with
- * respect to their siblings.
- *
- * At any time, a window and all its children
- * can be drawn into another bitmap to display
- * a complete screen, taking depth and
- * overlapping into account.
- *
- * This rendering model is commonly referred to as
- * screen composition, and is quite popular among
- * modern windowing systems.
- */
-typedef struct Window
-{
- Node link; /**< Link us with other siblings into our parent. */
- struct Window *parent; /**< Our parent window. NULL for the root window. */
-
- Bitmap *bitmap; /**< Pixel storage for window contents. */
- Rect geom; /**< [px] Window size and position relative to parent. */
-
- /**
- * List of child windows, arranged by depth (front to back).
- *
- * Child top/left coordinates are relative to us.
- */
- List children;
-
-} Window;
-
-/*
- * Public function prototypes
- */
-void win_compose(Window *w);
-void win_open(Window *w, Window *parent);
-void win_close(Window *w);
-void win_raise(Window *w);
-void win_setGeometry(Window *w, const Rect *new_geom);
-void win_move(Window *w, coord_t left, coord_t top);
-void win_resize(Window *w, coord_t width, coord_t height);
-void win_create(Window *w, Bitmap *bm);
-
-EXTERN_C_END
-
-#endif /* GFX_WIN_H */
-
+++ /dev/null
-/**
- * \file
- * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- *
- *
- * \brief Graphics user interface element to display a level bar.
- *
- * \version $Id$
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#include "levelbar.h"
-
-
-/**
- * Initialize the LevelBar widget with the bitmap associated,
- * the value range and the coordinates in the bitmap.
- * \note The levelbar should be at least 5 pixels wide and high
- * for correct borders drawing. No check is done on this.
- */
-void lbar_init(struct LevelBar *lb, struct Bitmap *bmp, int type, int min, int max, int pos,
- coord_t x1, coord_t y1, coord_t x2, coord_t y2)
-{
- lb->bitmap = bmp;
- lb->type = type;
- lb->min = min;
- lb->max = max;
- lb->pos = pos;
- lb->x1 = x1;
- lb->y1 = y1;
- lb->x2 = x2;
- lb->y2 = y2;
-}
-
-
-/**
- * Set the level.
- */
-void lbar_setLevel(struct LevelBar *lb, int level)
-{
- if (level < lb->min)
- level = lb->min;
- if (level > lb->max)
- level = lb->max;
-
- lb->pos = level;
-}
-
-
-/**
- * Get current level.
- */
-int lbar_getLevel(struct LevelBar *lb)
-{
- return lb->pos;
-}
-
-
-/**
- * Change level with respect to previous value
- * (delta can be negative).
- */
-void lbar_changeLevel(struct LevelBar *lb, int delta)
-{
- lbar_setLevel(lb, lb->pos + delta);
-}
-
-
-/**
- * Change the top limit.
- */
-void lbar_setMax(struct LevelBar *lb, int max)
-{
- lb->max = max;
-}
-
-
-/**
- * Render the LevelBar on the bitmap.
- */
-void lbar_draw(struct LevelBar *lb)
-{
-#define BORDERW 1
-#define BORDERH 1
-
- /* Compute filled bar length in pixels */
- int totlen = (lb->type & LBAR_HORIZONTAL) ? lb->x2 - lb->x1 - BORDERW*4 : lb->y2 - lb->y1 - BORDERH*4;
- int range = lb->max - lb->min;
- int barlen = ((long)(lb->pos - lb->min) * (long)totlen + range - 1) / range;
-
- // Draw border
- gfx_rectDraw(lb->bitmap, lb->x1, lb->y1, lb->x2, lb->y2);
-
- // Clear inside
- gfx_rectClear(lb->bitmap, lb->x1 + BORDERW, lb->y1 + BORDERH, lb->x2 - BORDERW, lb->y2 - BORDERH);
-
- // Draw bar
- if (lb->type & LBAR_HORIZONTAL)
- gfx_rectFill(lb->bitmap,
- lb->x1 + BORDERW*2, lb->y1 + BORDERH*2,
- lb->x1 + BORDERW*2 + barlen, lb->y2 - BORDERH*2);
- else
- gfx_rectFill(lb->bitmap,
- lb->x1 + BORDERW*2, lb->y2 - BORDERH*2 - barlen,
- lb->x2 - BORDERW*2, lb->y2 - BORDERH*2);
-}
+++ /dev/null
-/**
- * \file
- * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- *
- *
- * \version $Id$
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Graphics level bar widget
- */
-
-#ifndef GUI_LEVELBAR_H
-#define GUI_LEVELBAR_H
-
-#include <gfx/gfx.h>
-
-
-/** Type of levelbar */
-#define LBAR_HORIZONTAL 1
-#define LBAR_VERTICAL 2
-
-typedef struct LevelBar
-{
- struct Bitmap *bitmap;
- int type;
- int pos; ///< Current level
- int min; ///< Minimum level
- int max; ///< Maximum level
- coord_t x1, y1, x2, y2; ///< Position of widget in the bitmap
-} LevelBar;
-
-void lbar_init(struct LevelBar *lb, struct Bitmap *bmp, int type, int min, int max, int pos,
- coord_t x1, coord_t y1, coord_t x2, coord_t y2);
-void lbar_setLevel(struct LevelBar *lb, int level);
-int lbar_getLevel(struct LevelBar *lb);
-void lbar_changeLevel(struct LevelBar *lb, int delta);
-void lbar_setMax(struct LevelBar *lb, int max);
-void lbar_draw(struct LevelBar *lb);
-
-#endif /* GUI_LEVELBAR_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Generic editor for (volume/gain/contrast/...) setting.
- *
- * \version $Id$
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#include "leveledit.h"
-
-#include <cfg/macros.h> /* MAX() */
-#include <drv/kbd.h>
-#include <drv/timer.h>
-#include <gui/levelbar.h>
-#include <mware/pgm.h>
-#include <gfx/text.h>
-#include <gfx/font.h>
-#include <appconfig.h>
-
-#if CONFIG_MENU_MENUBAR
-#include <gui/menubar.h>
-#endif
-
-// BEGIN project_grl LOCAL
-#include <drv/lcd_gfx.h>
-#include <gui/guiman.h>
-// END project_grl LOCAL
-
-#define LBAR_HEIGHT 16
-
-/**
- * Allow user to change level.
- */
-void level_edit(struct LevelEdit *lev)
-{
-#if CONFIG_MENU_MENUBAR
- /* Labels for menubars */
- enum LabelId ch_labels[] = { LABEL_C1PLUS2, LABEL_CH_1, LABEL_CH_2 };
- const_iptr_t labels[] =
- {
- (const_iptr_t)LABEL_BACK,
- (const_iptr_t)LABEL_MINUS,
- (const_iptr_t)LABEL_PLUS,
- (const_iptr_t)LABEL_EMPTY
- };
- struct MenuBar mb;
-#endif /* CONFIG_MENU_MENUBAR */
-
- struct LevelBar bar1, bar2;
- keymask_t keys, old_rpt_mask;
- int step, rep_step;
-
- rep_step = MAX(lev->step, ((lev->max - lev->min) / 200));
- step = lev->step;
-
- // Allow keys repetition.
- old_rpt_mask = kbd_setRepeatMask(K_UP | K_DOWN);
-
- text_clear(lev->bitmap);
- //text_style(STYLEF_UNDERLINE, STYLEF_UNDERLINE);
- text_puts(lev->title, lev->bitmap);
- //text_style(0, STYLEF_UNDERLINE);
-
- if (lev->type & LEVELEDIT_DOUBLE)
- {
- int chn = 0; /* edit both channels */
-
- /* Levelbars init */
- lbar_init(&bar1, lev->bitmap, LBAR_HORIZONTAL,
- lev->min, lev->max, *lev->ch1_val, 0, 16, lev->bitmap->width / 2 - 1, 23);
- lbar_init(&bar2, lev->bitmap, LBAR_HORIZONTAL,
- lev->min, lev->max, *lev->ch2_val, lev->bitmap->width / 2 + 1, 16, lev->bitmap->width, 23);
-
- #if CONFIG_MENU_MENUBAR
- labels[3] = (const_iptr_t)ch_labels[chn];
- mbar_init(&mb, lev->bitmap, labels, countof(labels));
- mbar_draw(&mb);
- #endif /* CONFIG_MENU_MENUBAR */
-
- /* Input loop for double level setting */
- for (;;)
- {
- #if CONFIG_LEVELEDIT_TIMEOUT != 0
- ticks_t idle_timeout = timer_clock();
- #endif
- do
- {
- if (lev->display_hook)
- lev->display_hook(lev);
- else
- {
- text_xprintf(lev->bitmap, 1, 0, TEXT_CENTER | TEXT_FILL, lev->unit);
- PGM_FUNC(text_xprintf)(lev->bitmap, 1, 3, 0, PGM_STR("%d"), *lev->ch1_val);
- PGM_FUNC(text_xprintf)(lev->bitmap, 1, 14, 0, PGM_STR("%d"), *lev->ch2_val);
-
- lbar_setLevel(&bar1, *lev->ch1_val);
- lbar_setLevel(&bar2, *lev->ch2_val);
- lbar_draw(&bar1);
- lbar_draw(&bar2);
- }
-
- #if CONFIG_LEVELEDIT_TIMEOUT != 0
- if (timer_clock() - idle_timeout > ms_to_ticks(CONFIG_LEVELEDIT_TIMEOUT))
- {
- /* Accept input implicitly */
- keys = K_OK;
- break;
- }
- #endif
- }
- while (!(keys = kbd_peek()));
-
- if (keys & K_CANCEL)
- break;
-
- if (keys & K_OK)
- {
- chn = (chn + 1) % 3;
-
- #if CONFIG_MENU_MENUBAR
- labels[3] = (const_iptr_t)ch_labels[chn];
- mbar_draw(&mb);
- #endif /* CONFIG_MENU_MENUBAR */
- }
-
- /* Increment step to achieve greater accelerations on larger values */
- if (keys & K_REPEAT)
- step = MIN(rep_step, step + 1);
- else
- step = lev->step;
-
- if (keys & (K_UP | K_DOWN))
- {
- if (keys & K_UP)
- {
- /* If changing both channels (chn == 0), don't change
- * level if one of two is at min or max */
- if (chn != 0 ||
- (*lev->ch1_val + step <= lev->max
- && *lev->ch2_val + step <= lev->max))
- {
- /* If chn == 0 change both channels */
- if (chn != 2)
- {
- *lev->ch1_val += step;
- if (*lev->ch1_val > lev->max)
- *lev->ch1_val = lev->max;
- }
- if (chn != 1)
- {
- *lev->ch2_val += step;
- if (*lev->ch2_val > lev->max)
- *lev->ch2_val = lev->max;
- }
- }
- }
- else
- {
- if (chn != 0 ||
- (*lev->ch1_val - step >= lev->min
- && *lev->ch2_val - step >= lev->min))
- {
- if (chn != 2)
- {
- *lev->ch1_val -= step;
- if (*lev->ch1_val < lev->min)
- *lev->ch1_val = lev->min;
- }
- if (chn != 1)
- {
- *lev->ch2_val -= step;
- if (*lev->ch2_val < lev->min)
- *lev->ch2_val = lev->min;
- }
- }
- }
-
- if (lev->set_hook)
- lev->set_hook();
- }
- } // end for(;;)
- }
- else
- {
- const PGM_ATTR char *fmt = lev->unit ? PGM_STR("%d %s") : PGM_STR("%d");
-
-/*
- const int textw = MAX(PGM_FUNC(text_widthf)(lev->bitmap, fmt, lev->max, lev->unit),
- PGM_FUNC(text_widthf)(lev->bitmap, fmt, lev->min, lev->unit));
-
- const coord_t barlen = lev->bitmap->width - 6 - textw;
-*/
- const coord_t barlen = lev->bitmap->width;
- const coord_t barvtop = lev->bitmap->height / 2 - LBAR_HEIGHT/2 + lev->bitmap->font->height;
- lbar_init(&bar1, lev->bitmap, LBAR_HORIZONTAL,
- lev->min, lev->max, *lev->ch1_val,
- 0, barvtop, barlen, barvtop + LBAR_HEIGHT);
-
- #if CONFIG_MENU_MENUBAR
- mbar_init(&mb, lev->bitmap, labels, countof(labels));
- mbar_draw(&mb);
- #endif /* CONFIG_MENU_MENUBAR */
-
- /* Input loop for single level setting */
- for (;;)
- {
- #if CONFIG_LEVELEDIT_TIMEOUT != 0
- ticks_t idle_timeout = timer_clock();
- #endif
- do
- {
- if (lev->display_hook)
- lev->display_hook(lev);
- else
- {
- if (lev->type != LEVELEDIT_NOBAR)
- {
- lbar_setLevel(&bar1, *lev->ch1_val);
- lbar_draw(&bar1);
- }
- PGM_FUNC(text_xyprintf)(lev->bitmap, 0, bar1.y1 - lev->bitmap->font->height,
- TEXT_CENTER | TEXT_FILL, fmt, *lev->ch1_val, lev->unit);
- }
-
- #if CONFIG_LEVELEDIT_TIMEOUT != 0
- if (timer_clock() - idle_timeout > CONFIG_LEVELEDIT_TIMEOUT)
- {
- /* Accept input implicitly */
- keys = K_CANCEL;
- break;
- }
- #endif
-
-// BEGIN project_grl LOCAL
-#if 1
- //FIXME: must to this only when needed
- lcd_blitBitmap(&lcd_bitmap);
- }
- while (!(keys = GuiMan_KbdPeek()));
-#else
- }
- while (!(keys = kbd_peek()));
-#endif
-// END project_grl LOCAL
-
- if (keys & K_CANCEL)
- break;
-
- /* Increment step to achieve greater accelerations on larger values */
- if (keys & K_REPEAT)
- step = MIN(rep_step, step + 1);
- else
- step = lev->step;
-
- if (keys & K_UP)
- {
- *lev->ch1_val += step;
- if (*lev->ch1_val > lev->max)
- *lev->ch1_val = lev->max;
- }
-
- if (keys & K_DOWN)
- {
- *lev->ch1_val -= step;
- if (*lev->ch1_val < lev->min)
- *lev->ch1_val = lev->min;
- }
-
- if (lev->set_hook)
- lev->set_hook();
- }
- }
-
- kbd_setRepeatMask(old_rpt_mask);
-}
-
-/**
- * LevelEdit structure initialization.
- * Init data structure and init LevelEdit widgets.
- */
-void level_init(struct LevelEdit *lev,
- int type,
- struct Bitmap *bmp, const char *title, const char *unit,
- int min, int max, int step,
- int *ch1_val, int *ch2_val,
- level_set_callback *set_hook, display_callback *display_hook)
-{
- lev->type = type;
- lev->bitmap = bmp;
- lev->title = title;
- lev->unit = unit;
- lev->min = min;
- lev->max = max;
- lev->step = step;
-
- lev->ch1_val = ch1_val;
- lev->ch2_val = ch2_val;
- lev->set_hook = set_hook;
- lev->display_hook = display_hook;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Generic editor for (volume/gain/contrast/...) setting.
- *
- * \version $Id$
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-#ifndef GUI_LEVELEDIT_H
-#define GUI_LEVELEDIT_H
-
-//#include <gui/levelbar.h>
-
-/* Type for level_init */
-#define LEVELEDIT_NOBAR 0 /**< Edit number only, without bar nor units */
-#define LEVELEDIT_SINGLE 1 /**< Single channel editing */
-#define LEVELEDIT_DOUBLE 2 /**< Double channel editing */
-
-
-
-/* Fwd decl */
-struct Bitmap;
-struct LevelEdit;
-
-/** Type for callback used to set meter levels */
-typedef void level_set_callback(void);
-
-/** Type for callback used to customize display of units */
-typedef void display_callback(struct LevelEdit *);
-
-/**
- * State of a level meter
- */
-typedef struct LevelEdit {
- int type; /*<! Type of level edititing mode (see prev defines) */
- const char *title; /*<! Title on top of screen */
- const char *unit; /*<! Unit of quantity changed by this LevelEdit */
- int min; /*<! Minimum level */
- int max; /*<! Maximum level */
- int step; /*<! Value of a single increment/decrement */
-
- level_set_callback *set_hook; /*<! Callback called when a value is changed */
- display_callback *display_hook; /*<! Callback for complex unit display */
- int *ch1_val; /*<! (left) Value edited by this leveledit */
- int *ch2_val; /*<! Right channel edited */
-
- struct Bitmap *bitmap; /*<! Bitmap where the whole thing is rendered */
-} LevelEdit;
-
-
-void level_init(struct LevelEdit *lev,
- int type,
- struct Bitmap *bmp, const char *title, const char *unit,
- int min, int max, int step,
- int *ch1_val, int *ch2_val,
- level_set_callback *change_hook, display_callback *display_hook);
-void level_edit(struct LevelEdit *lev);
-
-#endif /* GUI_LEVELEDIT_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief General pourpose menu handling functions
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.8 2006/09/13 13:58:32 bernie
- *#* Add RenderHook support.
- *#*
- *#* Revision 1.7 2006/08/01 12:22:46 bernie
- *#* Mention DevLib license.
- *#*
- *#* Revision 1.6 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.5 2006/06/03 13:58:01 bernie
- *#* Fix recursive timeout and add exit status information.
- *#*
- *#* Revision 1.4 2006/06/02 12:26:18 bernie
- *#* Draw graphical checkmarks.
- *#*
- *#* Revision 1.3 2006/05/28 15:03:31 bernie
- *#* Avoid unnecessary rendering.
- *#*
- *#* Revision 1.2 2006/05/25 23:34:38 bernie
- *#* Implement menu timeouts.
- *#*
- *#* Revision 1.1 2006/05/15 07:20:54 bernie
- *#* Move menu to gui/.
- *#*
- *#* Revision 1.7 2006/04/27 05:39:24 bernie
- *#* Enhance text rendering to arbitrary x,y coords.
- *#*
- *#* Revision 1.6 2006/04/11 00:07:32 bernie
- *#* Implemenent MF_SAVESEL flag.
- *#*
- *#* Revision 1.5 2006/03/22 09:49:51 bernie
- *#* Simplifications from project_grl.
- *#*
- *#* Revision 1.4 2006/03/20 17:48:35 bernie
- *#* Implement support for ROM menus.
- *#*
- *#* Revision 1.3 2006/02/20 14:34:32 bernie
- *#* Include appconfig.h before using its definitions.
- *#*
- *#* Revision 1.2 2006/02/15 09:10:51 bernie
- *#* Make title bold; Fix height when we have no menubar.
- *#*/
-
-#include "menu.h"
-
-#include <gfx/gfx.h>
-#include <gfx/font.h>
-#include <gfx/text.h>
-#include <drv/kbd.h>
-#include <cfg/compiler.h>
-#include <cfg/debug.h>
-#include <appconfig.h>
-#include <string.h> /* strcpy() */
-
-#if CPU_HARVARD
-#include <avr/pgmspace.h> /* strncpy_P() */
-#endif
-
-#if CONFIG_MENU_SMOOTH
-#include <drv/lcd_gfx.h>
-#endif
-
-#if (CONFIG_MENU_TIMEOUT != 0)
-#include <drv/timer.h>
-#endif
-
-#if CONFIG_MENU_MENUBAR
-#include "menubar.h"
-#endif
-
-#if defined(CONFIG_LOCALE) && (CONFIG_LOCALE == 1)
-#include "msg.h"
-#else
-#define PTRMSG(x) ((const char *)x)
-#endif
-
-
-/* Temporary fake defines for ABORT stuff... */
-#define abort_top 0
-#define PUSH_ABORT false
-#define POP_ABORT do {} while(0)
-#define DO_ABORT do {} while(0)
-
-
-/**
- * Return the total number of items in in a menu.
- */
-static int menu_count(const struct Menu *menu)
-{
- int cnt = 0;
-
- for (cnt = 0; /*NOP*/; ++cnt)
- {
- const MenuItem *item = &menu->items[cnt];
-#if CPU_HARVARD
- MenuItem ram_item;
- if (menu->flags & MF_ROMITEMS)
- {
- memcpy_P(&ram_item, item, sizeof(ram_item));
- item = &ram_item;
- }
-#endif
- if (!(item->label || item->hook))
- break;
- }
-
- return cnt;
-}
-
-#if CONFIG_MENU_MENUBAR
-
-/**
- * Update the menu bar according to the selected item and redraw it.
- */
-static void menu_update_menubar(
- const struct Menu *menu,
- struct MenuBar *mb,
- int selected)
-{
- int item_flags;
-#if CPU_HARVARD
- if (menu->flags & MF_ROMITEMS)
- {
- ASSERT(sizeof(menu->items[selected].flags) == sizeof(int));
- item_flags = pgm_read_int(&menu->items[selected].flags);
- }
- else
-#endif
- item_flags = menu->items[selected].flags;
-
- const_iptr_t newlabel = (const_iptr_t)LABEL_OK;
-
- if (item_flags & MIF_DISABLED)
- newlabel = (const_iptr_t)LABEL_EMPTY;
- else if (item_flags & MIF_TOGGLE)
- newlabel = (const_iptr_t)LABEL_SEL;
- else if (item_flags & MIF_CHECKIT)
- {
- newlabel = (item_flags & MIF_CHECKED) ?
- (const_iptr_t)LABEL_EMPTY : (const_iptr_t)LABEL_SEL;
- }
-
- mb->labels[3] = newlabel;
- mbar_draw(mb);
-}
-#endif /* CONFIG_MENU_MENUBAR */
-
-
-static void menu_defaultRenderHook(struct Bitmap *bm, int ypos, bool selected, const struct MenuItem *item)
-{
- if (item->flags & MIF_CHECKIT)
- {
- gfx_rectClear(bm, 0, ypos,
- bm->font->height, ypos + bm->font->height);
-
- if (item->flags & MIF_TOGGLE)
- gfx_rectDraw(bm, 2, ypos + 2,
- bm->font->height - 2, ypos + bm->font->height - 2);
- if (item->flags & MIF_CHECKED)
- {
- gfx_line(bm,
- 3, ypos + 3,
- bm->font->height - 3, ypos + bm->font->height - 3);
- gfx_line(bm,
- bm->font->height - 3, ypos + 3,
- 3, ypos + bm->font->height - 3);
- }
- }
-
-#if CPU_HARVARD
- ((item->flags & MIF_RAMLABEL) ? text_xyprintf : text_xyprintf_P)
-#else
- text_xyprintf
-#endif
- (
- bm, (item->flags & MIF_CHECKIT) ? bm->font->height : 0, ypos,
- selected ? (STYLEF_INVERT | TEXT_FILL) : TEXT_FILL,
- PTRMSG(item->label)
- );
-}
-
-/**
- * Show a menu on the display.
- */
-static void menu_layout(
- const struct Menu *menu,
- int first_item,
- int selected,
- bool redraw)
-{
- coord_t ypos;
- int i;
- const char * PROGMEM title = PTRMSG(menu->title);
- Bitmap *bm = menu->bitmap;
-
- ypos = bm->cr.ymin;
-
-#if 0
- if (redraw)
- {
- /* Clear screen */
- text_clear(menu->bitmap);
- }
-#endif
-
- if (title)
- {
- if (redraw)
- text_xyprintf(bm, 0, ypos, STYLEF_UNDERLINE | STYLEF_BOLD | TEXT_CENTER | TEXT_FILL, title);
- ypos += bm->font->height;
- }
-
-#if CONFIG_MENU_SMOOTH
- static coord_t yoffset = 0;
- static int old_first_item = 0;
- static int speed;
- coord_t old_ymin = bm->cr.ymin;
-
- /* Clip drawing inside menu items area */
- gfx_setClipRect(bm,
- bm->cr.xmin, bm->cr.ymin + ypos,
- bm->cr.xmax, bm->cr.ymax);
-
- if (old_first_item != first_item)
- {
- /* Speed proportional to distance */
- speed = ABS(old_first_item - first_item) * 3;
-
- if (old_first_item > first_item)
- {
- yoffset += speed;
- if (yoffset > bm->font->height)
- {
- yoffset = 0;
- --old_first_item;
- }
- }
- else
- {
- yoffset -= speed;
- if (yoffset < -bm->font->height)
- {
- yoffset = 0;
- ++old_first_item;
- }
- }
- first_item = MIN(old_first_item, menu_count(menu));
-
- ypos += yoffset;
- redraw = true;
- }
-#endif /* CONFIG_MENU_SMOOTH */
-
- if (redraw) for (i = first_item; /**/; ++i)
- {
- const MenuItem *item = &menu->items[i];
-#if CPU_HARVARD
- MenuItem ram_item;
- if (menu->flags & MF_ROMITEMS)
- {
- memcpy_P(&ram_item, item, sizeof(ram_item));
- item = &ram_item;
- }
-#endif /* CPU_HARVARD */
-
- /* Check for end of room */
- if (ypos > bm->cr.ymax)
- break;
-
- /* Check for end of menu */
- if (!(item->label || item->hook))
- break;
-
- /* Only print visible items */
- if (!(item->flags & MIF_HIDDEN))
- {
- /* Check if a special render function is supplied, otherwise use defaults */
- RenderHook renderhook = (item->flags & MIF_RENDERHOOK) ? (RenderHook)item->label : menu_defaultRenderHook;
-
- /* Render menuitem */
- renderhook(menu->bitmap, ypos++, (i == selected), item);
-
- ypos += bm->font->height;
- }
- }
-
-#if CONFIG_MENU_SMOOTH
- if (redraw)
- {
- /* Clear rest of area */
- gfx_rectClear(bm, bm->cr.xmin, ypos, bm->cr.xmax, bm->cr.ymax);
-
- lcd_blitBitmap(&lcd_bitmap);
- }
-
- /* Restore old cliprect */
- gfx_setClipRect(bm,
- bm->cr.xmin, old_ymin,
- bm->cr.xmax, bm->cr.ymax);
-
-#endif /* CONFIG_MENU_SMOOTH */
-}
-
-
-/**
- * Handle menu item selection
- */
-static iptr_t menu_doselect(const struct Menu *menu, struct MenuItem *item)
-{
- iptr_t result = 0;
-
- /* Exclude other items */
- int mask, i;
- for (mask = item->flags & MIF_EXCLUDE_MASK, i = 0; mask; mask >>= 1, ++i)
- {
- if (mask & 1)
- menu->items[i].flags &= ~MIF_CHECKED;
- }
-
- if (item->flags & MIF_DISABLED)
- return MENU_DISABLED;
-
- /* Handle checkable items */
- if (item->flags & MIF_TOGGLE)
- item->flags ^= MIF_CHECKED;
- else if (item->flags & MIF_CHECKIT)
- item->flags |= MIF_CHECKED;
-
- /* Handle items with callback hooks */
- if (item->hook)
- {
- /* Push a jmp buffer to abort the operation with the STOP/CANCEL key */
- if (!PUSH_ABORT)
- {
- result = item->hook(item->userdata);
- POP_ABORT;
- }
- }
- else
- result = item->userdata;
-
- return result;
-}
-
-
-/**
- * Return the next visible item (rolls back to the first item)
- */
-static int menu_next_visible_item(const struct Menu *menu, int index)
-{
- int total = menu_count(menu);
- int item_flags;
-
- do
- {
- if (++index >= total)
- index = 0;
-
-#if CPU_HARVARD
- if (menu->flags & MF_ROMITEMS)
- {
- ASSERT(sizeof(menu->items[index].flags) == sizeof(int));
- item_flags = pgm_read_int(&menu->items[index].flags);
- }
- else
-#endif
- item_flags = menu->items[index].flags;
- }
- while (item_flags & MIF_HIDDEN);
-
- return index;
-}
-
-
-/**
- * Return the previous visible item (rolls back to the last item)
- */
-static int menu_prev_visible_item(const struct Menu *menu, int index)
-{
- int total = menu_count(menu);
- int item_flags;
-
- do
- {
- if (--index < 0)
- index = total - 1;
-
-#if CPU_HARVARD
- if (menu->flags & MF_ROMITEMS)
- {
- ASSERT(sizeof(menu->items[index].flags) == sizeof(int));
- item_flags = pgm_read_int(&menu->items[index].flags);
- }
- else
-#endif
- item_flags = menu->items[index].flags;
- }
- while (item_flags & MIF_HIDDEN);
-
- return index;
-}
-
-
-/**
- * Handle a menu and invoke hook functions for the selected menu items.
- */
-iptr_t menu_handle(const struct Menu *menu)
-{
- uint8_t items_per_page;
- uint8_t first_item = 0;
- uint8_t selected;
- iptr_t result = 0;
- bool redraw = true;
-
-#if (CONFIG_MENU_TIMEOUT != 0)
- ticks_t now, menu_idle_time = timer_clock();
-#endif
-
-#if CONFIG_MENU_MENUBAR
- struct MenuBar mb;
- const_iptr_t labels[] =
- {
- (const_iptr_t)LABEL_BACK,
- (const_iptr_t)LABEL_UPARROW,
- (const_iptr_t)LABEL_DOWNARROW,
- (const_iptr_t)0
- };
-
- /*
- * Initialize menu bar
- */
- if (menu->flags & MF_TOPLEVEL)
- labels[0] = (const_iptr_t)LABEL_EMPTY;
-
- mbar_init(&mb, menu->bitmap, labels, countof(labels));
-#endif /* CONFIG_MENU_MENUBAR */
-
-
- items_per_page =
- (menu->bitmap->height / menu->bitmap->font->height)
-#if CONFIG_MENU_MENUBAR
- - 1 /* menu bar labels */
-#endif
- - (menu->title ? 1 : 0);
-
- /* Selected item should be a visible entry */
- //first_item = selected = menu_next_visible_item(menu, menu->selected - 1);
- selected = menu->selected;
- first_item = 0;
-
- for(;;)
- {
- keymask_t key;
-
- /*
- * Keep selected item visible
- */
- while (selected < first_item)
- first_item = menu_prev_visible_item(menu, first_item);
- while (selected >= first_item + items_per_page)
- first_item = menu_next_visible_item(menu, first_item);
-
- menu_layout(menu, first_item, selected, redraw);
- redraw = false;
-
- #if CONFIG_MENU_MENUBAR
- menu_update_menubar(menu, &mb, selected);
- #endif
-
- #if CONFIG_MENU_SMOOTH || (CONFIG_MENU_TIMEOUT != 0)
- key = kbd_peek();
- #else
- key = kbd_get();
- #endif
-
- #if (CONFIG_MENU_TIMEOUT != 0)
- /* Reset idle timer on key press. */
- now = timer_clock();
- if (key)
- menu_idle_time = now;
- #endif
-
- if (key & K_OK)
- {
- struct MenuItem *item = &(menu->items[selected]);
-#if CPU_HARVARD
- MenuItem ram_item;
- if (menu->flags & MF_ROMITEMS)
- {
- memcpy_P(&ram_item, item, sizeof(ram_item));
- item = &ram_item;
- }
-#endif
- result = menu_doselect(menu, item);
- redraw = true;
-
- /* Return immediately */
- if (!(menu->flags & MF_STICKY))
- break;
-
- #if (CONFIG_MENU_TIMEOUT != 0)
- /* Chain timeout */
- if ((result == MENU_TIMEOUT) && !(menu->flags & MF_TOPLEVEL))
- break;
-
- /* Reset timeout */
- menu_idle_time = timer_clock();
- #endif
- }
- else if (key & K_UP)
- {
- selected = menu_prev_visible_item(menu, selected);
- redraw = true;
- }
- else if (key & K_DOWN)
- {
- selected = menu_next_visible_item(menu, selected);
- redraw = true;
- }
- else if (!(menu->flags & MF_TOPLEVEL))
- {
- if (key & K_CANCEL)
- {
- result = MENU_CANCEL;
- break;
- }
-
- #if CONFIG_MENU_TIMEOUT != 0
- if (now - menu_idle_time > ms_to_ticks(CONFIG_MENU_TIMEOUT))
- {
- result = MENU_TIMEOUT;
- break;
- }
- #endif
- }
- }
-
- /* Store currently selected item before leaving. */
- if (menu->flags & MF_SAVESEL)
- CONST_CAST(struct Menu *, menu)->selected = selected;
-
- return result;
-}
-
-
-/**
- * Set flags on a menuitem.
- *
- * \param menu Menu owner of the item to change.
- * \param idx Index of the menu item.
- * \param flags Bit mask of the flags to set.
- *
- * \return Old flags.
- */
-int menu_setFlags(struct Menu *menu, int idx, int flags)
-{
- ASSERT(idx < menu_count(menu));
- ASSERT(!(menu->flags & MF_ROMITEMS));
-
- int old = menu->items[idx].flags;
- menu->items[idx].flags |= flags;
- return old;
-}
-
-
-/**
- * Clear flags on a menuitem.
- *
- * \param menu Menu owner of the item to change.
- * \param idx Index of the menu item.
- * \param flags Bit mask of the flags to clear.
- *
- * \return Old flags.
- */
-int menu_clearFlags(struct Menu *menu, int idx, int flags)
-{
- ASSERT(idx < menu_count(menu));
- ASSERT(!(menu->flags & MF_ROMITEMS));
-
- int old = menu->items[idx].flags;
- menu->items[idx].flags &= ~flags;
- return old;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti <bernie@codewiz.org>
- * All Rights Reserved.
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Common menu handling API
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.5 2007/09/19 16:23:27 batt
- *#* Fix doxygen warnings.
- *#*
- *#* Revision 1.4 2006/09/13 13:58:33 bernie
- *#* Add RenderHook support.
- *#*
- *#* Revision 1.3 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.2 2006/06/03 13:58:02 bernie
- *#* Fix recursive timeout and add exit status information.
- *#*
- *#* Revision 1.1 2006/05/15 07:20:54 bernie
- *#* Move menu to gui/.
- *#*
- *#* Revision 1.4 2006/04/11 00:07:32 bernie
- *#* Implemenent MF_SAVESEL flag.
- *#*
- *#* Revision 1.3 2006/03/22 09:49:51 bernie
- *#* Simplifications from project_grl.
- *#*
- *#* Revision 1.2 2006/03/20 17:48:35 bernie
- *#* Implement support for ROM menus.
- *#*
- *#* Revision 1.1 2006/02/10 12:29:36 bernie
- *#* Add menu system.
- *#*
- *#* Revision 1.20 2005/11/16 18:10:19 bernie
- *#* Move top-level headers to cfg/ as in DevLib.
- *#*
- *#* Revision 1.19 2005/02/11 19:11:38 aleph
- *#* Move menu_displaymsg() in new displaymsg module
- *#*
- *#* Revision 1.18 2005/01/13 16:56:36 aleph
- *#* Fix progmem includes.
- *#*
- *#* Revision 1.17 2004/12/14 12:52:45 aleph
- *#* Add exclude menu flags
- *#*
- *#* Revision 1.16 2004/10/01 14:04:59 customer_pw
- *#* Add accessor functions for menu flags
- *#*
- *#* Revision 1.15 2004/09/09 08:31:36 customer_pw
- *#* Add disabled item type
- *#*
- *#* Revision 1.14 2004/08/29 21:46:12 bernie
- *#* CVSSILENT: Mark CVS log blocks.
- *#*
- *#* Revision 1.13 2004/08/25 15:35:23 customer_pw
- *#* IPTR -> iptr_t conversion.
- *#*
- *#* Revision 1.12 2004/08/25 13:23:45 bernie
- *#* IPTR -> iptr_t conversion.
- *#*/
-#ifndef MWARE_MENU_H
-#define MWARE_MENU_H
-
-#include <cfg/compiler.h>
-
-/* Fwd decl */
-struct Bitmap;
-
-/** Menu callback function */
-typedef iptr_t (*MenuHook)(iptr_t userdata);
-
-/**
- * Menu item description.
- */
-typedef struct MenuItem
-{
- const_iptr_t label; /**< Item label (ID or ptr to string, 0 to disable) */
- int flags; /**< See MIF_#? definitions below */
- MenuHook hook; /**< Callback function (NULL to terminate item list) */
- iptr_t userdata; /**< User data to be passed back to the hook */
-} MenuItem;
-
-/** Render hook callback function prototype */
-typedef void (*RenderHook)(struct Bitmap *bitmap, int ypos, bool selected, const struct MenuItem *item);
-
-/**
- * \name Flags for MenuItem.flags.
- * \{
- */
-#define MIF_EXCLUDE_MASK 0x00FF /**< Mask for mutual exclusion map (shared with priority). */
-#define MIF_PRI_MASK 0x00FF /**< Mask for priority value (shared with mutual exclusion). */
-#define MIF_PRI(x) ((x) & MIF_PRI_MASK) /**< Set menu item priority. */
-#define MIF_EXCLUDE_0 BV(0) /**< Exclude item 0 when this item is checked */
-#define MIF_EXCLUDE_1 BV(1) /**< Exclude item 1 when this item is checked */
-#define MIF_EXCLUDE_2 BV(2) /**< Exclude item 2 when this item is checked */
-#define MIF_EXCLUDE_3 BV(3) /**< Exclude item 3 when this item is checked */
-#define MIF_EXCLUDE_4 BV(4) /**< Exclude item 4 when this item is checked */
-#define MIF_EXCLUDE_5 BV(5) /**< Exclude item 5 when this item is checked */
-#define MIF_EXCLUDE_6 BV(6) /**< Exclude item 6 when this item is checked */
-#define MIF_EXCLUDE_7 BV(7) /**< Exclude item 7 when this item is checked */
-#define MIF_CHECKED BV(8) /**< Item is currently checked */
-#define MIF_CHECKIT BV(9) /**< Automatically check this item when selected */
-#define MIF_TOGGLE BV(10) /**< Toggle MIF_CHECKED when item is selected */
-#define MIF_HIDDEN BV(11) /**< This menu item is not visible */
-#define MIF_DISABLED BV(12) /**< This menu item is not visible */
-#define MIF_RAMLABEL BV(13) /**< Item label is stored in RAM, not in program memory */
-#define MIF_RENDERHOOK BV(14) /**< Menu render function is passed in label field */
-/* \} */
-
-/**
- * Menu description.
- */
-typedef struct Menu
-{
- MenuItem *items; /**< Array of items (end with a NULL hook) */
- const_iptr_t title; /**< Menu title (ID or ptr to string, 0 to disable) */
- int flags; /**< See MF_#? definitions below */
- struct Bitmap *bitmap; /**< Bitmap where the menu is rendered */
- int selected; /**< Initial selection (written to if MF_SAVESEL is set). */
-} Menu;
-
-/**
- * \name Flags for Menu.flags.
- * \{
- */
-#define MF_STICKY BV(0) /**< Stay in the menu when the items called return */
-#define MF_TOPLEVEL BV(1) /**< Top-level menu (do not display "back" label) */
-#define MF_ROMITEMS BV(2) /**< Menu items are stored in ROM (default is RAM) */
-#define MF_SAVESEL BV(3) /**< Remember the selected item across invocations. */
-/* \} */
-
-/**
- * \name Special result codes for menu_handle().
- * \{
- */
-#define MENU_OK ((iptr_t)0)
-#define MENU_CANCEL ((iptr_t)-1)
-#define MENU_TIMEOUT ((iptr_t)-2)
-#define MENU_ABORT ((iptr_t)-3)
-#define MENU_DISABLED ((iptr_t)-4)
-/* \} */
-
-/* Function prototypes */
-iptr_t menu_handle(const struct Menu *menu);
-int menu_setFlags(struct Menu *menu, int idx, int flags);
-int menu_clearFlags(struct Menu *menu, int idx, int flags);
-
-#endif /* MWARE_MENU_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti
- * All Rights Reserved.
- * -->
- *
- * \brief Buzzer hardware-specific definitions
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2006/02/10 12:31:03 bernie
- *#* Add templates for hw definitions.
- *#*
- *#*/
-
-#ifndef HW_BUZZER_H
-#define HW_BUZZER_H
-
-#define BUZZER_BIT BV(1)
-#define IS_BUZZER_ON 0
-#define BUZZER_HW_INIT do { } while (0)
-#define BUZZER_ON do { } while (0)
-#define BUZZER_OFF do { } while (0)
-
-#endif /* HW_BUZZER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti
- * All Rights Reserved.
- * -->
- *
- * \brief Keyboard hardware-specific definitions
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- * \author Stefano Fedrigo <a@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.3 2006/03/22 09:51:27 bernie
- *#* Wrap C++ stuff.
- *#*
- *#* Revision 1.2 2006/02/15 09:13:42 bernie
- *#* Add keyboard emulator.
- *#*
- *#* Revision 1.1 2006/02/10 12:31:03 bernie
- *#* Add templates for hw definitions.
- *#*
- *#*/
-
-#ifndef HW_KBD_H
-#define HW_KBD_H
-
-#include "kbd_map.h"
-#include <cfg/macros.h>
-
-#define K_RPT_MASK (K_UP | K_DOWN | K_OK | K_CANCEL)
-
-#define KBD_HW_INIT \
- do { \
- } while (0)
-
-EXTERN_C int emul_kbdReadCols(void);
-
-/**
- * Read the keyboard ports and return the mask of
- * depressed keys.
- */
-INLINE keymask_t kbd_readkeys(void)
-{
- return (keymask_t)emul_kbdReadCols();
-}
-
-#endif /* HW_KBD_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief LCD low-level hardware macros
- */
-
-#ifndef HW_LCD_H
-#define HW_LCD_H
-
-#include <appconfig.h>
-//#include <hw.h>
-
-#include <cpu/attr.h>
-#include <cpu/irq.h>
-#include <cpu/types.h>
-
-#include <cfg/macros.h> /* BV() */
-#include <cfg/debug.h>
-
-#include <avr/io.h>
-#include <stdbool.h>
-#include <inttypes.h>
-
-/**
- * \name LCD I/O pins/ports
- * @{
- */
-#define LCD_RS BV(PG3)
-#define LCD_RW BV(PG0)
-#define LCD_E BV(PG2)
-#define LCD_DB0 BV(PA0)
-#define LCD_DB1 BV(PA1)
-#define LCD_DB2 BV(PA2)
-#define LCD_DB3 BV(PA3)
-#define LCD_DB4 BV(PA4)
-#define LCD_DB5 BV(PA5)
-#define LCD_DB6 BV(PA6)
-#define LCD_DB7 BV(PA7)
-/*@}*/
-
-/**
- * \name DB high nibble (DB[4-7])
- * @{
- */
-#define LCD_PORT PORTG
-#define LCD_DB_PORT PORTA
-#define LCD_PIN PING
-#define LCD_DB_PIN PINA
-#define LCD_DDR DDRG
-#define LCD_DB_DDR DDRA
-
-#if CONFIG_LCD_4BIT
- #define LCD_MASK (LCD_DB7 | LCD_DB6 | LCD_DB5 | LCD_DB4)
- #define LCD_SHIFT 4
-#else
- #define LCD_MASK (uint8_t)0xff
- #define LCD_SHIFT 0
-#endif
-/*@}*/
-
-/**
- * \name LCD bus control macros
- * @{
- */
-#define LCD_CLR_RS (LCD_PORT &= ~LCD_RS)
-#define LCD_SET_RS (LCD_PORT |= LCD_RS)
-#define LCD_CLR_RD (LCD_PORT &= ~LCD_RW)
-#define LCD_SET_RD (LCD_PORT |= LCD_RW)
-#define LCD_CLR_E (LCD_PORT &= ~LCD_E)
-#define LCD_SET_E (LCD_PORT |= LCD_E)
-
-#if CONFIG_LCD_4BIT
- #define LCD_WRITE_H(x) (LCD_DB_PORT = (LCD_DB_PORT & ~LCD_MASK) | (((x) >> (4 - LCD_SHIFT)) & LCD_MASK))
- #define LCD_WRITE_L(x) (LCD_DB_PORT = (LCD_DB_PORT & ~LCD_MASK) | (((x) << LCD_SHIFT) & LCD_MASK))
- #define LCD_READ_H ((LCD_DB_PIN & LCD_MASK) >> (4 - LCD_SHIFT))
- #define LCD_READ_L ((LCD_DB_PIN & LCD_MASK) >> LCD_SHIFT)
-#else
- #define LCD_WRITE(x) (LCD_DB_PORT = (x))
- #define LCD_READ (LCD_DB_PIN)
-#endif
-/*@}*/
-
-/** Set data bus direction to output (write to display) */
-#define LCD_DB_OUT (LCD_DB_DDR |= LCD_MASK)
-
-/** Set data bus direction to input (read from display) */
-#define LCD_DB_IN (LCD_DB_DDR &= ~LCD_MASK)
-
-/** Delay for write (Enable pulse width, 220ns) */
-#define LCD_DELAY_WRITE \
- do { \
- NOP; \
- NOP; \
- NOP; \
- NOP; \
- NOP; \
- } while (0)
-
-/** Delay for read (Data ouput delay time, 120ns) */
-#define LCD_DELAY_READ \
- do { \
- NOP; \
- NOP; \
- NOP; \
- NOP; \
- } while (0)
-
-
-INLINE void lcd_bus_init(void)
-{
- cpuflags_t flags;
- IRQ_SAVE_DISABLE(flags);
-
- LCD_PORT = (LCD_PORT & ~(LCD_E | LCD_RW)) | LCD_RS;
- LCD_DDR |= LCD_RS | LCD_RW | LCD_E;
-
- /*
- * Data bus is in output state most of the time:
- * LCD r/w functions assume it is left in output state
- */
- LCD_DB_OUT;
-
-
- IRQ_RESTORE(flags);
-}
-
-#endif /* HW_LCD_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief MCP41 hardware-specific definitions
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#include <hw_mcp41.h>
-
-#include <cfg/macros.h>
-#include <cfg/compiler.h>
-
-#include <avr/io.h>
-
-
-const uint16_t mcp41_ports[MCP41_CNT] = {
- _SFR_IO_ADDR(PORTB), /** Led pot */
- _SFR_IO_ADDR(PORTB), /** Photometer pot */
- };
-const uint8_t mcp41_pins [MCP41_CNT] = {
- BV(PB7),
- BV(PB6),
- };
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief MCP41 hardware-specific definitions
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#ifndef HW_MCP41_H
-#define HW_MCP41_H
-
-#include <mcp41_map.h>
-#include <cfg/compiler.h>
-#include <cpu/irq.h>
-#include <avr/io.h>
-
-extern const uint16_t mcp41_ports[MCP41_CNT];
-extern const uint8_t mcp41_pins[MCP41_CNT];
-
-/**
- * Set MCP41 port associated with \a dev to output.
- */
-INLINE void SET_MCP41_DDR(Mcp41Dev dev)
-{
- /* DDR port is 1 address before PORT */
- ATOMIC(_SFR_IO8(mcp41_ports[dev] - 1) |= mcp41_pins[dev]);
-}
-
-INLINE void MCP41_ON(Mcp41Dev i)
-{
- ATOMIC(_SFR_IO8(mcp41_ports[i]) &= ~mcp41_pins[i]);
-}
-
-INLINE void MCP41_OFF(Mcp41Dev i)
-{
- ATOMIC(_SFR_IO8(mcp41_ports[i]) |= mcp41_pins[i]);
-}
-
-
-#endif /* HW_MCP41_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id$
- *
- * \brief TC520 hardware-specific definitions
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#ifndef HW_TC520_H
-#define HW_TC520_H
-
-#include <cfg/compiler.h>
-#include <avr/io.h>
-
-#define CE_PIN PE6
-#define DV_PIN PE5
-#define LOAD_PIN PE3
-#define READ_PIN PE4
-
-#define TC520_DDR DDRE
-#define TC520_PORT PORTE
-#define TC520_PIN PINE
-
-#define DV_HIGH() (TC520_PIN & BV(DV_PIN))
-#define DV_LOW() (!DV_HIGH())
-
-#define CE_HIGH() (TC520_PORT |= BV(CE_PIN))
-#define CE_LOW() (TC520_PORT &= ~BV(CE_PIN))
-
-#define LOAD_HIGH() (TC520_PORT |= BV(LOAD_PIN))
-#define LOAD_LOW() (TC520_PORT &= ~BV(LOAD_PIN))
-
-#define READ_HIGH() (TC520_PORT |= BV(READ_PIN))
-#define READ_LOW() (TC520_PORT &= ~BV(READ_PIN))
-
-#define TC520_HW_INIT \
-do\
-{\
- TC520_PORT |= (BV(CE_PIN) | BV(LOAD_PIN) | BV(READ_PIN));\
- TC520_DDR |= (BV(CE_PIN) | BV(LOAD_PIN) | BV(READ_PIN));\
- TC520_DDR &= ~BV(DV_PIN);\
-}\
-while(0)
-
-#endif /* HW_TC520_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti
- * All Rights Reserved.
- * -->
- *
- * \brief Keyboard map definitions.
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- * \author Stefano Fedrigo <a@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2006/02/10 12:31:03 bernie
- *#* Add templates for hw definitions.
- *#*
- *#*/
-
-#ifndef HW_KBD_MAP_H
-#define HW_KBD_MAP_H
-
-#include <cfg/macros.h>
-
-
-/**
- * Type for keyboard mask.
- */
-typedef uint16_t keymask_t;
-
-/**
- * \name Keycodes.
- */
-/*@{*/
-#define K_UP BV(0)
-#define K_DOWN BV(1)
-#define K_OK BV(2)
-#define K_CANCEL BV(3)
-
-#define K_REPEAT BV(14) /**< This is a repeated keyevent. */
-#define K_TIMEOUT BV(15) /**< Fake key event for timeouts. */
-/*@}*/
-
-
-#endif /* HW_KBD_MAP_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief MCP41 digital potentiometer map definitions.
- *
- * \version $Id$
- *
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-#ifndef MCP41_MAP_H
-#define MCP41_MAP_H
-
-/** \name Enum for mcp41 pot evices.
- * \{
- */
-typedef enum Mcp41Dev
-{
- MCP41_LED,
- MCP41_PHOTO_GAIN,
-
- MCP41_CNT,
-} Mcp41Dev;
-/* \} */
-
-#endif /* MCP41_MAP_H */
+++ /dev/null
-#
-# $Id: Makefile 18234 2007-10-08 13:39:48Z rasky $
-# Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
-# All rights reserved.
-#
-# Author: Stefano Fedrigo <aleph@develer.com>
-#
-# $Log$
-# Revision 1.2 2006/09/20 14:18:01 marco
-# Use only icons neede by demo.
-#
-# Revision 1.1 2006/09/19 17:48:00 bernie
-# Add temporary logo.
-#
-#
-
-# Set to 1 for debug builds
-DEBUG = 1
-
-RASTERS = logo.raster
-
-FLIPIMAGE = flipimage
-flipimage_SRC = flipimage.cpp
-flipimage_OBJ = $(flipimage_SRC:%.cpp=%.o)
-
-.PHONY: all
-all: $(RASTERS)
-
-# Link rule
-$(FLIPIMAGE): $(flipimage_OBJ)
- $(CXX) $^ $(flipimage_LIBS) $(LDFLAGS) -o $@
-
-.PHONY: clean
-clean:
- rm -f $(TRG) $(flipimage_OBJ)
- rm -f $(RASTERS)
-
-.PHONY: rasters
-rasters: $(FLIPIMAGE) $(RASTERS)
-
-%.raster: %.png $(FLIPIMAGE)
- convert $< txt:- | ./flipimage >$@
-
-# Include dependencies
--include *.d
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright (C) 2004 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \version $Id$
- * \author Stefano Fedrigo <aleph@develer.com>
- *
- * \brief Conversion tool from image TXT format to LCD bitmap
- */
-
-/*
- * $Log$
- * Revision 1.1 2006/09/19 17:48:00 bernie
- * Add temporary logo.
- *
- * Revision 1.3 2004/09/24 17:25:32 powersoft
- * Fix for new version of ImageMagick.
- *
- * Revision 1.2 2004/03/13 22:52:54 aleph
- * documentation fixes
- *
- * Revision 1.1 2004/01/26 15:31:17 aleph
- * Add boot images and tools for importing them
- *
- */
-
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-
-#define RASTER_WIDTH 82
-#define RASTER_HEIGHT 64
-
-// Minimum color level to consider a pixel on
-#define COLOR_THRESHOLD 128
-
-
-using namespace std;
-
-
-int main(void)
-{
- char buf[64];
- int n;
- unsigned char mask;
- unsigned char line[RASTER_WIDTH];
-
- for (int l = 0; l < RASTER_HEIGHT/8; l++)
- {
- mask = 1;
- memset(line, 0, sizeof(line));
-
- do
- {
- for (int x = 0; x < RASTER_WIDTH; x++)
- {
- if (!cin.getline(buf, sizeof(buf)))
- goto print_line;
-
- istringstream ss(buf);
- string s;
- char c;
-
- ss
- >> s // skip glob coord spec
- >> c // skip open paren
- >> n; // this is the red level
-
- //DEBUG
- //cout << "s='" << s << "' n='" << n << "'" << endl;
-
- if (n < COLOR_THRESHOLD)
- line[x] |= mask;
- }
- }
- while (mask <<= 1);
-
-print_line:
- cout << "\n\t";
- for (int x = 0; x < RASTER_WIDTH; x++)
- {
- printf("0x%02X", line[x]);
- if (x % 8 == 7)
- cout << ",\n\t";
- else
- cout << ", ";
- }
- cout << endl;
- }
-
- return 0;
-}
+++ /dev/null
-
-#include "logo.h"
-#include <cfg/compiler.h>
-#include <mware/pgm.h>
-
-/**
- * BeRTOS logo
- */
-const PROGMEM uint8_t bertos_logo_raster[] = {
-
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- 0x00, 0xF8, 0xF8, 0xF8, 0x78, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x78, 0x70, 0xF0, 0xF0, 0xE0, 0x80, 0x00,
- 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x70, 0x70, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x70, 0xF0, 0xE0, 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, 0x00,
-
- 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xC0, 0xC0, 0xC0, 0xF1, 0x7F, 0x3F, 0x1F, 0x00,
- 0x00, 0xFE, 0xFF, 0xFF, 0x3F, 0x18, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x3F,
- 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x07, 0x1F, 0xFF, 0xFE, 0xFC,
- 0x00, 0x00, 0x07, 0x1F, 0x9F, 0xBC, 0xB8, 0xB8,
- 0x30, 0x30, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
- 0x70, 0xB0, 0xB0, 0xB8, 0xB8, 0xBC, 0x9E, 0x1F,
- 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
- 0x80, 0x00,
-
- 0x32, 0x3F, 0x3F, 0x3F, 0x3C, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x3C, 0x1C, 0x1F, 0x1F, 0x0F, 0x03,
- 0x00, 0x00, 0x00, 0x3F, 0x0D, 0x04, 0x04, 0x0C,
- 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x31,
- 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24,
- 0x24, 0x25,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
-
-};
-
-EXTERN_CONST struct Image bertos_logo =
-{
- /* .raster = */ bertos_logo_raster,
- /* .width = */ 82,
- /* .height = */ 64,
- /* .stride = */ 82
-};
-
+++ /dev/null
-#include <gfx/gfx.h>
-
-extern const struct Image bertos_logo;
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Virtual KFile I/O interface.
- * This module implements some generic I/O interfaces for kfile.
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- *
- */
-
-
-#include "kfile.h"
-#include <appconfig.h>
-
-#include <cfg/debug.h>
-#include <mware/formatwr.h>
-#include <string.h>
-
-/*
- * Sanity check for config parameters required by this module.
- */
-#if !defined(CONFIG_KFILE_GETS) || ((CONFIG_KFILE_GETS != 0) && CONFIG_KFILE_GETS != 1)
- #error CONFIG_KFILE_GETS must be set to either 0 or 1 in appconfig.h
-#endif
-#if !defined(CONFIG_PRINTF)
- #error CONFIG_PRINTF missing in appconfig.h
-#endif
-
-
-/**
- * Generic putc() implementation using \a fd->write.
- */
-int kfile_putc(int _c, struct KFile *fd)
-{
- unsigned char c = (unsigned char)_c;
-
- if (kfile_write(fd, &c, sizeof(c)) == sizeof(c))
- return (int)((unsigned char)_c);
- else
- return EOF;
-}
-
-/**
- * Generic getc() implementation using \a fd->read.
- */
-int kfile_getc(struct KFile *fd)
-{
- unsigned char c;
-
- if (kfile_read(fd, &c, sizeof(c)) == sizeof(c))
- return (int)((unsigned char)c);
- else
- return EOF;
-}
-
-#if CONFIG_PRINTF
-/**
- * Formatted write.
- */
-int kfile_printf(struct KFile *fd, const char *format, ...)
-{
- va_list ap;
- int len;
-
- va_start(ap, format);
- len = _formatted_write(format, (void (*)(char, void *))kfile_putc, fd, ap);
- va_end(ap);
-
- return len;
-}
-#endif /* CONFIG_PRINTF */
-
-/**
- * Write a string to kfile \a fd.
- * \return 0 if OK, EOF in case of error.
- */
-int kfile_print(struct KFile *fd, const char *s)
-{
- while (*s)
- {
- if (kfile_putc(*s++, fd) == EOF)
- return EOF;
- }
- return 0;
-}
-
-#if CONFIG_KFILE_GETS
-/**
- * Read a line long at most as size and put it
- * in buf.
- * \return number of chars read or EOF in case
- * of error.
- */
-int kfile_gets(struct KFile *fd, char *buf, int size)
-{
- return kfile_gets_echo(fd, buf, size, false);
-}
-
-
-/**
- * Read a line long at most as size and put it
- * in buf, with optional echo.
- *
- * \return number of chars read, or EOF in case
- * of error.
- */
-int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo)
-{
- int i = 0;
- int c;
-
- for (;;)
- {
- if ((c = kfile_getc(fd)) == EOF)
- {
- buf[i] = '\0';
- return -1;
- }
-
- /* FIXME */
- if (c == '\r' || c == '\n' || i >= size-1)
- {
- buf[i] = '\0';
- if (echo)
- kfile_print(fd, "\r\n");
- break;
- }
- buf[i++] = c;
- if (echo)
- kfile_putc(c, fd);
- }
-
- return i;
-}
-#endif /* !CONFIG_KFILE_GETS */
-
-
-/**
- * Move \a fd file seek position of \a offset bytes from \a whence.
- *
- * This is a generic implementation of seek function, you can redefine
- * it in your local module if needed.
- */
-kfile_off_t kfile_genericSeek(struct KFile *fd, kfile_off_t offset, KSeekMode whence)
-{
- uint32_t seek_pos;
-
- switch (whence)
- {
-
- case KSM_SEEK_SET:
- seek_pos = 0;
- break;
- case KSM_SEEK_END:
- seek_pos = fd->size;
- break;
- case KSM_SEEK_CUR:
- seek_pos = fd->seek_pos;
- break;
- default:
- ASSERT(0);
- return EOF;
- break;
- }
-
- /* Bound check */
- if (seek_pos + offset > fd->size)
- {
- ASSERT(0);
- return EOF;
- }
-
- fd->seek_pos = seek_pos + offset;
-
- return fd->seek_pos;
-}
-
-/**
- * Reopen file \a fd.
- * This is a generic implementation that only flush file
- * and reset seek_pos to 0.
- */
-struct KFile * kfile_genericReopen(struct KFile *fd)
-{
- kfile_flush(fd);
- kfile_seek(fd, 0, KSM_SEEK_SET);
- return fd;
-}
-
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Virtual KFile I/O interface.
- * KFile is a generic interface for file I/O.
- * It uses an object-oriented model to supply
- * a generic interface for drivers to communicate.
- * This module contains only definitions, the instance structure
- * and an API.
- * Each KFile user should implement at least some methods.
- * E.G.
- * If you have a serial driver and want to comply to KFile interface,
- * you have to declare your context structure:
- *
- * \code
- * typedef struct KFileSerial
- * {
- * KFile fd;
- * Serial *ser;
- * } KFileSerial;
- * \endcode
- *
- * You should also supply a macro for casting KFile to KFileSerial:
- *
- * \code
- * INLINE KFileSerial * KFILESERIAL(KFile *fd)
- * {
- * ASSERT(fd->_type == KFT_SERIAL);
- * return (KFileSerial *)fd;
- * }
- * \endcode
- *
- * Then you can implement as much interface functions as you like
- * and leave the others to NULL.
- * ser_close implementation example:
- *
- * \code
- * static int ser_kfile_close(struct KFile *fd)
- * {
- * KFileSerial *fds = KFILESERIAL(fd);
- * ser_close(fds->ser);
- * return 0;
- * }
- * \endcode
- * KFILESERIAL macro helps to ensure that obj passed is really a Serial.
- *
- * KFile interface do not supply the open function: this is deliberate,
- * because in embedded systems each device has its own init parameters.
- * For the same reason specific file settings (like baudrate for Serial, for example)
- * are demanded to specific driver implementation.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- */
-
-#ifndef KERN_KFILE_H
-#define KERN_KFILE_H
-
-#include <cfg/compiler.h>
-#include <cfg/debug.h>
-#include <cfg/macros.h>
-
-/* fwd decl */
-struct KFile;
-
-typedef int32_t kfile_off_t; ///< KFile offset type, used by kfile_seek function.
-
-/**
- * Costants for repositioning read/write file offset.
- * These are needed because on some embedded platforms
- * ANSI I/O library may not be present.
- */
-typedef enum KSeekMode
-{
- KSM_SEEK_SET, ///< Seek from file beginning.
- KSM_SEEK_CUR, ///< Seek from file current position.
- KSM_SEEK_END, ///< Seek from file end.
-} KSeekMode;
-
-/**
- * Prototypes for KFile access functions.
- * I/O file functions must be ANSI compliant.
- * \note A KFile user can choose which function subset to implement,
- * but has to set to NULL unimplemented features.
- * \{
- */
-
-/**
- * Read from file.
- * \return the number of bytes read.
- */
-typedef size_t (*ReadFunc_t) (struct KFile *fd, void *buf, size_t size);
-
-/**
- * Write to file.
- * \return the number of bytes written.
- */
-typedef size_t (*WriteFunc_t) (struct KFile *fd, const void *buf, size_t size);
-
-/**
- * Seek into file (if seekable).
- * \return the new file offset or EOF on errors.
- */
-typedef kfile_off_t (*SeekFunc_t) (struct KFile *fd, kfile_off_t offset, KSeekMode whence);
-
-/**
- * Close and reopen file \a fd.
- * The reopening is done with the former file parameters and access modes.
- */
-typedef struct KFile * (*ReOpenFunc_t) (struct KFile *fd);
-
-/**
- * Close file.
- * \return 0 on success, EOF on errors.
- */
-typedef int (*CloseFunc_t) (struct KFile *fd);
-
-/**
- * Flush file I/O.
- * \return 0 on success, EOF on errors.
- */
-typedef int (*FlushFunc_t) (struct KFile *fd);
-
-/**
- * Get file error mask.
- * \return 0 on success or file error code, device specific.
- */
-typedef int (*ErrorFunc_t) (struct KFile *fd);
-
-/**
- * Clear errors.
- */
-typedef void (*ClearErrFunc_t) (struct KFile *fd);
-/* \} */
-
-/**
- * Context data for callback functions which operate on
- * pseudo files.
- * \note If you change interface, remember to add corresponding access function.
- */
-typedef struct KFile
-{
- ReadFunc_t read;
- WriteFunc_t write;
- ReOpenFunc_t reopen;
- CloseFunc_t close;
- SeekFunc_t seek;
- FlushFunc_t flush;
- ErrorFunc_t error;
- ClearErrFunc_t clearerr;
- DB(id_t _type); ///< Used to keep trace, at runtime, of obj type.
-
- /* NOTE: these must _NOT_ be size_t on 16bit CPUs! */
- uint32_t seek_pos;
- uint32_t size;
-} KFile;
-
-/**
- * Generic implementation of kfile_seek.
- */
-kfile_off_t kfile_genericSeek(struct KFile *fd, kfile_off_t offset, KSeekMode whence);
-
-/**
- * Generic implementation of kfile_reopen.
- */
-struct KFile * kfile_genericReopen(struct KFile *fd);
-
-int kfile_putc(int c, struct KFile *fd); ///< Generic putc implementation using kfile_write.
-int kfile_getc(struct KFile *fd); ///< Generic getc implementation using kfile_read.
-int kfile_printf(struct KFile *fd, const char *format, ...);
-int kfile_print(struct KFile *fd, const char *s);
-int kfile_gets(struct KFile *fd, char *buf, int size);
-int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo);
-
-/**
- * Interface functions for KFile access.
- * \note Remember to change following functions if KFile interface changes.
- * \{
- */
-INLINE size_t kfile_read(struct KFile *fd, void *buf, size_t size)
-{
- ASSERT(fd->read);
- return fd->read(fd, buf, size);
-}
-
-INLINE size_t kfile_write(struct KFile *fd, const void *buf, size_t size)
-{
- ASSERT(fd->write);
- return fd->write(fd, buf, size);
-}
-
-INLINE KFile * kfile_reopen(struct KFile *fd)
-{
- ASSERT(fd->reopen);
- return fd->reopen(fd);
-}
-
-INLINE int kfile_close(struct KFile *fd)
-{
- ASSERT(fd->close);
- return fd->close(fd);
-}
-
-INLINE kfile_off_t kfile_seek(struct KFile *fd, kfile_off_t offset, KSeekMode whence)
-{
- ASSERT(fd->seek);
- return fd->seek(fd, offset, whence);
-}
-
-INLINE int kfile_flush(struct KFile *fd)
-{
- ASSERT(fd->flush);
- return fd->flush(fd);
-}
-
-INLINE int kfile_error(struct KFile *fd)
-{
- ASSERT(fd->error);
- return fd->error(fd);
-}
-
-INLINE void kfile_clearerr(struct KFile *fd)
-{
- ASSERT(fd->clearerr);
- fd->clearerr(fd);
-}
-/* \} */
-
-/**
- * Kfile test function.
- */
-bool kfile_test(KFile *fd, uint8_t *test_buf, uint8_t *save_buf, size_t size);
-
-#endif /* KERN_KFILE_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Test suite for virtual KFile I/O interface.
- * This module implements a test for some generic I/O interfaces for kfile.
- *
- * \version $Id$
- * \author Francesco Sacchi <batt@develer.com>
- * \author Daniele Basile <asterix@develer.com>
- *
- */
-
-
-#include "kfile.h"
-#include <appconfig.h>
-
-#include <cfg/debug.h>
-#include <mware/formatwr.h>
-#include <string.h>
-
-/**
- * KFile read/write subtest.
- * Try to write/read in the same \a f file location \a size bytes.
- * \return true if all is ok, false otherwise
- * \note Restore file position at exit (if no error)
- * \note Test buffer \a buf must be filled with
- * the following statement:
- * <pre>
- * buf[i] = i & 0xff
- * </pre>
- */
-static bool kfile_rwTest(KFile *f, uint8_t *buf, size_t size)
-{
- /*
- * Write test buffer
- */
- if (kfile_write(f, buf, size) != size)
- return false;
-
- kfile_seek(f, -(kfile_off_t)size, KSM_SEEK_CUR);
-
- /*
- * Reset test buffer
- */
- memset(buf, 0, size);
-
- /*
- * Read file in test buffer
- */
- if (kfile_read(f, buf, size) != size)
- return false;
- kfile_seek(f, -(kfile_off_t)size, KSM_SEEK_CUR);
-
- /*
- * Check test result
- */
- for (size_t i = 0; i < size; i++)
- if (buf[i] != (i & 0xff))
- return false;
-
- return true;
-}
-
-/**
- * KFile read/write test.
- * This function write and read \a test_buf long \a size
- * on \a fd handler.
- * \a save_buf can be NULL or a buffer where to save previous file content.
- */
-bool kfile_test(KFile *fd, uint8_t *test_buf, uint8_t *save_buf, size_t size)
-{
- /*
- * Part of test buf size that you would write.
- * This var is used in test 3 to check kfile_write
- * when writing beyond filesize limit.
- */
- kfile_off_t len = size / 2;
-
-
- /* Fill test buffer */
- for (size_t i = 0; i < size; i++)
- test_buf[i] = (i & 0xff);
-
- /*
- * If necessary, user can save content,
- * for later restore.
- */
- if (save_buf)
- {
- kfile_read(fd, save_buf, size);
- kprintf("Saved content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
- }
-
- /* TEST 1 BEGIN. */
- kprintf("Test 1: write from pos 0 to [%lu]\n", size);
-
- /*
- * Seek to addr 0.
- */
- if (kfile_seek(fd, 0, KSM_SEEK_SET) != 0)
- goto kfile_test_end;
-
- /*
- * Test read/write to address 0..size
- */
- if (!kfile_rwTest(fd, test_buf, size))
- goto kfile_test_end;
-
- kprintf("Test 1: ok!\n");
-
- /*
- * Restore previous read content.
- */
- if (save_buf)
- {
- kfile_seek(fd, 0, KSM_SEEK_SET);
-
- if (kfile_write(fd, save_buf, size) != size)
- goto kfile_test_end;
-
- kprintf("Restore content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
- }
- /* TEST 1 END. */
-
- /* TEST 2 BEGIN. */
- kprintf("Test 2: write from pos [%lu] to [%lu]\n", fd->size/2 , fd->size/2 + size);
-
- /*
- * Go to half test size.
- */
- kfile_seek(fd, (fd->size / 2), KSM_SEEK_SET);
-
- /*
- * If necessary, user can save content
- * for later restore.
- */
- if (save_buf)
- {
- kfile_read(fd, save_buf, size);
- kfile_seek(fd, -(kfile_off_t)size, KSM_SEEK_CUR);
- kprintf("Saved content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
- }
-
- /*
- * Test read/write to address filesize/2 ... filesize/2 + size
- */
- if (!kfile_rwTest(fd, test_buf, size))
- goto kfile_test_end;
-
- kprintf("Test 2: ok!\n");
-
- /*
- * Restore previous content.
- */
- if (save_buf)
- {
- kfile_seek(fd, -(kfile_off_t)size, KSM_SEEK_CUR);
-
- if (kfile_write(fd, save_buf, size) != size)
- goto kfile_test_end;
-
- kprintf("Restore content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + size);
- }
-
- /* TEST 2 END. */
-
- /* TEST 3 BEGIN. */
- kprintf("Test 3: write outside of fd->size limit [%lu]\n", fd->size);
- kprintf("This test should FAIL!, you must see an assertion fail message.\n");
-
- /*
- * Go to the Flash end
- */
- kfile_seek(fd, -len, KSM_SEEK_END);
-
- /*
- * If necessary, user can save content,
- * for later restore.
- */
- if (save_buf)
- {
- kfile_read(fd, save_buf, len);
- kfile_seek(fd, -len, KSM_SEEK_CUR);
- kprintf("Saved content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + len);
- }
-
- /*
- * Test read/write to address (filesize - size) ... filesize
- */
- if (kfile_rwTest(fd, test_buf, size))
- goto kfile_test_end;
-
- kprintf("Test 3: ok!\n");
-
- /*
- * Restore previous read content
- */
- if (save_buf)
- {
- kfile_seek(fd, -len, KSM_SEEK_END);
-
- if (kfile_write(fd, save_buf, len) != len)
- goto kfile_test_end;
-
- kprintf("Restore content..form [%lu] to [%lu]\n", fd->seek_pos, fd->seek_pos + len);
- }
-
- /* TEST 3 END. */
-
- kfile_close(fd);
- return true;
-
-kfile_test_end:
- kfile_close(fd);
- return false;
-}
-
-
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Monitor to check for stack overflows
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-
-#include "monitor.h"
-
-#if CONFIG_KERN_MONITOR
-
-#include "proc_p.h"
-#include <mware/list.h>
-#include <drv/timer.h>
-#include <kern/proc.h>
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-
-static List MonitorProcs;
-
-
-void monitor_init(void)
-{
- LIST_INIT(&MonitorProcs);
-}
-
-
-void monitor_add(Process* proc, const char* name, cpustack_t* stack_base, size_t stack_size)
-{
- proc->monitor.name = name;
- proc->monitor.stack_base = stack_base;
- proc->monitor.stack_size = stack_size;
-
- ADDTAIL(&MonitorProcs, &proc->monitor.link);
-}
-
-
-void monitor_remove(Process* proc)
-{
- REMOVE(&proc->monitor.link);
-}
-
-void monitor_rename(Process *proc, const char* name)
-{
- proc->monitor.name = name;
-}
-
-/* TODO: use containerof() */
-#define MONITOR_NODE_TO_PROCESS(node) \
- (struct Process *)((intptr_t)(node) - offsetof(struct Process, monitor.link))
-
-size_t monitor_checkStack(cpustack_t* stack_base, size_t stack_size)
-{
- cpustack_t* beg;
- cpustack_t* cur;
- cpustack_t* end;
- size_t sp_free;
-
- beg = stack_base;
- end = stack_base + stack_size / sizeof(cpustack_t) - 1;
-
- if (CPU_STACK_GROWS_UPWARD)
- {
- cur = beg;
- beg = end;
- end = cur;
- }
-
- cur = beg;
- while (cur != end)
- {
- if (*cur != CONFIG_KERN_STACKFILLCODE)
- break;
-
- if (CPU_STACK_GROWS_UPWARD)
- cur--;
- else
- cur++;
- }
-
- sp_free = ABS(cur - beg) * sizeof(cpustack_t);
- return sp_free;
-}
-
-
-void monitor_report(void)
-{
- struct Process* p;
- int i;
-
- if (LIST_EMPTY(&MonitorProcs))
- {
- kputs("No stacks registered in the monitor\n");
- return;
- }
-
- kprintf("%-24s%-8s%-8s%-8s%-8s\n", "Process name", "TCB", "SPbase", "SPsize", "SPfree");
- for (i=0;i<56;i++)
- kputchar('-');
- kputchar('\n');
-
- for (p = MONITOR_NODE_TO_PROCESS(LIST_HEAD(&MonitorProcs));
- p->monitor.link.succ;
- p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
- {
- size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
- kprintf("%-24s%-8p%-8p%-8lu%-8lu\n",
- p->monitor.name, p, p->monitor.stack_base, p->monitor.stack_size, free);
- }
-}
-
-
-static void NORETURN monitor(void)
-{
- struct Process *p;
-
- while (1)
- {
- for (p = MONITOR_NODE_TO_PROCESS(LIST_HEAD(&MonitorProcs));
- p->monitor.link.succ;
- p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
- {
- size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
-
- if (free < 0x20)
- kprintf("MONITOR: WARNING: Free stack for process '%s' is only %u chars\n",
- p->monitor.name, (unsigned int)free);
-
- timer_delay(500);
- }
- }
-}
-
-
-void monitor_start(size_t stacksize, cpustack_t *stack)
-{
- proc_new(monitor, NULL, stacksize, stack);
-}
-
-#endif /* CONFIG_KERN_MONITOR */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Monitor to check for stack overflows
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-#ifndef KERN_MONITOR_H
-#define KERN_MONITOR_H
-
-#include <cpu/types.h>
-#include <config_kern.h>
-
-#if CONFIG_KERN_MONITOR
-
-/**
- * Start the kernel monitor. It is a special process which checks every second the stacks of the
- * running processes trying to detect stack overflows.
- *
- * \param stacksize Size of stack in chars
- * \param stack Pointer to the stack that will be used by the monitor
- *
- * \note The stack is provided by the caller so that there is no wasted space if the monitor
- * is not used.
- */
-void monitor_start(size_t stacksize, cpustack_t *stack);
-
-
-/**
- * Manually check if a given stack has overflown. This is used to check for stacks
- * of processes handled externally form the kernel, or for other stacks (for instance
- * the interrupt supervisor stack).
- *
- * \note For this function to work, the stack must have been filled at startup with
- * CONFIG_KERN_STACKFILLCODE.
- */
-size_t monitor_checkStack(cpustack_t *stack_base, size_t stack_size);
-
-
-/** Print a report of the stack status through kdebug */
-void monitor_report(void);
-
-
-#endif /* CONFIG_KERN_MONITOR */
-#endif /* KERN_MONITOR_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- *
- * This module implements a common system for executing
- * a user defined action calling a hook function.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Simple inter-process messaging system
- *
- * Handle queues of messages associated an action.
- *
- * A message port is an abstraction used to exchange information
- * asynchronously between processes or other entities such as
- * interrupts and call-back functions.
- *
- * This form of IPC is higher-level than bare signals and
- * semaphores, because it sets a policy for exchanging
- * structured data with well-defined synchronization and
- * ownership semantics.
- *
- * Before using it, a message port must be initialized by
- * calling msg_initPort(), which associates the port with
- * an Event object, which can be setup to signal a process
- * or invoke a call-back hook.
- *
- * A process or interrupt routine can deliver messages to any
- * message port by calling msg_put(). By sending a message,
- * the sender temporarly or permanently transfers ownership
- * of its associated data to the receiver.
- *
- * Queuing a message to a port automatically triggers the
- * associated Event to notify the receiver. When the
- * receiver wakes up, it usually invokes msg_get() to pick
- * the next message from the port.
- *
- * Message ports can hold any number of pending messages,
- * and receivers usually process them in FIFO order.
- * Other scheduling policies are possible, but not implemented
- * in this API.
- *
- * After the receiver has done processing a message, it replies
- * it back to the sender with msg_reply(), which transfer
- * ownership back to the original sender. Replies are delivered
- * to a reply port, which is nothing more than another MsgPort
- * structure designated by the sender.
- *
- * Returning messages to senders is not mandatory, but it provides
- * a convenient way to provide some kind of result and simplify
- * the resource allocation scheme at the same time.
- *
- * When using signals to receive messages in a process, you
- * call sig_wait() in an event-loop to wake up when messages
- * are delivered to any of your ports. When your process
- * wakes up with the port signal active, multiple messages
- * may already have queued up at the message port, and the
- * process must process them all before returning to sleep.
- * Signals don't keep a nesting count.
- *
- * A simple message loop works like this:
- *
- * \code
- * // Our message port.
- * static MsgPort test_port;
- *
- * // A test message with two parameters and a result.
- * typedef struct
- * {
- * Msg msg;
- *
- * int x, y;
- * int result;
- * } TestMsg;
- *
- *
- * // A process that sends two messages and waits for replies.
- * static void sender_proc(void)
- * {
- * MsgPort test_reply_port;
- * TestMsg msg1;
- * TestMsg msg2;
- * Msg *reply;
- *
- * msg_initPort(&reply_port,
- * event_createSignal(proc_current(), SIGF_SINGLE);
- *
- * // Fill-in first message and send it out.
- * msg1.x = 3;
- * msg1.y = 2;
- * msg1.msg.replyPort = &test_reply_port;
- * msg_put(&test_port, &msg1);
- *
- * // Fill-in second message and send it out too.
- * msg2.x = 5;
- * msg2.y = 4;
- * msg2.msg.replyPort = &test_reply_port;
- * msg_put(&test_port, &msg1);
- *
- * // Wait for a reply...
- * sig_wait(SIG_SINGLE);
- *
- * reply = (TestMsg *)msg_get(&test_reply_port);
- * ASSERT(reply != NULL);
- * ASSERT(reply->result == 5);
- *
- * // Get reply to second message.
- * while (!(reply = (TestMsg *)msg_get(&test_reply_port))
- * {
- * // Not yet, be patient and wait some more.
- * sig_wait(SIG_SINGLE);
- * }
- *
- * ASSERT(reply->result == 9);
- * }
- *
- *
- * // Receive messages and do something boring with them.
- * static void receiver_proc(void)
- * {
- * msg_initPort(&test_port,
- * event_createSignal(proc_current(), SIGF_EXAMPLE);
- *
- * proc_new(sender_proc, (iptr_t)&test_port,
- * sender_stack, sizeof(sender_stack);
- *
- * for (;;)
- * {
- * sigmask_t sigs = sig_wait(SIGF_EXAMPLE | more_signals);
- *
- * if (sigs & SIGF_EXAMPLE)
- * {
- * TestMsg *emsg;
- * while (emsg = (TestMsg *)msg_get(&test_port)
- * {
- * // Do something with the message
- * emsg->result = emsg->x + emsg->y;
- * msg_reply((Msg *)msg);
- * }
- * }
- * }
- * }
- * \endcode
- */
-
- */
-
-#ifndef KERN_MSG_H
-#define KERN_MSG_H
-
-#include "event.h"
-#include <mware/list.h>
-
-
-typedef struct MsgPort
-{
- List queue; /**< Messages queued at this port. */
- Event event; /**< Event to trigger when a message arrives. */
-} MsgPort;
-
-
-typedef struct Msg
-{
- Node link; /**< Link into message port queue. */
- MsgPort *replyPort; /**< Port to which the msg is to be replied. */
- /* User data may follow */
-} Msg;
-
-
-/**
- * Lock a message port.
- *
- * This is required before reading or manipulating
- * any field of the MsgPort structure.
- *
- * \note Ports may be locked multiple times and each
- * call to msg_lockPort() must be paired with
- * a corresponding call to msg_unlockPort().
- *
- * \todo Add a configurable policy for locking against
- * interrupts and locking with semaphorse.
- *
- * \see msg_unlockPort()
- */
-INLINE void msg_lockPort(MsgPort *port)
-{
- proc_forbid();
-}
-
-/**
- * Unlock a message port.
- *
- * \see msg_lockPort()
- */
-INLINE void msg_unlockPort(MsgPort *port)
-{
- proc_permit();
-}
-
-
-/** Initialize a message port */
-INLINE void msg_initPort(MsgPort *port, Event event)
-{
- LIST_INIT(&port->queue);
- port->event = event;
-}
-
-/** Queue \a msg into \a port, triggering the associated event */
-INLINE void msg_put(MsgPort *port, Msg *msg)
-{
- msg_portLock(port);
- ADDTAIL(&port->queue, &msg->link);
- msg_portUnlock(port);
-
- event_do(&port->event);
-}
-
-/**
- * Get the first message from the queue of \a port.
- *
- * \return Pointer to the message or NULL if the port was empty.
- */
-INLINE Msg *msg_get(MsgPort *port)
-{
- Msg *msg;
-
- msg_portLock(port);
- msg = (Msg *)REMHEAD(&port->queue);
- msg_portUnlock(port);
-
- return msg;
-}
-
-/** Peek the first message in the queue of \a port, or NULL if the port is empty. */
-INLINE Msg *msg_peek(MsgPort *port)
-{
- Msg *msg;
-
- msg_portLock(port);
- msg = (Msg *)port->queue.head;
- if (ISLISTEMPTY(&port->queue))
- msg = NULL;
- msg_portUnlock(port);
-
- return msg;
-}
-
-/** Send back (reply) \a msg to its sender. */
-INLINE void msg_reply(Msg *msg)
-{
- msg_put(msg->replyPort, msg);
-}
-
-#endif /* KERN_MSG_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Simple realtime multitasking scheduler.
- * Context switching is only done cooperatively.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-
-#include "proc_p.h"
-#include "proc.h"
-//#include "hw.h"
-#include <mware/event.h>
-#include <cpu/irq.h>
-#include <cpu/types.h>
-#include <cpu/attr.h>
-#include <cfg/debug.h>
-#include <cfg/module.h>
-#include <cfg/arch_config.h> /* ARCH_EMUL */
-#include <cfg/macros.h> /* ABS() */
-
-#include <string.h> /* memset() */
-
-/**
- * CPU dependent context switching routines.
- *
- * \note This function *MUST* preserve also the status of the interrupts.
- */
-EXTERN_C void asm_switch_context(cpustack_t **new_sp, cpustack_t **save_sp);
-EXTERN_C int asm_switch_version(void);
-
-/*
- * The scheduer tracks ready and waiting processes
- * by enqueuing them in these lists. A pointer to the currently
- * running process is stored in the CurrentProcess pointer.
- *
- * NOTE: these variables are protected by DI/EI locking
- */
-REGISTER Process *CurrentProcess;
-REGISTER List ProcReadyList;
-
-
-#if CONFIG_KERN_PREEMPTIVE
-/*
- * The time sharing scheduler forces a task switch when
- * the current process has consumed its quantum.
- */
-uint16_t Quantum;
-#endif
-
-
-/* In Win32 we must emulate stack on the real process stack */
-#if (ARCH & ARCH_EMUL)
-extern List StackFreeList;
-#endif
-
-/** The main process (the one that executes main()). */
-struct Process MainProcess;
-
-
-static void proc_init_struct(Process *proc)
-{
- /* Avoid warning for unused argument. */
- (void)proc;
-
-#if CONFIG_KERN_SIGNALS
- proc->sig_recv = 0;
-#endif
-
-#if CONFIG_KERN_PREEMPTIVE
- proc->forbid_cnt = 0;
-#endif
-
-#if CONFIG_KERN_HEAP
- proc->flags = 0;
-#endif
-}
-
-MOD_DEFINE(proc);
-
-void proc_init(void)
-{
- LIST_INIT(&ProcReadyList);
-
-#if CONFIG_KERN_MONITOR
- monitor_init();
-#endif
-
- /* We "promote" the current context into a real process. The only thing we have
- * to do is create a PCB and make it current. We don't need to setup the stack
- * pointer because it will be written the first time we switch to another process.
- */
- proc_init_struct(&MainProcess);
- CurrentProcess = &MainProcess;
-
- /* Make sure the assembly routine is up-to-date with us */
- ASSERT(asm_switch_version() == 1);
- MOD_INIT(proc);
-}
-
-
-/**
- * Create a new process, starting at the provided entry point.
- *
- * \return Process structure of new created process
- * if successful, NULL otherwise.
- */
-struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(void), iptr_t data, size_t stacksize, cpustack_t *stack_base)
-{
- Process *proc;
- size_t i;
- size_t proc_size_words = ROUND2(sizeof(Process), sizeof(cpustack_t)) / sizeof(cpustack_t);
-#if CONFIG_KERN_HEAP
- bool free_stack = false;
-#endif
-
-#if (ARCH & ARCH_EMUL)
- /* Ignore stack provided by caller and use the large enough default instead. */
- stack_base = (cpustack_t *)LIST_HEAD(&StackFreeList);
- REMOVE(LIST_HEAD(&StackFreeList));
- stacksize = CONFIG_PROC_DEFSTACKSIZE;
-#elif CONFIG_KERN_HEAP
- /* Did the caller provide a stack for us? */
- if (!stack_base)
- {
- /* Did the caller specify the desired stack size? */
- if (!stacksize)
- stacksize = CONFIG_PROC_DEFSTACKSIZE + sizeof(Process);
-
- /* Allocate stack dinamically */
- if (!(stack_base = heap_alloc(stacksize)))
- return NULL;
-
- free_stack = true;
- }
-#else
- /* Stack must have been provided by the user */
- ASSERT(stack_base);
- ASSERT(stacksize);
-#endif
-
-#if CONFIG_KERN_MONITOR
- /* Fill-in the stack with a special marker to help debugging */
- memset(stack_base, CONFIG_KERN_STACKFILLCODE, stacksize / sizeof(cpustack_t));
-#endif
-
- /* Initialize the process control block */
- if (CPU_STACK_GROWS_UPWARD)
- {
- proc = (Process*)stack_base;
- proc->stack = stack_base + proc_size_words;
- if (CPU_SP_ON_EMPTY_SLOT)
- proc->stack++;
- }
- else
- {
- proc = (Process*)(stack_base + stacksize / sizeof(cpustack_t) - proc_size_words);
- proc->stack = (cpustack_t*)proc;
- if (CPU_SP_ON_EMPTY_SLOT)
- proc->stack--;
- }
-
- proc_init_struct(proc);
- proc->user_data = data;
-
-#if CONFIG_KERN_HEAP
- proc->stack_base = stack_base;
- proc->stack_size = stack_size;
- if (free_stack)
- proc->flags |= PF_FREESTACK;
-#endif
-
- /* Initialize process stack frame */
- CPU_PUSH_CALL_CONTEXT(proc->stack, proc_exit);
- CPU_PUSH_CALL_CONTEXT(proc->stack, entry);
-
- /* Push a clean set of CPU registers for asm_switch_context() */
- for (i = 0; i < CPU_SAVED_REGS_CNT; i++)
- CPU_PUSH_WORD(proc->stack, CPU_REG_INIT_VALUE(i));
-
- /* Add to ready list */
- ATOMIC(SCHED_ENQUEUE(proc));
-
-#if CONFIG_KERN_MONITOR
- monitor_add(proc, name, stack_base, stacksize);
-#endif
-
- return proc;
-}
-
-/** Rename a process */
-void proc_rename(struct Process *proc, const char *name)
-{
-#if CONFIG_KERN_MONITOR
- monitor_rename(proc, name);
-#else
- (void)proc; (void)name;
-#endif
-}
-
-
-/**
- * System scheduler: pass CPU control to the next process in
- * the ready queue.
- *
- * Saving and restoring the context on the stack is done
- * by a CPU-dependent support routine which must usually be
- * written in assembly.
- */
-void proc_schedule(void)
-{
- struct Process *old_process;
- cpuflags_t flags;
-
- /* Remember old process to save its context later */
- old_process = CurrentProcess;
-
-#ifdef IRQ_RUNNING
- /* Scheduling in interrupts is a nono. */
- ASSERT(!IRQ_RUNNING());
-#endif
-
- /* Poll on the ready queue for the first ready process */
- IRQ_SAVE_DISABLE(flags);
- while (!(CurrentProcess = (struct Process *)list_remHead(&ProcReadyList)))
- {
- /*
- * Make sure we physically reenable interrupts here, no matter what
- * the current task status is. This is important because if we
- * are idle-spinning, we must allow interrupts, otherwise no
- * process will ever wake up.
- *
- * During idle-spinning, can occur an interrupt, it may be able to
- * modify \p ProcReadyList. To ensure that compiler reload this
- * variable every while cycle we call CPU_MEMORY_BARRIER.
- * The memory barrier ensure that all variables used in this context
- * are reloaded.
- * \todo If there was a way to write sig_wait() so that it does not
- * disable interrupts while waiting, there would not be any
- * reason to do this.
- */
- IRQ_ENABLE;
- CPU_IDLE;
- MEMORY_BARRIER;
- IRQ_DISABLE;
- }
- IRQ_RESTORE(flags);
-
- /*
- * Optimization: don't switch contexts when the active
- * process has not changed.
- */
- if (CurrentProcess != old_process)
- {
- cpustack_t *dummy;
-
-#if CONFIG_KERN_PREEMPTIVE
- /* Reset quantum for this process */
- Quantum = CONFIG_KERN_QUANTUM;
-#endif
-
- /* Save context of old process and switch to new process. If there is no
- * old process, we save the old stack pointer into a dummy variable that
- * we ignore. In fact, this happens only when the old process has just
- * exited.
- * TODO: Instead of physically clearing the process at exit time, a zombie
- * list should be created.
- */
- asm_switch_context(&CurrentProcess->stack, old_process ? &old_process->stack : &dummy);
- }
-
- /* This RET resumes the execution on the new process */
-}
-
-
-/**
- * Terminate the current process
- */
-void proc_exit(void)
-{
-#if CONFIG_KERN_MONITOR
- monitor_remove(CurrentProcess);
-#endif
-
-#if CONFIG_KERN_HEAP
- /*
- * The following code is BROKEN.
- * We are freeing our own stack before entering proc_schedule()
- * BAJO: A correct fix would be to rearrange the scheduler with
- * an additional parameter which frees the old stack/process
- * after a context switch.
- */
- if (CurrentProcess->flags & PF_FREESTACK)
- heap_free(CurrentProcess->stack_base, CurrentProcess->stack_size);
- heap_free(CurrentProcess);
-#endif
-
-#if (ARCH & ARCH_EMUL)
-#warning This is wrong
- /* Reinsert process stack in free list */
- ADDHEAD(&StackFreeList, (Node *)(CurrentProcess->stack
- - (CONFIG_PROC_DEFSTACKSIZE / sizeof(cpustack_t))));
-
- /*
- * NOTE: At this point the first two words of what used
- * to be our stack contain a list node. From now on, we
- * rely on the compiler not reading/writing the stack.
- */
-#endif /* ARCH_EMUL */
-
- CurrentProcess = NULL;
- proc_schedule();
- /* not reached */
-}
-
-
-/**
- * Co-operative context switch
- */
-void proc_switch(void)
-{
- cpuflags_t flags;
-
- IRQ_SAVE_DISABLE(flags);
- SCHED_ENQUEUE(CurrentProcess);
- IRQ_RESTORE(flags);
-
- proc_schedule();
-}
-
-
-/**
- * Get the pointer to the current process
- */
-struct Process *proc_current(void)
-{
- return CurrentProcess;
-}
-
-/**
- * Get the pointer to the user data of the current process
- */
-iptr_t proc_current_user_data(void)
-{
- return CurrentProcess->user_data;
-}
-
-
-#if CONFIG_KERN_PREEMPTIVE
-
-/**
- * Disable preemptive task switching.
- *
- * The scheduler maintains a per-process nesting counter. Task switching is
- * effectively re-enabled only when the number of calls to proc_permit()
- * matches the number of calls to proc_forbid().
- *
- * Calling functions that could sleep while task switching is disabled
- * is dangerous, although supported. Preemptive task switching is
- * resumed while the process is sleeping and disabled again as soon as
- * it wakes up again.
- *
- * \sa proc_permit()
- */
-void proc_forbid(void)
-{
- /* No need to protect against interrupts here. */
- ++CurrentProcess->forbid_cnt;
-}
-
-/**
- * Re-enable preemptive task switching.
- *
- * \sa proc_forbid()
- */
-void proc_permit(void)
-{
- /* No need to protect against interrupts here. */
- --CurrentProcess->forbid_cnt;
-}
-
-#endif /* CONFIG_KERN_PREEMPTIVE */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Process scheduler (public interface).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-#ifndef KERN_PROC_H
-#define KERN_PROC_H
-
-#include <cfg/compiler.h>
-#include <cpu/irq.h>
-#include <config_kern.h>
-
-/* Fwd decl */
-struct Process;
-
-/* Task scheduling services */
-void proc_init(void);
-struct Process *proc_new_with_name(const char* name, void (*entry)(void), iptr_t data, size_t stacksize, cpustack_t *stack);
-
-#if !CONFIG_KERN_MONITOR
- #define proc_new(entry,data,size,stack) proc_new_with_name(NULL,(entry),(data),(size),(stack))
-#else
- #define proc_new(entry,data,size,stack) proc_new_with_name(#entry,(entry),(data),(size),(stack))
-#endif
-
-void proc_exit(void);
-void proc_switch(void);
-void proc_test(void);
-struct Process *proc_current(void);
-iptr_t proc_current_user_data(void);
-void proc_rename(struct Process *proc, const char* name);
-
-#if CONFIG_KERN_PREEMPTIVE
- void proc_forbid(void);
- void proc_permit(void);
-#else
- INLINE void proc_forbid(void) { /* nop */ }
- INLINE void proc_permit(void) { /* nop */ }
-#endif
-
-/**
- * Execute a block of \a CODE atomically with respect to task scheduling.
- */
-#define PROC_ATOMIC(CODE) \
- do { \
- proc_forbid(); \
- CODE; \
- proc_permit(); \
- } while(0)
-
-#endif /* KERN_PROC_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2001, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Internal scheduler structures and definitions for processes.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef KERN_PROC_P_H
-#define KERN_PROC_P_H
-
-#include <cfg/compiler.h>
-#include <cpu/types.h> /* for cpu_stack_t */
-#include <mware/list.h>
-#include <config_kern.h>
-#include <appconfig.h>
-
-typedef struct Process
-{
- Node link; /**< Link Process into scheduler lists */
- cpustack_t *stack; /**< Per-process SP */
- iptr_t user_data; /**< Custom data passed to the process */
-
-#if CONFIG_KERN_SIGNALS
- sigmask_t sig_wait; /**< Signals the process is waiting for */
- sigmask_t sig_recv; /**< Received signals */
-#endif
-
-#if CONFIG_KERN_PREEMPTIVE
- int forbid_cnt; /**< Nesting count for proc_forbid()/proc_permit(). */
-#endif
-
-#if CONFIG_KERN_HEAP
- uint16_t flags; /**< Flags */
- cpustack_t *stack_base; /**< Base of process stack */
- size_t stack_size; /**< Size of process stack */
-#endif
-
-#if CONFIG_KERN_MONITOR
- struct ProcMonitor
- {
- Node link;
- const char *name;
- cpustack_t *stack_base;
- size_t stack_size;
- } monitor;
-#endif
-
-} Process;
-
-
-/**
- * \name Flags for Process.flags.
- * \{
- */
-#define PF_FREESTACK BV(0) /**< Free the stack when process dies */
-/*\}*/
-
-
-/** Track running processes. */
-extern REGISTER Process *CurrentProcess;
-
-/** Track ready processes. */
-extern REGISTER List ProcReadyList;
-
-
-/** Enqueue a task in the ready list. */
-#define SCHED_ENQUEUE(proc) ADDTAIL(&ProcReadyList, &(proc)->link)
-
-/** Schedule to another process *without* adding the current to the ready list. */
-void proc_schedule(void);
-
-#if CONFIG_KERN_MONITOR
- /** Initialize the monitor */
- void monitor_init(void);
-
- /** Register a process into the monitor */
- void monitor_add(Process *proc, const char *name, cpustack_t *stack, size_t stacksize);
-
- /** Unregister a process from the monitor */
- void monitor_remove(Process *proc);
-
- /** Rename a process */
- void monitor_rename(Process *proc, const char* name);
-#endif /* CONFIG_KERN_MONITOR */
-
-#endif /* KERN_PROC_P_H */
-
+++ /dev/null
-
-#include <kern/proc.h>
-#include <drv/timer.h>
-
-/**
- * Proc scheduling test subthread 1
- */
-static void NORETURN proc_test_thread1(void)
-{
- for (;;)
- {
- kputs(">task 1\n");
- timer_delay(50);
- proc_switch();
- }
-}
-
-/**
- * Proc scheduling test subthread 2
- */
-static void NORETURN proc_test_thread2(void)
-{
- for (;;)
- {
- kputs(">task 2\n");
- timer_delay(75);
- proc_switch();
- }
-}
-
-static cpustack_t proc_test_stack1[CONFIG_PROC_DEFSTACKSIZE / sizeof(cpustack_t)];
-static cpustack_t proc_test_stack2[CONFIG_PROC_DEFSTACKSIZE / sizeof(cpustack_t)];
-
-/**
- * Proc scheduling test
- */
-void NORETURN proc_test(void)
-{
- proc_new(proc_test_thread1, NULL, sizeof(proc_test_stack1), proc_test_stack1);
- proc_new(proc_test_thread2, NULL, sizeof(proc_test_stack2), proc_test_stack2);
- kputs("Created tasks\n");
-
- kputs("stack1:\n");
-// #warning FIXME
- kdump(proc_test_stack1+sizeof(proc_test_stack1)-64, 64);
- kputs("stack2:\n");
-// #warning FIXME
- kdump(proc_test_stack2+sizeof(proc_test_stack1)-64, 64);
-
- for (;;)
- {
- kputs(">main task\n");
- timer_delay(93);
- proc_switch();
- }
-
- ASSERT(false);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2001, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Semaphore based synchronization services.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "sem.h"
-#include <kern/proc.h>
-#include <kern/proc_p.h>
-#include <kern/signal.h>
-#include <cfg/debug.h>
-
-INLINE void sem_verify(struct Semaphore *s)
-{
- (void)s;
- ASSERT(s);
- LIST_ASSERT_VALID(&s->wait_queue);
- ASSERT(s->nest_count >= 0);
- ASSERT(s->nest_count < 128); // heuristic max
-}
-
-
-/**
- * \brief Initialize a Semaphore structure.
- */
-void sem_init(struct Semaphore *s)
-{
- LIST_INIT(&s->wait_queue);
- s->owner = NULL;
- s->nest_count = 0;
-}
-
-
-/**
- * \brief Attempt to lock a semaphore without waiting.
- *
- * \return true in case of success, false if the semaphore
- * was already locked by someone else.
- *
- * \note each call to sem_attempt() must be matched by a
- * call to sem_release().
- *
- * \see sem_obtain() sem_release()
- */
-bool sem_attempt(struct Semaphore *s)
-{
- bool result = false;
-
- proc_forbid();
- sem_verify(s);
- if ((!s->owner) || (s->owner == CurrentProcess))
- {
- s->owner = CurrentProcess;
- s->nest_count++;
- result = true;
- }
- proc_permit();
-
- return result;
-}
-
-
-/**
- * \brief Lock a semaphore.
- *
- * If the semaphore is already owned by another process, the caller
- * process will be enqueued into the waiting list and sleep until
- * the semaphore is available.
- *
- * \note Each call to sem_obtain() must be matched by a
- * call to sem_release().
- *
- * \note This routine is optimized for highest speed in
- * the most common case: the semaphore is free or locked
- * by the calling process itself. Rearranging this code
- * is probably a bad idea.
- *
- * \sa sem_release() sem_attempt()
- */
-void sem_obtain(struct Semaphore *s)
-{
- proc_forbid();
- sem_verify(s);
-
- /* Is the semaphore already locked by another process? */
- if (UNLIKELY(s->owner && (s->owner != CurrentProcess)))
- {
- /* Append calling process to the wait queue */
- ADDTAIL(&s->wait_queue, (Node *)CurrentProcess);
-
- /*
- * We will wake up only when the current owner calls
- * sem_release(). Then, the semaphore will already
- * be locked for us.
- */
- proc_permit();
- proc_schedule();
- }
- else
- {
- ASSERT(LIST_EMPTY(&s->wait_queue));
-
- /* The semaphore was free: lock it */
- s->owner = CurrentProcess;
- s->nest_count++;
- proc_permit();
- }
-}
-
-
-/**
- * \brief Release a lock on a previously locked semaphore.
- *
- * If the nesting count of the semaphore reaches zero,
- * the next process waiting for it will be awaken.
- *
- * \note This routine is optimized for highest speed in
- * the most common case: the semaphore has been locked just
- * once and nobody else was waiting for it. Rearranging
- * this code is probably a bad idea.
- *
- * \sa sem_obtain() sem_attempt()
- */
-void sem_release(struct Semaphore *s)
-{
- proc_forbid();
- sem_verify(s);
-
- ASSERT(s->owner == CurrentProcess);
-
- /*
- * Decrement nesting count and check if the semaphore
- * has been fully unlocked.
- */
- if (--s->nest_count == 0)
- {
- Process *proc;
-
- /* Disown semaphore */
- s->owner = NULL;
-
- /* Give semaphore to the first applicant, if any */
- if (UNLIKELY((proc = (Process *)list_remHead(&s->wait_queue))))
- {
- s->nest_count = 1;
- s->owner = proc;
- SCHED_ENQUEUE(proc);
- }
- }
-
- proc_permit();
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2001,2004,2005,2006,2007 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Mutually exclusive semaphores.
- * Shared locking not supported in this implementation.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-
-#ifndef KERN_SEM_H
-#define KERN_SEM_H
-
-#include <cfg/compiler.h>
-#include <mware/list.h>
-
-/* Fwd decl */
-struct Process;
-
-
-typedef struct Semaphore
-{
- struct Process *owner;
- List wait_queue;
- int nest_count;
-} Semaphore;
-
-/**
- * \name Process synchronization services
- * \{
- */
-void sem_init(struct Semaphore *s);
-bool sem_attempt(struct Semaphore *s);
-void sem_obtain(struct Semaphore *s);
-void sem_release(struct Semaphore *s);
-/* \} */
-
-#endif /* KERN_SEM_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief IPC signals implementation.
- *
- * Signals are a low-level IPC primitive. A process receives a signal
- * when some external event has happened. Like interrupt requests,
- * signals do not carry any additional information. If processing a
- * specific event requires additional data, the process must obtain it
- * through some other mechanism.
- *
- * Despite the name, one shouldn't confuse these signals with POSIX
- * signals. POSIX signals are usually executed synchronously, like
- * software interrupts.
- *
- * Signals are very low overhead. Using them exclusively to wait
- * for multiple asynchronous events results in very simple dispatch
- * logic with low processor and resource usage.
- *
- * The "event" module is a higher-level interface that can optionally
- * deliver signals to processes. Messages provide even higher-level
- * IPC services built on signals. Semaphore arbitration is also
- * implemented using signals.
- *
- * In this implementation, each process has a limited set of signal
- * bits (usually 32) and can wait for multiple signals at the same
- * time using sig_wait(). Signals can also be polled using sig_check(),
- * but a process spinning on its signals usually defeats their purpose
- * of providing a multitasking-friendly infrastructure for event-driven
- * applications.
- *
- * Signals are like flags: they are either active or inactive. After an
- * external event has delivered a particular signal, it remains raised until
- * the process acknowledges it using either sig_wait() or sig_check().
- * Counting signals is not a reliable way to count how many times a
- * particular event has occurred, because the same signal may be
- * delivered twice before the process can notice.
- *
- * Any execution context, including an interrupt handler, can deliver
- * a signal to a process using sig_signal(). Multiple independent signals
- * may be delivered at once with a single invocation of sig_signal(),
- * although this is rarely useful.
- *
- * \section signal_allocation Signal Allocation
- *
- * There's no hardcoded mapping of specific events to signal bits.
- * The meaning of a particular signal bit is defined by an agreement
- * between the delivering entity and the receiving process.
- * For instance, a terminal driver may be designed to deliver
- * a signal bit called SIG_INT when it reads the CTRL-C sequence
- * from the keyboard, and a process may react to it by quitting.
- *
- * \section sig_single SIG_SINGLE
- *
- * The SIG_SINGLE bit is reserved as a convenient shortcut in those
- * simple scenarios where a process needs to wait on just one event
- * synchronously. By using SIG_SINGLE, there's no need to allocate
- * a specific signal from the free pool. The constraints for safely
- * accessing SIG_SINGLE are:
- * - The process MUST sig_wait() exclusively on SIG_SINGLE
- * - SIG_SIGNAL MUST NOT be left pending after use (sig_wait() will reset
- * it automatically)
- * - Do not sleep between starting the asynchronous task that will fire
- * SIG_SINGLE, and the call to sig_wait().
- * - Do not call system functions that may implicitly sleep, such as
- * timer_delayTickes().
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "signal.h"
-
-#include <cfg/debug.h>
-#include <drv/timer.h>
-#include <kern/proc.h>
-#include <kern/proc_p.h>
-
-
-#if CONFIG_KERN_SIGNALS
-
-/**
- * Check if any of the signals in \a sigs has occurred and clear them.
- * \return the signals that have occurred.
- */
-sigmask_t sig_check(sigmask_t sigs)
-{
- sigmask_t result;
- cpuflags_t flags;
-
- IRQ_SAVE_DISABLE(flags);
- result = CurrentProcess->sig_recv & sigs;
- CurrentProcess->sig_recv &= ~sigs;
- IRQ_RESTORE(flags);
-
- return result;
-}
-
-
-/**
- * Sleep until any of the signals in \a sigs occurs.
- * \return the signal(s) that have awoken the process.
- */
-sigmask_t sig_wait(sigmask_t sigs)
-{
- sigmask_t result;
- cpuflags_t flags;
-
- IRQ_SAVE_DISABLE(flags);
-
- /* Loop until we get at least one of the signals */
- while (!(result = CurrentProcess->sig_recv & sigs))
- {
- /* go to sleep and proc_schedule() another process */
- CurrentProcess->sig_wait = sigs;
- proc_schedule();
-
- /* When we come back here, a signal must be arrived */
- ASSERT(!CurrentProcess->sig_wait);
- ASSERT(CurrentProcess->sig_recv);
- }
-
- /* Signals found: clear them and return */
- CurrentProcess->sig_recv &= ~sigs;
-
- IRQ_RESTORE(flags);
- return result;
-}
-
-/**
- * Sleep until any of the signals in \a sigs or \a timeout ticks elapse.
- * If the timeout elapse a SIG_TIMEOUT is added to the received signal(s).
- * \return the signal(s) that have awoken the process.
- * \note Caller must check return value to check which signal awoke the process.
- */
-sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout)
-{
- Timer t;
- sigmask_t res;
- cpuflags_t flags;
-
- ASSERT(!sig_check(SIG_TIMEOUT));
- ASSERT(!(sigs & SIG_TIMEOUT));
- /* IRQ are needed to run timer */
- ASSERT(IRQ_ENABLED());
-
- timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
- timer_setDelay(&t, timeout);
- timer_add(&t);
- res = sig_wait(SIG_TIMEOUT | sigs);
-
- IRQ_SAVE_DISABLE(flags);
- /* Remove timer if sigs occur before timer signal */
- if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT))
- timer_abort(&t);
- IRQ_RESTORE(flags);
- return res;
-}
-
-
-/**
- * Send the signals \a sigs to the process \a proc.
- * The process will be awoken if it was waiting for any of them.
- *
- * \note This call is interrupt safe.
- */
-void sig_signal(Process *proc, sigmask_t sigs)
-{
- cpuflags_t flags;
- IRQ_SAVE_DISABLE(flags);
-
- /* Set the signals */
- proc->sig_recv |= sigs;
-
- /* Check if process needs to be awoken */
- if (proc->sig_recv & proc->sig_wait)
- {
- /* Wake up process and enqueue in ready list */
- proc->sig_wait = 0;
- SCHED_ENQUEUE(proc);
- }
-
- IRQ_RESTORE(flags);
-}
-
-#endif /* CONFIG_KERN_SIGNALS */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Signal module (public interface).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-
-#ifndef KERN_SIGNAL_H
-#define KERN_SIGNAL_H
-
-#include <cfg/compiler.h>
-
-
-/* Fwd decl */
-struct Process;
-
-/* Inter-process Communication services */
-sigmask_t sig_check(sigmask_t sigs);
-void sig_signal(struct Process *proc, sigmask_t sig);
-sigmask_t sig_wait(sigmask_t sigs);
-sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout);
-
-
-/**
- * \name Signal definitions
- * \{
- */
-#define SIG_USER0 BV(0) /**< Free for user usage */
-#define SIG_USER1 BV(1) /**< Free for user usage */
-#define SIG_USER2 BV(2) /**< Free for user usage */
-#define SIG_USER3 BV(3) /**< Free for user usage */
-#define SIG_TIMEOUT BV(4) /**< Reserved for timeout use */
-#define SIG_SYSTEM5 BV(5) /**< Reserved for system use */
-#define SIG_SYSTEM6 BV(6) /**< Reserved for system use */
-#define SIG_SINGLE BV(7) /**< Used to wait for a single event */
-/*\}*/
-
-#endif /* KERN_SIGNAL_H */
+++ /dev/null
-#if defined(__i386__)
- #include "switch_i386.s"
-#elif defined(__x86_64__)
- #include "switch_x86_64.s"
-#else
- #error Unknown CPU
-#endif
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief ARM context switch
- *
- * \version $Id: proc.c 18271 2007-10-11 14:51:31Z batt $
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-
-/*
- * NOTE: At each change of this function affecting proc.c
- * (i.e. arguments, data stored in the stack) bump up version
- * number in asm_switch_version().
- */
-
-/* void asm_switch_context(void **new_sp, void **save_sp) */
-.globl asm_switch_context
-asm_switch_context:
- mrs r2, cpsr /* Save status. */
- stmfd sp!, {r2, r4-r11, lr} /* Save registers. */
-
- str sp, [r1] /* Save old stack pointer. */
- ldr sp, [r0] /* Load new stack pointer */
-
- ldmfd sp!, {r2, r4-r11, lr} /* Load new registers. */
- msr cpsr, r2 /* restore flags reg. */
-
- mov pc, lr
-
-
-/* int asm_switch_version(void) */
-.globl asm_switch_version
-asm_switch_version:
- mov r0, #1
- mov pc, lr
+++ /dev/null
-/*!
- * \file
- * <!--
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- * This file is part of DevLib - See devlib/README for information.
- * -->
- *
- * \brief AVR context switch
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#include <avr/io.h>
-
-/*
- * NOTE: At each change of this function affecting proc.c
- * (i.e. arguments, data stored in the stack) bump up version
- * number in asm_switch_version().
- */
-
-/* void asm_switch_context(void **new_sp, void **save_sp) */
-.globl asm_switch_context
-asm_switch_context:
-
-; r0 is the TEMP REG and can be used freely.
-; r1 is the ZERO REG and must always contain 0.
-;
-; Stack frame is 19 byte, remember to update
-; CPU_SAVED_REGS_CNT if you change pushed regs.
-
- in r0,SREG-__SFR_OFFSET
- push r0
-; push r1 ;zero-reg
- push r2
- push r3
- push r4
- push r5
- push r6
- push r7
- push r8
- push r9
- push r10
- push r11
- push r12
- push r13
- push r14
- push r15
- push r16
- push r17
-; push r18 ;caller-save
-; push r19 ;caller-save
-; push r20 ;caller-save
-; push r21 ;caller-save
-; push r22 ;caller-save
-; push r23 ;caller-save
-; push r24 ;caller-save
-; push r25 ;caller-save
-; push r26 ;caller-save
-; push r27 ;caller-save
- push r28
- push r29
-; push r30 ;caller-save
-; push r31 ;caller-save
-
-; First parameter (new_sp) is in r24:r25, second (save_sp) in r22:r23
-
- in r18,SPL-__SFR_OFFSET ; r18:r19 = SP
- in r19,SPH-__SFR_OFFSET
- movw r26,r22 ; X = save_sp
- st X+,r18 ; *save_sp = SP
- st X,r19
- movw r26,r24 ; X = new_sp
- ld r18,X+
- ld r19,X
-
-; Set new stack pointer.
-; AVR is an 8 bit processor so
-; care must be taken when updating
-; SP that is a 16 bit reg.
-; Two instructions are required to update SP
-; so an IRQ can sneak in between them.
-; So IRQ *MUST* be disabled and then restored.
- cli ; Disable interrupt
- out SPL-__SFR_OFFSET,r18 ; SP = *new_sp
- out SPH-__SFR_OFFSET,r19
- out SREG-__SFR_OFFSET,r0 ; Restore previous IRQ state
-
-; pop r31 ;caller-save
-; pop r30 ;caller-save
- pop r29
- pop r28
-; pop r27 ;caller-save
-; pop r26 ;caller-save
-; pop r25 ;caller-save
-; pop r24 ;caller-save
-; pop r23 ;caller-save
-; pop r22 ;caller-save
-; pop r21 ;caller-save
-; pop r20 ;caller-save
-; pop r19 ;caller-save
-; pop r18 ;caller-save
- pop r17
- pop r16
- pop r15
- pop r14
- pop r13
- pop r12
- pop r11
- pop r10
- pop r9
- pop r8
- pop r7
- pop r6
- pop r5
- pop r4
- pop r3
- pop r2
-; pop r1 ;zero-reg
- pop r0
- out SREG-__SFR_OFFSET,r0
-
- ret
-
-
-/* int asm_switch_version(void) */
-.globl asm_switch_version
-asm_switch_version:
- ldi r24,lo8(1)
- ldi r25,hi8(1)
- ret
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- *
- * \brief DSP5680x task switching support
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2006/02/24 01:17:05 bernie
- *#* Update for new emulator.
- *#*
- *#* Revision 1.5 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.4 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.3 2004/07/30 14:24:16 rasky
- *#* Task switching con salvataggio perfetto stato di interrupt (SR)
- *#* Kernel monitor per dump informazioni su stack dei processi
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 17:27:00 bernie
- *#* Import kern/ subdirectory.
- *#*
- *#*/
-
-void asm_switch_context(void ** new_sp/*R2*/, void ** save_sp/*R3*/);
-asm void asm_switch_context(void ** new_sp, void ** save_sp)
-{
- lea (SP)+
-
- ; From the manual:
- ; The compiler uses page 0 address locations X: 0x0030 - 0x003F as register
- ; variables. Frequently accessed local variables are assigned to the page 0
- ; registers instead of to stack locations so that load and store instructions
- ; are shortened. Addresses X: 0x0030 - 0x0037 (page 0 registers MR0-MR7) are
- ; volatile registers and can be overwritten. The remaining registers (page 0
- ; registers MR8-MR15) are treated as non-volatile and, if used by a routine,
- ; must be saved on entry and restored on exit.
- ;
- ; So, register 0x30-0x37 are caller-save, while 0x38-0x3F are callee-save.
- move x:<$38,y1
- move y1,x:(SP)+
- move x:<$39,y1
- move y1,x:(SP)+
- move x:<$3A,y1
- move y1,x:(SP)+
- move x:<$3B,y1
- move y1,x:(SP)+
- move x:<$3C,y1
- move y1,x:(SP)+
- move x:<$3D,y1
- move y1,x:(SP)+
- move x:<$3E,y1
- move y1,x:(SP)+
- move x:<$3F,y1
- move y1,x:(SP)
-
- ;
- ; Switch stacks
- nop
- move SP, x:(R3)
- nop
- move x:(R2), SP
- nop
-
- ;
- ; restore all saved registers
- ;
- pop y1
- move y1,x:<$3F
- pop y1
- move y1,x:<$3E
- pop y1
- move y1,x:<$3D
- pop y1
- move y1,x:<$3C
- pop y1
- move y1,x:<$3B
- pop y1
- move y1,x:<$3A
- pop y1
- move y1,x:<$39
- pop y1
- move y1,x:<$38
-
- ; SR is already pushed on the stack (normal call context). Use RTI to restore
- ; it, so that interrupt status is preserved across the tasks.
- rti
-}
-
-int asm_switch_version(void);
-int asm_switch_version(void)
-{
- return 1;
-}
+++ /dev/null
-;* Copyright 2004 Develer S.r.l. (http://www.develer.com/)
-;* Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
-;* This file is part of DevLib - See devlib/README for information.
-;*
-;* \version $Id$
-;*
-;* \author Bernardo Innocenti <bernie@develer.com>
-;*
-
-;* $Log$
-;* Revision 1.2 2004/06/06 16:14:12 bernie
-;* Add DevLib license information.
-;*
-;* Revision 1.1 2004/05/23 17:27:00 bernie
-;* Import kern/ subdirectory.
-;*
-;*
-
-!!!!!! THIS FILE HAS NOT BEEN REVISED FOR THE NEW SCHEDULER API !!!!!!
-
-
-
- NAME AsmSwitch
- RSEG CODE
-
- EXTERN ?LR
- EXTERN ?GR
- PUBLIC AsmSwitchContext
- PUBLIC AsmReplaceContext
-
-
-;* Perform low-level process context switching
-;*
-;* void AsmSwitchContext(cpustack_t *new_sp, cpustack_t **save_sp)
-;* GR+0 SP+2
-;*
-;* Replace current context with new process
-;*
-;* void AsmReplaceContext(cpustack_t *new_sp, cpustack_t **dummy)
-;* GR+0 SP+2
-;*
-
-AsmSwitchContext:
-
-; pop 2nd parameter from the stack
- ld ?GR+2,2[SP]
-
-; save all registers
- push ?LR+0
- push ?LR+2
- push ?LR+4
- push ?LR+6
- push ?LR+8
- push ?LR+10
- push ?LR+12
- push ?LR+14
- push ?LR+16
- push ?LR+18
- push ?LR+20
- push ?LR+22
- push ?LR+24
- push ?LR+26
- push ?LR+28
- push ?LR+30
- st SP,[?GR+2] ; save old stack pointer
- ; fall-thru
-
-AsmReplaceContext:
- ld SP,?GR+0 ; load new stack pointer
-
-; restore all registers
- pop ?LR+30
- pop ?LR+28
- pop ?LR+26
- pop ?LR+24
- pop ?LR+22
- pop ?LR+20
- pop ?LR+18
- pop ?LR+16
- pop ?LR+14
- pop ?LR+12
- pop ?LR+10
- pop ?LR+8
- pop ?LR+6
- pop ?LR+4
- pop ?LR+2
- pop ?LR+0
-
-; restore execution in new context
- ret
-
- END
+++ /dev/null
-/*!
- * \file
- * <!--
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- * This file is part of DevLib - See devlib/README for information.
- * -->
- *
- * \brief i386 context switch
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/* void asm_switch_context(void ** new_sp, void ** save_sp) */
-.globl asm_switch_context
-asm_switch_context:
- pushl %eax
- pushl %ebx
- pushl %ecx
- pushl %edx
- pushl %esi
- pushl %edi
- pushl %ebp
- movl 0x24(%esp),%ebp /* ebp = save_sp */
- movl %esp,(%ebp) /* *save_sp = esp */
- movl 0x20(%esp),%ebp /* ebp = new_sp */
- movl (%ebp),%esp /* esp = *new_sp */
- popl %ebp
- popl %edi
- popl %esi
- popl %edx
- popl %ecx
- popl %ebx
- popl %eax
- ret
-
-/* int asm_switch_version(void) */
-.globl asm_switch_version
-asm_switch_version:
- mov $1,%eax
- ret
-
+++ /dev/null
-/*!
- * \file
- * <!--
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- * This file is part of DevLib - See devlib/README for information.
- * -->
- *
- * \brief i386 context switch for WIN32
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-!!!!!! THIS FILE HAS NOT BEEN REVISED FOR THE NEW SCHEDULER API !!!!!!
-
-__declspec(naked) void AsmSwitchContext(void * new_sp, void ** save_sp)
-{
- __asm
- {
- push eax
- push ebx
- push ecx
- push edx
- push esi
- push edi
- push ebp
- mov ebp,dword ptr [esp+24h] ; ebp <- save_sp
- mov dword ptr [ebp],esp ; *save_sp = esp
- mov esp,dword ptr [esp+20h] ; new_sp
- pop ebp
- pop edi
- pop esi
- pop edx
- pop ecx
- pop ebx
- pop eax
- ret
- }
-}
-
-__declspec(naked) void AsmReplaceContext(void * new_sp, void ** dummy)
-{
- __asm
- {
- mov esp,dword ptr [esp + 4] ; new_sp
- pop ebp
- pop edi
- pop esi
- pop edx
- pop ecx
- pop ebx
- pop eax
- ret
- }
-}
-
+++ /dev/null
-/*!
- * \file
- * <!--
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- * This file is part of DevLib - See devlib/README for information.
- * -->
- *
- * \brief i386 context switch
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*
- * $Log$
- * Revision 1.4 2006/09/20 14:02:49 marco
- * C-style comment.
- *
- * Revision 1.3 2006/02/24 01:35:40 bernie
- * Update for new emulator.
- *
- * Revision 1.2 2006/02/24 01:17:05 bernie
- * Update for new emulator.
- *
- * Revision 1.1 2005/11/27 03:06:15 bernie
- * Add x86_64 task switching (to be updated to new-style scheduler).
- *
- * Revision 1.1 2005/11/14 21:06:38 bernie
- * Add x86_64 support.
- *
- * Revision 1.2 2004/06/06 16:14:12 bernie
- * Add DevLib license information.
- *
- * Revision 1.1 2004/05/23 17:27:00 bernie
- * Import kern/ subdirectory.
- *
- */
-
-/* I know it's ugly... */
-/* .intel_syntax */
-
-/* void AsmSwitchContext(void **new_sp, void **save_sp) */
-/* %rdi %rsi */
-.globl asm_switch_context
-asm_switch_context:
- pushq %rax
- pushq %rbx
- pushq %rcx
- pushq %rdx
- pushq %rsi
- pushq %rdi
- pushq %rbp
- movq %rsp,(%rsi) /* *save_sp = rsp */
- movq (%rdi),%rsp /* rsp = *new_sp */
- popq %rbp
- popq %rdi
- popq %rsi
- popq %rdx
- popq %rcx
- popq %rbx
- popq %rax
- ret
-
-/* int asm_switch_version(void) */
-.globl asm_switch_version
-asm_switch_version:
- mov $1,%rax
- ret
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- * -->
- *
- * \brief Display Blanker (implementation).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "blanker.h"
-#include <drv/kbd.h>
-#include <drv/timer.h>
-
-/* Time without input events before starting blanker */
-#define BLK_BLANKTIMEOUT (15 * 1000) /* ms */
-
-// TODO: move to blanker_hw.h
-#include <drv/power.h>
-#define BLK_LCDON power_LcdOn()
-#define BLK_LCDOFF power_LcdOff()
-
-
-/** Keyboard event handler to listen for key presses in blanker. */
-static KbdHandler blk_KbdHandler;
-
-/** Time since last key event. */
-static ticks_t blk_lastevent;
-
-/** Display blanking function is enabled. */
-static bool blk_enabled;
-
-/** Display blanker is engaged right now. */
-static bool blk_active;
-
-
-static bool blk_on(void)
-{
- if (!blk_active)
- {
- blk_active = true;
- BLK_LCDOFF;
- }
- return true;
-}
-
-
-static void blk_off(void)
-{
- if (blk_active)
- {
- blk_active = false;
- BLK_LCDON;
- }
-}
-
-
-void blk_retrigger(void)
-{
- blk_lastevent = timer_clock();
- blk_off();
-}
-
-#if 0
-/**
- * Matrix-like screen saver effect
- */
-static void blk_hack(void)
-{
- static signed char blk_colstart[LCD_COLS];
- UBYTE row, col;
-
-
- if (rand()%3 == 0)
- {
- /* Modify one column */
- col = rand() % LCD_COLS;
- blk_colstart[col] += rand() % 12 - 5;
- }
-
- for (col = 0; col < LCD_COLS; ++col)
- {
- if (blk_colstart[col] > 0)
- {
- --blk_colstart[col];
-
- /* Scroll down */
- for(row = LCD_ROWS-1; row; --row)
- {
- lcd_SetAddr(blk_layer, LCD_POS(col,row));
- lcd_PutChar(blk_layer->Buf[LCD_POS(col,row-1)], blk_layer);
- }
-
- /* Add new kanji */
- lcd_SetAddr(blk_layer, LCD_POS(col,0));
- lcd_PutChar((char)(rand() % 127 + 128), blk_layer);
- }
- else if (blk_colstart[col] < 0)
- {
- ++blk_colstart[col];
-
- /* Clear tail */
- for(row = 0; row < LCD_ROWS; ++row)
- {
- if (blk_layer->Buf[LCD_POS(col,row)] != ' ')
- {
- lcd_SetAddr(blk_layer, LCD_POS(col,row));
- lcd_PutChar(' ', blk_layer);
- break;
- }
- }
- }
- }
-}
-#endif
-
-
-static keymask_t blk_handlerFunc(keymask_t key)
-{
- /* key used to turn off blanker */
- static keymask_t offkey;
-
- ticks_t now = timer_clock();
-
- /* If key pressed */
- if (key != 0)
- {
- blk_lastevent = now;
- if (blk_active)
- {
- blk_off();
-
- /* remember and eat key event */
- offkey = key;
- key = 0;
- }
- else if (key == offkey)
- {
- /* keep eating the key until released */
- key = 0;
- }
-
- /* pass key through */
- return key;
- }
-
- /* reset off key */
- offkey = 0;
-
- /* Blank timeout reached? */
- if (now - blk_lastevent > ms_to_ticks(BLK_BLANKTIMEOUT))
- {
- /* Enable blanker unless already done */
- if (!blk_active && !blk_on())
- return 0;
-
-#if 0
- /* Do some nice visual effect */
- blk_hack();
-#endif /* _DEBUG */
- }
-
- return 0;
-}
-
-
-void blk_enable(void)
-{
- if (!blk_enabled)
- {
- blk_active = false;
- blk_lastevent = timer_clock();
-
- /* Add display blanker handler */
- blk_KbdHandler.hook = blk_handlerFunc;
- blk_KbdHandler.pri = 100; /* high priority */
- blk_KbdHandler.flags = KHF_RAWKEYS;
- kbd_addHandler(&blk_KbdHandler);
-
- blk_enabled = true;
- }
-}
-
-
-void blk_disable(void)
-{
- if (blk_enabled)
- {
- kbd_remHandler(&blk_KbdHandler);
- blk_off();
- blk_enabled = false;
- }
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
- * -->
- *
- * \brief Display Blanker (implementation).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-#ifndef MWARE_BLANKER_H
-#define MWARE_BLANKER_H
-
-extern void blk_enable(void);
-extern void blk_disable(void);
-extern void blk_retrigger(void);
-
-#endif /* MWARE_BLANKER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Functions to convert integers to/from host byte-order.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-#ifndef MWARE_BYTEORDER_H
-#define MWARE_BYTEORDER_H
-
-#include <cfg/compiler.h>
-#include <cpu/attr.h>
-
-/**
- * Swap upper and lower bytes in a 16-bit value.
- */
-INLINE uint16_t swab16(uint16_t x)
-{
- return ((x & (uint16_t)0x00FFU) << 8)
- | ((x & (uint16_t)0xFF00U) >> 8);
-}
-
-/**
- * Reverse bytes in a 32-bit value (e.g.: 0x12345678 -> 0x78563412).
- */
-INLINE uint32_t swab32(uint32_t x)
-{
- return ((x & (uint32_t)0x000000FFUL) << 24)
- | ((x & (uint32_t)0x0000FF00UL) << 8)
- | ((x & (uint32_t)0x00FF0000UL) >> 8)
- | ((x & (uint32_t)0xFF000000UL) >> 24);
-}
-
-/**
- * Reverse bytes in a 64-bit value.
- */
-INLINE uint64_t swab64(uint64_t x)
-{
- return (uint64_t)swab32(x >> 32)
- | ((uint64_t)swab32(x & 0xFFFFFFFFUL) << 32);
-}
-
-/**
- * Reverse bytes in a float value.
- */
-INLINE float swab_float(float x)
-{
- /* Avoid breaking strict aliasing rules. */
- char *cx = (char *)(&x);
- STATIC_ASSERT(sizeof(float) == 4);
- #define BYTEORDER_SWAP(a, b) ((a) ^= (b) ^= (a) ^= (b))
- BYTEORDER_SWAP(cx[0], cx[3]);
- BYTEORDER_SWAP(cx[1], cx[2]);
- #undef BYTEORDER_SWAP
- return x;
-}
-
-INLINE uint16_t cpu_to_be16(uint16_t x)
-{
- return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab16(x) : x;
-}
-
-INLINE uint16_t cpu_to_le16(uint16_t x)
-{
- return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab16(x) : x;
-}
-
-INLINE uint32_t cpu_to_be32(uint32_t x)
-{
- return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab32(x) : x;
-}
-
-INLINE uint32_t cpu_to_le32(uint32_t x)
-{
- return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab32(x) : x;
-}
-
-INLINE uint64_t cpu_to_be64(uint64_t x)
-{
- return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab64(x) : x;
-}
-
-INLINE uint64_t cpu_to_le64(uint64_t x)
-{
- return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab64(x) : x;
-}
-
-INLINE float cpu_to_be_float(float x)
-{
- return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab_float(x) : x;
-}
-
-INLINE float cpu_to_le_float(float x)
-{
- return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab_float(x) : x;
-}
-
-INLINE uint16_t be16_to_cpu(uint16_t x)
-{
- return cpu_to_be16(x);
-}
-
-INLINE uint16_t le16_to_cpu(uint16_t x)
-{
- return cpu_to_le16(x);
-}
-
-INLINE uint32_t be32_to_cpu(uint32_t x)
-{
- return cpu_to_be32(x);
-}
-
-INLINE uint32_t le32_to_cpu(uint32_t x)
-{
- return cpu_to_le32(x);
-}
-
-INLINE uint64_t be64_to_cpu(uint64_t x)
-{
- return cpu_to_be64(x);
-}
-
-INLINE uint64_t le64_to_cpu(uint64_t x)
-{
- return cpu_to_le64(x);
-}
-
-INLINE float be_float_to_cpu(float x)
-{
- return cpu_to_be_float(x);
-}
-
-INLINE float le_float_to_cpu(float x)
-{
- return cpu_to_le_float(x);
-}
-
-INLINE uint16_t host_to_net16(uint16_t x)
-{
- return cpu_to_be16(x);
-}
-
-INLINE uint16_t net_to_host16(uint16_t x)
-{
- return be16_to_cpu(x);
-}
-
-INLINE uint32_t host_to_net32(uint32_t x)
-{
- return cpu_to_be32(x);
-}
-
-INLINE uint32_t net_to_host32(uint32_t x)
-{
- return be32_to_cpu(x);
-}
-
-INLINE uint64_t host_to_net64(uint64_t x)
-{
- return cpu_to_be64(x);
-}
-
-INLINE uint64_t net_to_host64(uint64_t x)
-{
- return be64_to_cpu(x);
-}
-
-INLINE float host_to_net_float(float x)
-{
- return cpu_to_be_float(x);
-}
-
-INLINE float net_to_host_float(float x)
-{
- return be_float_to_cpu(x);
-}
-
-#ifdef __cplusplus
-
-/// Type generic byte swapping.
-template<typename T>
-INLINE T swab(T x);
-
-template<> INLINE uint16_t swab(uint16_t x) { return swab16(x); }
-template<> INLINE uint32_t swab(uint32_t x) { return swab32(x); }
-template<> INLINE uint64_t swab(uint64_t x) { return swab64(x); }
-template<> INLINE int16_t swab(int16_t x) { return static_cast<int16_t>(swab16(static_cast<uint16_t>(x))); }
-template<> INLINE int32_t swab(int32_t x) { return static_cast<int32_t>(swab32(static_cast<uint32_t>(x))); }
-template<> INLINE int64_t swab(int64_t x) { return static_cast<int64_t>(swab64(static_cast<uint64_t>(x))); }
-template<> INLINE float swab(float x) { return swab_float(x); }
-
-/// Type generic conversion from CPU byte order to big-endian byte order.
-template<typename T>
-INLINE T cpu_to_be(T x)
-{
- return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab(x) : x;
-}
-
-/// Type generic conversion from CPU byte-order to little-endian.
-template<typename T>
-INLINE T cpu_to_le(T x)
-{
- return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab(x) : x;
-}
-
-/// Type generic conversion from big endian byte-order to CPU byte order.
-template<typename T>
-INLINE T be_to_cpu(T x)
-{
- return cpu_to_be(x);
-}
-
-/// Type generic conversion from little-endian byte order to CPU byte order.
-template<typename T>
-INLINE T le_to_cpu(T x)
-{
- return cpu_to_le(x);
-}
-
-/// Type generic conversion from network byte order to host byte order.
-template<typename T>
-INLINE T net_to_host(T x)
-{
- return be_to_cpu(x);
-}
-
-/// Type generic conversion from host byte order to network byte order.
-template<typename T>
-INLINE T host_to_net(T x)
-{
- return net_to_host(x);
-}
-
-#endif /* __cplusplus */
-
-#endif /* MWARE_BYTEORDER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Giovanni Bajo
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- * This module permits to create hunks for the functions that must be executed through
- * RPC commands. For instance, given this code:
- *
- * \code
- * ResultCode cmd_add(long a, long b, long* result);
- * DECLARE_COMMAND_HUNK(add, (long)(long)(NIL), (long)(NIL));
- * // ^ parameters ^ return values
- * \endcode
- *
- * The macro is expanded to:
- *
- * \code
- * ResultCode cmd_add_hunk(params argv[], params results[])
- * {
- * return cmd_add(argv[0].l, argv[1].l, &results[0].l);
- * }
- *
- * const struct CmdTemplate cmd_add_template =
- * {
- * "add", "dd", "d", cmd_add_hunk
- * };
- * \endcode
- *
- * which is all the boilerplate needed to make the function ready for the RPC.
- * The implementation uses the Boost Preprocessor Library (part of the Boost
- * library, available at http://www.boost.org). The version we developed the
- * code with is 1.31.
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- *
- * \brief Preprocessor magic to create hunks for the commands executed from the parser
- *
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2006/06/01 12:27:39 marco
- *#* Added utilities for protocols
- *#*
- *#* Revision 1.8 2005/01/12 20:06:31 rasky
- *#* enum ResultCode è ora un typedef
- *#*
- *#* Revision 1.7 2004/12/14 15:10:53 user1
- *#* Bernardo e Francesco: Assegnazione di un codice di ritorno ai processi
- *#*
- *#* Revision 1.6 2004/12/02 17:43:15 rasky
- *#* Aggiunta la possibilità di settare le flag dei comandi con la nuova macro DECLARE_CMD_HUNK_FLAGS (altrimenti, il default è zero)
- *#*
- *#* Revision 1.5 2004/10/16 13:20:15 rasky
- *#* Aggiunto supporto per alias di uno stesso comando
- *#*
- *#* Revision 1.4 2004/08/25 14:17:10 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.3 2004/07/31 22:00:07 rasky
- *#* Fixata una dipendenza
- *#*
- *#* Revision 1.2 2004/07/31 14:32:58 rasky
- *#* args e results possono overlapparsi sempre grazie ai thunk generati: eliminati i due array separati per risparmiare memoria
- *#*
- *#* Revision 1.1 2004/05/22 16:29:16 rasky
- *#* Generazione degli hunk dei comandi RPC tramite preprocessore
- *#*
- *#*/
-
-#ifndef CMD_HUNK_H
-#define CMD_HUNK_H
-
-#include "parser.h"
-
-// Bring in the Boost Preprocess Library
-#include <boost/preprocessor/library.hpp>
-
-#define HUNK_INDEX_FOR_NIL 0
-#define HUNK_INDEX_FOR_string 1
-#define HUNK_INDEX_FOR_long 2
-#define HUNK_ARRAY_LETTERS (3, (NIL, s, l))
-#define HUNK_ARRAY_STRINGS (3, ("", "s", "d"))
-
-// Transform int->l, float->f, etc.
-#define HUNK_TYPE_LETTER(s, _, type) \
- BOOST_PP_CAT(HUNK_INDEX_FOR_, type) \
- /**/
-
-#define HUNK_TRANSFORMER(_, array, elem) \
- BOOST_PP_ARRAY_ELEM(elem, array) \
- /**/
-
-#define HUNK_SEQ_TRANS_ARRAY(seq, array) \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TRANSFORMER, array, seq) \
- /**/
-
-#define HUNK_PARAM(_, n, seq) \
- args_results[n+1]. BOOST_PP_SEQ_ELEM(n, seq) \
- /**/
-
-#define HUNK_RESULT(_, n, seq) \
- &args_results[n]. BOOST_PP_SEQ_ELEM(n, seq) \
- /**/
-
-#define HUNK_IDENTITY(_, dummy, x) x
-#define CMD_HUNK_TEMPLATE(func) cmd_##func###_template
-
-#define DECLARE_CMD_HUNK_2(func, name, param_types, result_types, flags) \
- static ResultCode cmd_##name##_hunk(parms args_results[]) \
- { \
- return cmd_##func( \
- BOOST_PP_ENUM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(param_types)), HUNK_PARAM, HUNK_SEQ_TRANS_ARRAY(param_types, HUNK_ARRAY_LETTERS)) \
- BOOST_PP_COMMA_IF(BOOST_PP_AND(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(param_types)), BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(result_types)))) \
- BOOST_PP_ENUM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(result_types)), HUNK_RESULT, HUNK_SEQ_TRANS_ARRAY(result_types, HUNK_ARRAY_LETTERS)) \
- ); \
- } \
- const struct CmdTemplate CMD_HUNK_TEMPLATE(name) = { \
- #name, \
- BOOST_PP_SEQ_FOR_EACH(HUNK_IDENTITY, _, HUNK_SEQ_TRANS_ARRAY(param_types, HUNK_ARRAY_STRINGS)), \
- BOOST_PP_SEQ_FOR_EACH(HUNK_IDENTITY, _, HUNK_SEQ_TRANS_ARRAY(result_types, HUNK_ARRAY_STRINGS)), \
- cmd_##name##_hunk, \
- flags \
- } \
- /**/
-
-#define DECLARE_CMD_HUNK(func, param_types, result_types) \
- DECLARE_CMD_HUNK_2(func, func, \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
- 0) \
- /**/
-
-#define DECLARE_CMD_HUNK_NAME(func, name, param_types, result_types) \
- DECLARE_CMD_HUNK_2(func, name, \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
- 0) \
- /**/
-
-#define DECLARE_CMD_HUNK_FLAGS(func, param_types, result_types, flags) \
- DECLARE_CMD_HUNK_2(func, func, \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
- BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
- flags) \
- /**/
-
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Events handling implementation
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-
-#include "event.h"
-
-void event_hook_ignore(UNUSED_ARG(Event *, e))
-{
-}
-
-#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
-void event_hook_signal(Event *e)
-{
- sig_signal((e)->Ev.Sig.sig_proc, (e)->Ev.Sig.sig_bit);
-}
-#endif
-
-void event_hook_softint(Event *e)
-{
- e->Ev.Int.func(e->Ev.Int.user_data);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2001, 2003 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Events handling
- *
- * This module implements a common system for executing
- * a user defined action calling a hook function.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef KERN_EVENT_H
-#define KERN_EVENT_H
-
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-#if CONFIG_KERNEL
- #include <config_kern.h>
- #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
- #include <kern/signal.h>
- #endif
-
- /* Forward decl */
- struct Process;
-#endif
-
-
-/// User defined callback type
-typedef void (*Hook)(void *);
-
-typedef struct Event
-{
- void (*action)(struct Event *);
- union
- {
-#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
- struct
- {
- struct Process *sig_proc; /* Process to be signalled */
- sigbit_t sig_bit; /* Signal to send */
- } Sig;
-#endif
- struct
- {
- Hook func; /* Pointer to softint hook */
- void *user_data; /* Data to be passed back to user hook */
- } Int;
- } Ev;
-} Event;
-
-void event_hook_ignore(Event *event);
-void event_hook_signal(Event *event);
-void event_hook_softint(Event *event);
-
-/** Initialize the event \a e as a no-op */
-#define event_initNone(e) \
- ((e)->action = event_hook_ignore)
-
-/** Same as event_initNone(), but returns the initialized event */
-INLINE Event event_createNone(void);
-INLINE Event event_createNone(void)
-{
- Event e;
- e.action = event_hook_ignore;
- return e;
-}
-
-/** Initialize the event \a e with a software interrupt (call function \a f, with parameter \a u) */
-#define event_initSoftInt(e,f,u) \
- ((e)->action = event_hook_softint,(e)->Ev.Int.func = (f), (e)->Ev.Int.user_data = (u))
-
-/** Same as event_initSoftInt(), but returns the initialized event */
-INLINE Event event_createSoftInt(Hook func, void *user_data)
-{
- Event e;
- e.action = event_hook_softint;
- e.Ev.Int.func = func;
- e.Ev.Int.user_data = user_data;
- return e;
-}
-
-
-#if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS
-
-/** Initialize the event \a e with a signal (send signal \a s to process \a p) */
-#define event_initSignal(e,p,s) \
- ((e)->action = event_hook_signal,(e)->Ev.Sig.sig_proc = (p), (e)->Ev.Sig.sig_bit = (s))
-
-/** Same as event_initSignal(), but returns the initialized event */
-INLINE Event event_createSignal(struct Process *proc, sigbit_t bit)
-{
- Event e;
- e.action = event_hook_signal;
- e.Ev.Sig.sig_proc = proc;
- e.Ev.Sig.sig_bit = bit;
- return e;
-}
-
-#endif
-
-/** Trigger an event */
-INLINE void event_do(struct Event *e)
-{
- e->action(e);
-}
-
-#endif /* KERN_EVENT_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief C++-like structured exception handling for C programs
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-#ifndef MWARE_EXCEPT_H
-#define MWARE_EXCEPT_H
-
-#include <cfg/debug.h>
-
-#include <setjmp.h>
-
-#define EXCEPT_CONTEXTS 8
-
-/**
- * A stack of jump buffers used to record try sites
- * so they can be reached from throw sites.
- *
- * The stack contains return points for each nested
- * context. jmp_buf's are pushed into the stack at
- * try points and popped out when the try block ends
- * normally or when an exception is thrown.
- */
-extern jmp_buf except_stack[EXCEPT_CONTEXTS];
-extern int except_top;
-
-#define PUSH_EXCEPT (ASSERT(except_top < EXCEPT_CONTEXTS), setjmp(except_stack[except_top++]))
-#define POP_EXCEPT (ASSERT(except_top > 0), --except_top)
-#define DO_EXCEPT (ASSERT(except_top > 0), longjmp(except_stack[--except_top], true))
-
-/**
- * Jump buffer to use when throwing an exception or aborting an operation
- *
- * User code can throw exceptions like this:
- *
- * \code
- * void a_function_throwing_exceptions(void)
- * {
- * if (some_error_condition)
- * THROW;
- * }
- * \endcode
- *
- * Catching exceptions (brackets are optional):
- *
- * \code
- * EXCEPT_DEFINE;
- *
- * void a_function_catching_an_exception(void)
- * {
- * TRY
- * {
- * printf("Entered try block\n");
- * a_function_throwing_exceptions();
- * printf("Survived execution of critical code\n");
- * }
- * CATCH
- * {
- * printf("Exception caught!\n");
- * }
- * CATCH_END
- * }
- * \endcode
- *
- * Simple syntax when you don't need to do anything when catching an excaption:
- *
- * \code
- * TRY
- * printf("Entered try block\n");
- * a_function_throwing_exceptions();
- * printf("Survived execution of critical code\n");
- * TRY_END
- * \endcode
- *
- * You also need to declare the exception stack once in
- * your global declarations:
- * \code
- * EXCEPT_DEFINE;
- * \endcode
- */
-#define TRY if (PUSH_EXCEPT) { {
-#define TRY_END } POP_EXCEPT; }
-#define CATCH } POP_EXCEPT; } else {
-#define CATCH_END }
-#define THROW DO_EXCEPT
-
-
-#define EXCEPT_DEFINE \
- jmp_buf except_stack[EXCEPT_CONTEXTS]; \
- int except_top;
-
-#endif /* MWARE_EXCEPT_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief General pourpose FIFO buffer implemented with a ring buffer
- *
- * \li \c begin points to the first buffer element;
- * \li \c end points to the last buffer element (unlike the STL convention);
- * \li \c head points to the element to be extracted next;
- * \li \c tail points to the location following the last insertion;
- * \li when any of the pointers advances beyond \c end, it is reset
- * back to \c begin.
- *
- * \code
- *
- * +-----------------------------------+
- * | empty | valid data | empty |
- * +-----------------------------------+
- * ^ ^ ^ ^
- * begin head tail end
- *
- * \endcode
- *
- * The buffer is EMPTY when \c head and \c tail point to the same location:
- * \code head == tail \endcode
- *
- * The buffer is FULL when \c tail points to the location immediately
- * after \c head:
- * \code tail == head - 1 \endcode
- *
- * The buffer is also FULL when \c tail points to the last buffer
- * location and head points to the first one:
- * \code head == begin && tail == end \endcode
- */
-
-#ifndef MWARE_FIFO_H
-#define MWARE_FIFO_H
-
-#include <cpu/types.h>
-#include <cpu/irq.h>
-#include <cfg/debug.h>
-
-typedef struct FIFOBuffer
-{
- unsigned char * volatile head;
- unsigned char * volatile tail;
- unsigned char *begin;
- unsigned char *end;
-} FIFOBuffer;
-
-
-#define ASSERT_VALID_FIFO(fifo) \
- ATOMIC( \
- ASSERT((fifo)->head >= (fifo)->begin); \
- ASSERT((fifo)->head <= (fifo)->end); \
- ASSERT((fifo)->tail >= (fifo)->begin); \
- ASSERT((fifo)->tail <= (fifo)->end); \
- )
-
-
-/**
- * Check whether the fifo is empty
- *
- * \note Calling fifo_isempty() is safe while a concurrent
- * execution context is calling fifo_push() or fifo_pop()
- * only if the CPU can atomically update a pointer
- * (which the AVR and other 8-bit processors can't do).
- *
- * \sa fifo_isempty_locked
- */
-INLINE bool fifo_isempty(const FIFOBuffer *fb)
-{
- //ASSERT_VALID_FIFO(fb);
- return fb->head == fb->tail;
-}
-
-
-/**
- * Check whether the fifo is full
- *
- * \note Calling fifo_isfull() is safe while a concurrent
- * execution context is calling fifo_pop() and the
- * CPU can update a pointer atomically.
- * It is NOT safe when the other context calls
- * fifo_push().
- * This limitation is not usually problematic in a
- * consumer/producer scenario because the
- * fifo_isfull() and fifo_push() are usually called
- * in the producer context.
- */
-INLINE bool fifo_isfull(const FIFOBuffer *fb)
-{
- //ASSERT_VALID_FIFO(fb);
- return
- ((fb->head == fb->begin) && (fb->tail == fb->end))
- || (fb->tail == fb->head - 1);
-}
-
-
-/**
- * Push a character on the fifo buffer.
- *
- * \note Calling \c fifo_push() on a full buffer is undefined.
- * The caller must make sure the buffer has at least
- * one free slot before calling this function.
- *
- * \note It is safe to call fifo_pop() and fifo_push() from
- * concurrent contexts, unless the CPU can't update
- * a pointer atomically (which the AVR and other 8-bit
- * processors can't do).
- *
- * \sa fifo_push_locked
- */
-INLINE void fifo_push(FIFOBuffer *fb, unsigned char c)
-{
-#ifdef __MWERKS__
-#pragma interrupt called
-#endif
- //ASSERT_VALID_FIFO(fb);
-
- /* Write at tail position */
- *(fb->tail) = c;
-
- if (UNLIKELY(fb->tail == fb->end))
- /* wrap tail around */
- fb->tail = fb->begin;
- else
- /* Move tail forward */
- fb->tail++;
-}
-
-
-/**
- * Pop a character from the fifo buffer.
- *
- * \note Calling \c fifo_pop() on an empty buffer is undefined.
- * The caller must make sure the buffer contains at least
- * one character before calling this function.
- *
- * \note It is safe to call fifo_pop() and fifo_push() from
- * concurrent contexts.
- */
-INLINE unsigned char fifo_pop(FIFOBuffer *fb)
-{
-#ifdef __MWERKS__
-#pragma interrupt called
-#endif
- //ASSERT_VALID_FIFO(fb);
-
- if (UNLIKELY(fb->head == fb->end))
- {
- /* wrap head around */
- fb->head = fb->begin;
- return *(fb->end);
- }
- else
- /* move head forward */
- return *(fb->head++);
-}
-
-
-/**
- * Make the fifo empty, discarding all its current contents.
- */
-INLINE void fifo_flush(FIFOBuffer *fb)
-{
- //ASSERT_VALID_FIFO(fb);
- fb->head = fb->tail;
-}
-
-
-#if CPU_REG_BITS >= CPU_BITS_PER_PTR
-
- /*
- * 16/32bit CPUs that can update a pointer with a single write
- * operation, no need to disable interrupts.
- */
- #define fifo_isempty_locked(fb) fifo_isempty((fb))
- #define fifo_push_locked(fb, c) fifo_push((fb), (c))
- #define fifo_pop_locked(fb) fifo_pop((fb))
- #define fifo_flush_locked(fb) fifo_flush((fb))
-
-#else /* CPU_REG_BITS < CPU_BITS_PER_PTR */
-
- /**
- * Similar to fifo_isempty(), but with stronger guarantees for
- * concurrent access between user and interrupt code.
- *
- * \note This is actually only needed for 8-bit processors.
- *
- * \sa fifo_isempty()
- */
- INLINE bool fifo_isempty_locked(const FIFOBuffer *fb)
- {
- bool result;
- ATOMIC(result = fifo_isempty(fb));
- return result;
- }
-
-
- /**
- * Similar to fifo_push(), but with stronger guarantees for
- * concurrent access between user and interrupt code.
- *
- * \note This is actually only needed for 8-bit processors.
- *
- * \sa fifo_push()
- */
- INLINE void fifo_push_locked(FIFOBuffer *fb, unsigned char c)
- {
- ATOMIC(fifo_push(fb, c));
- }
-
- /* Probably not really needed, but hard to prove. */
- INLINE unsigned char fifo_pop_locked(FIFOBuffer *fb)
- {
- unsigned char c;
- ATOMIC(c = fifo_pop(fb));
- return c;
- }
-
- /**
- * Similar to fifo_flush(), but with stronger guarantees for
- * concurrent access between user and interrupt code.
- *
- * \note This is actually only needed for 8-bit processors.
- *
- * \sa fifo_flush()
- */
- INLINE void fifo_flush_locked(FIFOBuffer *fb)
- {
- ATOMIC(fifo_flush(fb));
- }
-
-#endif /* CPU_REG_BITS < BITS_PER_PTR */
-
-
-/**
- * Thread safe version of fifo_isfull()
- */
-INLINE bool fifo_isfull_locked(const FIFOBuffer *_fb)
-{
- bool result;
- ATOMIC(result = fifo_isfull(_fb));
- return result;
-}
-
-
-/**
- * FIFO Initialization.
- */
-INLINE void fifo_init(FIFOBuffer *fb, unsigned char *buf, size_t size)
-{
- /* FIFO buffers have a known bug with 1-byte buffers. */
- ASSERT(size > 1);
-
- fb->head = fb->tail = fb->begin = buf;
- fb->end = buf + size - 1;
-}
-
-
-#if 0
-
-/*
- * UNTESTED: if uncommented, to be moved in fifobuf.c
- */
-void fifo_pushblock(FIFOBuffer *fb, unsigned char *block, size_t len)
-{
- size_t freelen;
-
- /* Se c'e' spazio da tail alla fine del buffer */
- if (fb->tail >= fb->head)
- {
- freelen = fb->end - fb->tail + 1;
-
- /* C'e' abbastanza spazio per scrivere tutto il blocco? */
- if (freelen < len)
- {
- /* Scrivi quello che entra fino alla fine del buffer */
- memcpy(fb->tail, block, freelen);
- block += freelen;
- len -= freelen;
- fb->tail = fb->begin;
- }
- else
- {
- /* Scrivi tutto il blocco */
- memcpy(fb->tail, block, len);
- fb->tail += len;
- return;
- }
- }
-
- for(;;)
- {
- while (!(freelen = fb->head - fb->tail - 1))
- Delay(FIFO_POLLDELAY);
-
- /* C'e' abbastanza spazio per scrivere tutto il blocco? */
- if (freelen < len)
- {
- /* Scrivi quello che entra fino alla fine del buffer */
- memcpy(fb->tail, block, freelen);
- block += freelen;
- len -= freelen;
- fb->tail += freelen;
- }
- else
- {
- /* Scrivi tutto il blocco */
- memcpy(fb->tail, block, len);
- fb->tail += len;
- return;
- }
- }
-}
-#endif
-
-#endif /* MWARE_FIFO_H */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \brief Basic "printf", "sprintf" and "fprintf" formatter.
- *
- * This module is 100% reentrant and can be adapted to user-defined routines
- * that needs formatters with special properties like different output
- * channels or new format specifiers.
- *
- * To reduce size in applications not using real numbers or long integers
- * the formatter may be compiled to exclude certain parts. This is
- * controlled by giving a -D option a compilation time:
- *
- * \code
- * -D CONFIG_PRINTF=PRINTF_FULL Full ANSI printf formatter
- * -D CONFIG_PRINTF=PRINTF_NOFLOAT Exclude support for floats
- * -D CONFIG_PRINTF=PRINTF_REDUCED Simplified formatter (see below)
- * -D CONFIG_PRINTF=PRINTF_NOMODIFIERS Exclude 'l' and 'h' modifiers in reduced version
- * -D CONFIG_PRINTF=PRINTF_DISABLED No formatter at all
- * \endcode
- *
- * Code size on AVR4 with GCC 3.4.1 (-O2):
- * PRINTF_FULL 2912byte (0xB60)
- * PRINTF_NOFLOAT 1684byte (0x694)
- * PRINTF_REDUCED 924byte (0x39C)
- * PRINTF_NOMODIFIERS 416byte (0x1A0)
- *
- * Code/data size in words on DSP56K with CodeWarrior 6.0:
- * PRINTF_FULL 1493/45
- * PRINTF_NOFLOAT 795/45
- * PRINTF_REDUCED 482/0
- * PRINTF_NOMODIFIERS 301/0
- *
- * The reduced version of formatter is suitable when program size is critical
- * rather than formatting power. This routine uses less than 20 bytes of
- * stack space which makes it practical even in systems with less than 256
- * bytes of user RAM.
- *
- * The only formatting specifiers supported by the reduced formatter are:
- * \code
- * %% %c %s %d %o %x %X and %hd %ho %hx %hX %ld %lo %lx %lX
- * \endcode
- *
- * It means that real variables are not supported as well as field
- * width and precision arguments.
- */
-
-
-#include "formatwr.h"
-#include <mware/pgm.h>
-#include <mware/hex.h>
-#include <cfg/debug.h> /* ASSERT */
-#include <appconfig.h> /* CONFIG_ macros */
-
-#ifndef CONFIG_PRINTF_N_FORMATTER
- /** Disable the arcane %n formatter. */
- #define CONFIG_PRINTF_N_FORMATTER 0
-#endif
-
-#ifndef CONFIG_PRINTF_OCTAL_FORMATTER
- /** Disable the %o formatter. */
- #define CONFIG_PRINTF_OCTAL_FORMATTER 0
-#endif
-
-/* True if we must keep a count of the number of characters we print. */
-#define CONFIG_PRINTF_COUNT_CHARS (CONFIG_PRINTF_RETURN_COUNT || CONFIG_PRINTF_N_FORMATTER)
-
-#if CONFIG_PRINTF
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
- #include <float.h>
-
- /* Maximum precision for floating point values */
- typedef long double max_float_t;
-
- /*bernie: save some memory, who cares about floats with lots of decimals? */
- #define FRMWRI_BUFSIZE 134
- #warning 134 is too much, the code must be fixed to have a lower precision limit
-#else
- /*
- * Conservative estimate. Should be (probably) 12 (which is the size necessary
- * to represent (2^32-1) in octal plus the sign bit.
- */
- #define FRMWRI_BUFSIZE 16
-#endif
-
-/* Probably useful for fancy microcontrollers such as the PIC, nobody knows. */
-#ifndef MEM_ATTRIBUTE
-#define MEM_ATTRIBUTE
-#endif
-
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
- #define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
-#else
- #define IS_SHORT (sizeof(int) == 2)
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
-
-static char *float_conversion(MEM_ATTRIBUTE max_float_t value,
- MEM_ATTRIBUTE short nr_of_digits,
- MEM_ATTRIBUTE char *buf,
- MEM_ATTRIBUTE char format_flag,
- MEM_ATTRIBUTE char g_flag,
- MEM_ATTRIBUTE bool alternate_flag)
-{
- MEM_ATTRIBUTE char *cp;
- MEM_ATTRIBUTE char *buf_pointer;
- MEM_ATTRIBUTE short n, i, dec_point_pos, integral_10_log;
-
- buf_pointer = buf;
- integral_10_log = 0;
-
- if (value >= 1)
- {
- while (value >= 1e11) /* To speed up things a bit */
- {
- value /= 1e10;
- integral_10_log += 10;
- }
- while (value >= 10)
- {
- value /= 10;
- integral_10_log++;
- }
- }
- else if (value) /* Not just 0.0 */
- {
- while (value <= 1e-10) /* To speed up things a bit */
- {
- value *= 1e10;
- integral_10_log -= 10;
- }
- while (value < 1)
- {
- value *= 10;
- integral_10_log--;
- }
- }
- if (g_flag)
- {
- if (integral_10_log < nr_of_digits && integral_10_log >= -4)
- {
- format_flag = 0;
- nr_of_digits -= integral_10_log;
- }
- nr_of_digits--;
- if (alternate_flag)
- /* %#G - No removal of trailing zeros */
- g_flag = 0;
- else
- /* %G - Removal of trailing zeros */
- alternate_flag = true;
- }
-
- /* %e or %E */
- if (format_flag)
- {
- dec_point_pos = 0;
- }
- else
- {
- /* Less than one... */
- if (integral_10_log < 0)
- {
- *buf_pointer++ = '0';
- if ((n = nr_of_digits) || alternate_flag)
- *buf_pointer++ = '.';
- i = 0;
- while (--i > integral_10_log && nr_of_digits)
- {
- *buf_pointer++ = '0';
- nr_of_digits--;
- }
- if (integral_10_log < (-n - 1))
- /* Nothing more to do */
- goto CLEAN_UP;
- dec_point_pos = 1;
- }
- else
- {
- dec_point_pos = - integral_10_log;
- }
- }
-
- i = dec_point_pos;
- while (i <= nr_of_digits )
- {
- value -= (max_float_t)(n = (short)value); /* n=Digit value=Remainder */
- value *= 10; /* Prepare for next shot */
- *buf_pointer++ = n + '0';
- if ( ! i++ && (nr_of_digits || alternate_flag))
- *buf_pointer++ = '.';
- }
-
- /* Rounding possible */
- if (value >= 5)
- {
- n = 1; /* Carry */
- cp = buf_pointer - 1;
- do
- {
- if (*cp != '.')
- {
- if ( (*cp += n) == ('9' + 1) )
- {
- *cp = '0';
- n = 1;
- }
- else
- n = 0;
- }
- } while (cp-- > buf);
- if (n)
- {
- /* %e or %E */
- if (format_flag)
- {
- cp = buf_pointer;
- while (cp > buf)
- {
- if (*(cp - 1) == '.')
- {
- *cp = *(cp - 2);
- cp--;
- }
- else
- *cp = *(cp - 1);
- cp--;
- }
- integral_10_log++;
- }
- else
- {
- cp = ++buf_pointer;
- while (cp > buf)
- {
- *cp = *(cp - 1);
- cp--;
- }
- }
- *buf = '1';
- }
- }
-
-CLEAN_UP:
- /* %G - Remove trailing zeros */
- if (g_flag)
- {
- while (*(buf_pointer - 1) == '0')
- buf_pointer--;
- if (*(buf_pointer - 1) == '.')
- buf_pointer--;
- }
-
- /* %e or %E */
- if (format_flag)
- {
- *buf_pointer++ = format_flag;
- if (integral_10_log < 0)
- {
- *buf_pointer++ = '-';
- integral_10_log = -integral_10_log;
- }
- else
- *buf_pointer++ = '+';
- n = 0;
- buf_pointer +=10;
- do
- {
- n++;
- *buf_pointer++ = (integral_10_log % 10) + '0';
- integral_10_log /= 10;
- } while ( integral_10_log || n < 2 );
- for ( i = n ; n > 0 ; n-- )
- *(buf_pointer - 11 - i + n) = *(buf_pointer - n);
- buf_pointer -= 10;
- }
- return (buf_pointer);
-}
-
-#endif /* CONFIG_PRINTF > PRINTF_NOFLOAT */
-
-/**
- * This routine forms the core and entry of the formatter.
- *
- * The conversion performed conforms to the ANSI specification for "printf".
- */
-int
-PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
- void put_one_char(char, void *),
- void *secret_pointer,
- va_list ap)
-{
-#if CONFIG_PRINTF > PRINTF_REDUCED
- MEM_ATTRIBUTE static char bad_conversion[] = "???";
- MEM_ATTRIBUTE static char null_pointer[] = "<NULL>";
-
- MEM_ATTRIBUTE int precision;
- MEM_ATTRIBUTE int n;
-#if CONFIG_PRINTF_COUNT_CHARS
- MEM_ATTRIBUTE int nr_of_chars;
-#endif
- MEM_ATTRIBUTE int field_width;
- MEM_ATTRIBUTE char format_flag;
- enum PLUS_SPACE_FLAGS {
- PSF_NONE, PSF_PLUS, PSF_MINUS
- };
- enum DIV_FACTOR {
- DIV_DEC, DIV_HEX,
-#if CONFIG_PRINTF_OCTAL_FORMATTER
- DIV_OCT,
-#endif
- };
- MEM_ATTRIBUTE struct {
- enum PLUS_SPACE_FLAGS plus_space_flag : 2;
-#if CONFIG_PRINTF_OCTAL_FORMATTER
- enum DIV_FACTOR div_factor : 2;
-#else
- enum DIV_FACTOR div_factor : 1;
-#endif
- bool left_adjust : 1;
- bool l_L_modifier : 1;
- bool h_modifier : 1;
- bool alternate_flag : 1;
- bool nonzero_value : 1;
- bool zeropad : 1;
-#if CPU_HARVARD
- bool progmem : 1;
-#endif
- } flags;
- MEM_ATTRIBUTE unsigned long ulong;
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
- MEM_ATTRIBUTE max_float_t fvalue;
-#endif
-
- MEM_ATTRIBUTE char *buf_pointer;
- MEM_ATTRIBUTE char *ptr;
- MEM_ATTRIBUTE const char *hex;
- MEM_ATTRIBUTE char buf[FRMWRI_BUFSIZE];
-
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars = 0;
-#endif
- for (;;) /* Until full format string read */
- {
- while ((format_flag = PGM_READ_CHAR(format++)) != '%') /* Until '%' or '\0' */
- {
- if (!format_flag)
-#if CONFIG_PRINTF_RETURN_COUNT
- return (nr_of_chars);
-#else
- return 0;
-#endif
- put_one_char(format_flag, secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- }
- if (PGM_READ_CHAR(format) == '%') /* %% prints as % */
- {
- format++;
- put_one_char('%', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- continue;
- }
-
- flags.left_adjust = false;
- flags.alternate_flag = false;
- flags.plus_space_flag = PSF_NONE;
- flags.zeropad = false;
-#if CPU_HARVARD
- flags.progmem = false;
-#endif
- ptr = buf_pointer = &buf[0];
- hex = HEX_tab;
-
- /* check for leading '-', '+', ' ','#' or '0' flags */
- for (;;)
- {
- switch (PGM_READ_CHAR(format))
- {
- case ' ':
- if (flags.plus_space_flag)
- goto NEXT_FLAG;
- case '+':
- flags.plus_space_flag = PSF_PLUS;
- goto NEXT_FLAG;
- case '-':
- flags.left_adjust = true;
- goto NEXT_FLAG;
- case '#':
- flags.alternate_flag = true;
- goto NEXT_FLAG;
- case '0':
- flags.zeropad = true;
- goto NEXT_FLAG;
- }
- break;
-NEXT_FLAG:
- format++;
- }
-
- /* Optional field width (may be '*') */
- if (PGM_READ_CHAR(format) == '*')
- {
- field_width = va_arg(ap, int);
- if (field_width < 0)
- {
- field_width = -field_width;
- flags.left_adjust = true;
- }
- format++;
- }
- else
- {
- field_width = 0;
- while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
- field_width = field_width * 10 + (PGM_READ_CHAR(format++) - '0');
- }
-
- if (flags.left_adjust)
- flags.zeropad = false;
-
- /* Optional precision (or '*') */
- if (PGM_READ_CHAR(format) == '.')
- {
- if (PGM_READ_CHAR(++format) == '*')
- {
- precision = va_arg(ap, int);
- format++;
- }
- else
- {
- precision = 0;
- while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
- precision = precision * 10 + (PGM_READ_CHAR(format++) - '0');
- }
- }
- else
- precision = -1;
-
- /* At this point, "left_adjust" is nonzero if there was
- * a sign, "zeropad" is 1 if there was a leading zero
- * and 0 otherwise, "field_width" and "precision"
- * contain numbers corresponding to the digit strings
- * before and after the decimal point, respectively,
- * and "plus_space_flag" is either 0 (no flag) or
- * contains a plus or space character. If there was no
- * decimal point, "precision" will be -1.
- */
-
- flags.l_L_modifier = false;
- flags.h_modifier = false;
-
- /* Optional 'l','L','z' or 'h' modifier? */
- switch (PGM_READ_CHAR(format))
- {
- case 'l':
- case 'L':
- case 'z':
- flags.l_L_modifier = true;
- format++;
- break;
- case 'h':
- flags.h_modifier = true;
- format++;
- break;
- }
-
- /*
- * At exit from the following switch, we will emit
- * the characters starting at "buf_pointer" and
- * ending at "ptr"-1
- */
- switch (format_flag = PGM_READ_CHAR(format++))
- {
-#if CONFIG_PRINTF_N_FORMATTER
- case 'n':
- if (sizeof(short) != sizeof(int))
- {
- if (sizeof(int) != sizeof(long))
- {
- if (h_modifier)
- *va_arg(ap, short *) = nr_of_chars;
- else if (flags.l_L_modifier)
- *va_arg(ap, long *) = nr_of_chars;
- else
- *va_arg(ap, int *) = nr_of_chars;
- }
- else
- {
- if (h_modifier)
- *va_arg(ap, short *) = nr_of_chars;
- else
- *va_arg(ap, int *) = nr_of_chars;
- }
- }
- else
- {
- if (flags.l_L_modifier)
- *va_arg(ap, long *) = nr_of_chars;
- else
- *va_arg(ap, int *) = nr_of_chars;
- }
- continue;
-#endif
- case 'c':
- buf[0] = va_arg(ap, int);
- ptr++;
- break;
-
- /* Custom formatter for strings in program memory. */
- case 'S':
-#if CPU_HARVARD
- flags.progmem = true;
-#endif
- /* Fall trough */
-
- case 's':
- if ( !(buf_pointer = va_arg(ap, char *)) )
- buf_pointer = null_pointer;
- if (precision < 0)
- precision = 10000;
-
- /*
- * Move `ptr' to the last character of the
- * string that will be actually printed.
- */
- ptr = buf_pointer;
-#if CPU_HARVARD
- if (flags.progmem)
- {
- for (n=0; pgm_read_char(ptr) && n < precision; n++)
- ++ptr;
- }
- else
-#endif
- for (n=0; *ptr && n < precision; n++)
- ++ptr;
- break;
-
-#if CONFIG_PRINTF_OCTAL_FORMATTER
- case 'o':
- if (flags.alternate_flag && !precision)
- precision++;
-#endif
- case 'x':
- hex = hex_tab;
- case 'u':
- case 'p':
- case 'X':
- if (format_flag == 'p')
-#if defined(__AVR__) || defined(__I196__) /* 16bit pointers */
- ulong = (unsigned long)(unsigned short)va_arg(ap, char *);
-#else /* 32bit pointers */
- ulong = (unsigned long)va_arg(ap, char *);
-#endif /* 32bit pointers */
- else if (flags.l_L_modifier)
- ulong = va_arg(ap, unsigned long);
- else if (flags.h_modifier)
- ulong = (unsigned long)(unsigned short)va_arg(ap, unsigned int);
- else
- ulong = va_arg(ap, unsigned int);
-
- flags.div_factor =
-#if CONFIG_PRINTF_OCTAL_FORMATTER
- (format_flag == 'o') ? DIV_OCT :
-#endif
- (format_flag == 'u') ? DIV_DEC : DIV_HEX;
- flags.plus_space_flag = PSF_NONE;
- goto INTEGRAL_CONVERSION;
-
- case 'd':
- case 'i':
- if (flags.l_L_modifier)
- ulong = (unsigned long)(long)va_arg(ap, long);
- else
- ulong = (unsigned long)(long)va_arg(ap, int);
-
- /* Extract sign */
- if ((signed long)ulong < 0)
- {
- flags.plus_space_flag = PSF_MINUS;
- ulong = (unsigned long)(-((signed long)ulong));
- }
-
- flags.div_factor = DIV_DEC;
-
- /* Now convert to digits */
-INTEGRAL_CONVERSION:
- ptr = buf_pointer = &buf[FRMWRI_BUFSIZE - 1];
- flags.nonzero_value = (ulong != 0);
-
- /* No char if zero and zero precision */
- if (precision != 0 || flags.nonzero_value)
- {
- switch (flags.div_factor)
- {
- case DIV_DEC:
- do
- *--buf_pointer = hex[ulong % 10];
- while (ulong /= 10);
- break;
-
- case DIV_HEX:
- do
- *--buf_pointer = hex[ulong % 16];
- while (ulong /= 16);
- break;
-#if CONFIG_PRINTF_OCTAL_FORMATTER
- case DIV_OCT:
- do
- *--buf_pointer = hex[ulong % 8];
- while (ulong /= 8);
- break;
-#endif
- }
- }
-
- /* "precision" takes precedence */
- if (precision < 0)
- if (flags.zeropad)
- precision = field_width - (flags.plus_space_flag != PSF_NONE);
- while (precision > (int)(ptr - buf_pointer))
- *--buf_pointer = '0';
-
- if (flags.alternate_flag && flags.nonzero_value)
- {
- if (format_flag == 'x' || format_flag == 'X')
- {
- *--buf_pointer = format_flag;
- *--buf_pointer = '0';
- }
-#if CONFIG_PRINTF_OCTAL_FORMATTER
- else if ((format_flag == 'o') && (*buf_pointer != '0'))
- {
- *--buf_pointer = '0';
- }
-#endif
- }
- ASSERT(buf_pointer >= buf);
- break;
-
-#if CONFIG_PRINTF > PRINTF_NOFLOAT
- case 'g':
- case 'G':
- n = 1;
- format_flag -= 2;
- if (! precision)
- {
- precision = 1;
- }
- goto FLOATING_CONVERSION;
- case 'f':
- format_flag = 0;
- case 'e':
- case 'E':
- n = 0;
-FLOATING_CONVERSION:
- if (precision < 0)
- {
- precision = 6;
- }
-
- if (sizeof(double) != sizeof(max_float_t))
- {
- fvalue = flags.l_L_modifier ?
- va_arg(ap,max_float_t) : va_arg(ap,double);
- }
- else
- fvalue = va_arg(ap,max_float_t);
-
- if (fvalue < 0)
- {
- flags.plus_space_flag = PSF_MINUS;
- fvalue = -fvalue;
- }
- ptr = float_conversion (fvalue,
- (short)precision,
- buf_pointer += field_width,
- format_flag,
- (char)n,
- flags.alternate_flag);
- if (flags.zeropad)
- {
- precision = field_width - (flags.plus_space_flag != PSF_NONE);
- while (precision > ptr - buf_pointer)
- *--buf_pointer = '0';
- }
- break;
-
-#endif /* CONFIG_PRINTF <= PRINTF_NOFLOAT */
-
- case '\0': /* Really bad place to find NUL in */
- format--;
-
- default:
- /* Undefined conversion! */
- ptr = buf_pointer = bad_conversion;
- ptr += sizeof(bad_conversion) - 1;
- break;
-
- }
-
- /*
- * This part emittes the formatted string to "put_one_char".
- */
-
- /* If field_width == 0 then nothing should be written. */
- precision = ptr - buf_pointer;
-
- if ( precision > field_width)
- {
- n = 0;
- }
- else
- {
- n = field_width - precision - (flags.plus_space_flag != PSF_NONE);
- }
-
- /* emit any leading pad characters */
- if (!flags.left_adjust)
- while (--n >= 0)
- {
- put_one_char(' ', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- }
-
- /* emit flag characters (if any) */
- if (flags.plus_space_flag)
- {
- put_one_char(flags.plus_space_flag == PSF_PLUS ? '+' : '-', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- }
-
-#if CPU_HARVARD
- if (flags.progmem)
- {
- while (--precision >= 0)
- {
- put_one_char(pgm_read_char(buf_pointer++), secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- }
- }
- else
-#endif /* CPU_HARVARD */
- {
- /* emit the string itself */
- while (--precision >= 0)
- {
- put_one_char(*buf_pointer++, secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- }
- }
-
- /* emit trailing space characters */
- if (flags.left_adjust)
- while (--n >= 0)
- {
- put_one_char(' ', secret_pointer);
-#if CONFIG_PRINTF_COUNT_CHARS
- nr_of_chars++;
-#endif
- }
- }
-
-#else /* PRINTF_REDUCED starts here */
-
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
- bool l_modifier, h_modifier;
- unsigned long u_val, div_val;
-#else
- unsigned int u_val, div_val;
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-
- char format_flag;
- unsigned int nr_of_chars, base;
- char outChar;
- char *ptr;
-
- nr_of_chars = 0;
- for (;;) /* Until full format string read */
- {
- while ((format_flag = PGM_READ_CHAR(format++)) != '%') /* Until '%' or '\0' */
- {
- if (!format_flag)
- return (nr_of_chars);
- put_one_char(format_flag, secret_pointer);
- nr_of_chars++;
- }
-
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
- /*=================================*/
- /* Optional 'l' or 'h' modifiers ? */
- /*=================================*/
- l_modifier = h_modifier = false;
- switch (PGM_READ_CHAR(format))
- {
- case 'l':
- l_modifier = true;
- format++;
- break;
-
- case 'h':
- h_modifier = true;
- format++;
- break;
- }
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
-
- switch (format_flag = PGM_READ_CHAR(format++))
- {
- case 'c':
- format_flag = va_arg(ap, int);
- default:
- put_one_char(format_flag, secret_pointer);
- nr_of_chars++;
- continue;
-
- case 's':
- ptr = va_arg(ap, char *);
- while ((format_flag = *ptr++))
- {
- put_one_char(format_flag, secret_pointer);
- nr_of_chars++;
- }
- continue;
-
- case 'o':
- base = 8;
- if (IS_SHORT)
- div_val = 0x8000;
- else
- div_val = 0x40000000;
- goto CONVERSION_LOOP;
-
- case 'd':
- base = 10;
- if (IS_SHORT)
- div_val = 10000;
- else
- div_val = 1000000000;
- goto CONVERSION_LOOP;
-
- case 'X':
- case 'x':
- base = 16;
- if (IS_SHORT)
- div_val = 0x1000;
- else
- div_val = 0x10000000;
-
-CONVERSION_LOOP:
-#if CONFIG_PRINTF > PRINTF_NOMODIFIERS
- if (h_modifier)
- u_val = (format_flag == 'd') ?
- (short)va_arg(ap, int) : (unsigned short)va_arg(ap, int);
- else if (l_modifier)
- u_val = va_arg(ap, long);
- else
- u_val = (format_flag == 'd') ?
- va_arg(ap,int) : va_arg(ap,unsigned int);
-#else /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
- u_val = va_arg(ap,int);
-#endif /* CONFIG_PRINTF > PRINTF_NOMODIFIERS */
- if (format_flag == 'd')
- {
- if (((int)u_val) < 0)
- {
- u_val = - u_val;
- put_one_char('-', secret_pointer);
- nr_of_chars++;
- }
- }
- while (div_val > 1 && div_val > u_val)
- {
- div_val /= base;
- }
- do
- {
- outChar = (u_val / div_val) + '0';
- if (outChar > '9')
- {
- if (format_flag == 'x')
- outChar += 'a'-'9'-1;
- else
- outChar += 'A'-'9'-1;
- }
- put_one_char(outChar, secret_pointer);
- nr_of_chars++;
- u_val %= div_val;
- div_val /= base;
- }
- while (div_val);
-
- } /* end switch(format_flag...) */
- }
-#endif /* CONFIG_PRINTF > PRINTF_REDUCED */
-}
-
-#endif /* CONFIG_PRINTF */
+++ /dev/null
-/**
- * \file
- * <!--
-* This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \brief Basic "printf", "sprintf" and "fprintf" formatter.
- */
-
-#ifndef MWARE_FORMATWR_H
-#define MWARE_FORMATWR_H
-
-#include <stdarg.h> /* va_list */
-#include <appconfig.h>
-#include <cpu/attr.h> /* CPU_HARVARD */
-
-/**
- * \name _formatted_write() configuration
- * \{
- */
-#define PRINTF_DISABLED 0
-#define PRINTF_NOMODIFIERS 1
-#define PRINTF_REDUCED 2
-#define PRINTF_NOFLOAT 3
-#define PRINTF_FULL 4
-/* \} */
-
-#ifndef CONFIG_PRINTF_RETURN_COUNT
- /** Enable/disable _formatted_write return value */
- #define CONFIG_PRINTF_RETURN_COUNT 1
-#endif
-
-int
-_formatted_write(
- const char *format,
- void put_char_func(char c, void *user_data),
- void *user_data,
- va_list ap);
-
-#if CPU_HARVARD
- #include <mware/pgm.h>
- int _formatted_write_P(
- const char * PROGMEM format,
- void put_char_func(char c, void *user_data),
- void *user_data,
- va_list ap);
-#endif /* CPU_HARVARD */
-
-#endif /* MWARE_FORMATWR_H */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- * All Rights Reserved.
- * -->
- *
- * \brief Portable hash table implementation
- *
- * Some rationales of our choices in implementation:
- *
- * \li For embedded systems, it is vital to allocate the table in static memory. To do
- * so, it is necessary to expose the \c HashNode and \c HashTable structures in the header file.
- * Nevertheless, they should be used as opaque types (that is, the users should not
- * access the structure fields directly).
- *
- * \li To statically allocate the structures, a macro is provided. With this macro, we
- * are hiding completely \c HashNode to the user (who only manipulates \c HashTable). Without
- * the macro, the user would have had to define both the \c HashNode and the \c HashTable
- * manually, and pass both of them to \c ht_init() (which would have created the link between
- * the two). Instead, the link is created with a literal initialization.
- *
- * \li The hash table is created as power of two to remove the divisions from the code.
- * Of course, hash functions work at their best when the table size is a prime number.
- * When calculating the modulus to convert the hash value to an index, the actual operation
- * becomes a bitwise AND: this is fast, but truncates the value losing bits. Thus, the higher
- * bits are first "merged" with the lower bits through some XOR operations (see the last line of
- * \c calc_hash()).
- *
- * \li To minimize the memory occupation, there is no flag to set for the empty node. An
- * empty node is recognized by its data pointer set to NULL. It is then invalid to store
- * NULL as data pointer in the table.
- *
- * \li The visiting interface through iterators is implemented with pass-by-value semantic.
- * While this is overkill for medium-to-stupid compilers, it is the best designed from an
- * user point of view. Moreover, being totally inlined (defined completely in the header),
- * even a stupid compiler should be able to perform basic optimizations on it.
- * We thought about using a pass-by-pointer semantic but it was much more awful to use, and
- * the compiler is then forced to spill everything to the stack (unless it is *very* smart).
- *
- * \li The current implementation allows to either store the key internally (that is, copy
- * the key within the hash table) or keep it external (that is, a hook is used to extract
- * the key from the data in the node). The former is more memory-hungry of course, as it
- * allocated static space to store the key copies. The overhead to keep both methods at
- * the same time is minimal:
- * <ul>
- * <li>There is a run-time check in node_get_key which is execute per each node visited.</li>
- * <li>Theoretically, there is no memory overhead. In practice, there were no
- * flags in \c struct HashTable till now, so we had to add a first bit flag, but the
- * overhead will disappear if a second flag is added for a different reason later.</li>
- * <li>There is a little interface overhead, since we have two different versions of
- * \c ht_insert(), one with the key passed as parameter and one without, but in
- * the common case (external keys) both can be used.</li>
- * </ul>
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.8 2007/02/06 16:05:01 asterix
- *#* Replaced ROTATE_* with ROT* defined in macros.h
- *#*
- *#* Revision 1.7 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2006/06/01 12:27:39 marco
- *#* Added utilities for protocols
- *#*
- *#*/
-
-#include "hashtable.h"
-#include <cfg/debug.h>
-#include <cfg/compiler.h>
-#include <cfg/macros.h> //ROTL(), ROTR();
-
-#include <string.h>
-
-
-
-typedef const void** HashNodePtr;
-#define NODE_EMPTY(node) (!*(node))
-#define HT_HAS_INTERNAL_KEY(ht) (CONFIG_HT_OPTIONAL_INTERNAL_KEY && ht->flags.key_internal)
-
-/** For hash tables with internal keys, compute the pointer to the internal key for a given \a node. */
-INLINE uint8_t *key_internal_get_ptr(struct HashTable *ht, HashNodePtr node)
-{
- uint8_t* key_buf = ht->key_data.mem;
- size_t index;
-
- // Compute the index of the node and use it to move within the whole key buffer
- index = node - &ht->mem[0];
- ASSERT(index < (size_t)(1 << ht->max_elts_log2));
- key_buf += index * (INTERNAL_KEY_MAX_LENGTH + 1);
-
- return key_buf;
-}
-
-
-INLINE void node_get_key(struct HashTable* ht, HashNodePtr node, const void** key, uint8_t* key_length)
-{
- if (HT_HAS_INTERNAL_KEY(ht))
- {
- uint8_t* k = key_internal_get_ptr(ht, node);
-
- // Key has its length stored in the first byte
- *key_length = *k++;
- *key = k;
- }
- else
- *key = ht->key_data.hook(*node, key_length);
-}
-
-
-INLINE bool node_key_match(struct HashTable* ht, HashNodePtr node, const void* key, uint8_t key_length)
-{
- const void* key2;
- uint8_t key2_length;
-
- node_get_key(ht, node, &key2, &key2_length);
-
- return (key_length == key2_length && memcmp(key, key2, key_length) == 0);
-}
-
-
-static uint16_t calc_hash(const void* _key, uint8_t key_length)
-{
- const char* key = (const char*)_key;
- uint16_t hash = key_length;
- int i;
- int len = (int)key_length;
-
- for (i = 0; i < len; ++i)
- hash = ROTL(hash, 4) ^ key[i];
-
- return hash ^ (hash >> 6) ^ (hash >> 13);
-}
-
-
-static HashNodePtr perform_lookup(struct HashTable* ht,
- const void* key, uint8_t key_length)
-{
- uint16_t hash = calc_hash(key, key_length);
- uint16_t mask = ((1 << ht->max_elts_log2) - 1);
- uint16_t index = hash & mask;
- uint16_t first_index = index;
- uint16_t step;
- HashNodePtr node;
-
- // Fast-path optimization: we check immediately if the current node
- // is the one we were looking for, so we save the computation of the
- // increment step in the common case.
- node = &ht->mem[index];
- if (NODE_EMPTY(node)
- || node_key_match(ht, node, key, key_length))
- return node;
-
- // Increment while going through the hash table in case of collision.
- // This implements the double-hash technique: we use the higher part
- // of the hash as a step increment instead of just going to the next
- // element, to minimize the collisions.
- // Notice that the number must be odd to be sure that the whole table
- // is traversed. Actually MCD(table_size, step) must be 1, but
- // table_size is always a power of 2, so we just ensure that step is
- // never a multiple of 2.
- step = (ROTR(hash, ht->max_elts_log2) & mask) | 1;
-
- do
- {
- index += step;
- index &= mask;
-
- node = &ht->mem[index];
- if (NODE_EMPTY(node)
- || node_key_match(ht, node, key, key_length))
- return node;
-
- // The check is done after the key compare. This actually causes
- // one more compare in the case the table is full (since the first
- // element was compared at the very start, and then at the end),
- // but it makes faster the common path where we enter this loop
- // for the first time, and index will not match first_index for
- // sure.
- } while (index != first_index);
-
- return NULL;
-}
-
-
-void ht_init(struct HashTable* ht)
-{
- memset(ht->mem, 0, sizeof(ht->mem[0]) * (1 << ht->max_elts_log2));
-}
-
-
-static bool insert(struct HashTable* ht, const void* key, uint8_t key_length, const void* data)
-{
- HashNodePtr node;
-
- if (!data)
- return false;
-
- if (HT_HAS_INTERNAL_KEY(ht))
- key_length = MIN(key_length, (uint8_t)INTERNAL_KEY_MAX_LENGTH);
-
- node = perform_lookup(ht, key, key_length);
- if (!node)
- return false;
-
- if (HT_HAS_INTERNAL_KEY(ht))
- {
- uint8_t* k = key_internal_get_ptr(ht, node);
- *k++ = key_length;
- memcpy(k, key, key_length);
- }
-
- *node = data;
- return true;
-}
-
-
-bool ht_insert_with_key(struct HashTable* ht, const void* key, uint8_t key_length, const void* data)
-{
-#ifdef _DEBUG
- if (!HT_HAS_INTERNAL_KEY(ht))
- {
- // Construct a fake node and use it to match the key
- HashNodePtr node = &data;
- if (!node_key_match(ht, node, key, key_length))
- {
- ASSERT2(0, "parameter key is different from the external key");
- return false;
- }
- }
-#endif
-
- return insert(ht, key, key_length, data);
-}
-
-
-bool ht_insert(struct HashTable* ht, const void* data)
-{
- const void* key;
- uint8_t key_length;
-
-#ifdef _DEBUG
- if (HT_HAS_INTERNAL_KEY(ht))
- {
- ASSERT("parameter cannot be a hash table with internal keys - use ht_insert_with_key()"
- && 0);
- return false;
- }
-#endif
-
- key = ht->key_data.hook(data, &key_length);
-
- return insert(ht, key, key_length, data);
-}
-
-
-const void* ht_find(struct HashTable* ht, const void* key, uint8_t key_length)
-{
- HashNodePtr node;
-
- if (HT_HAS_INTERNAL_KEY(ht))
- key_length = MIN(key_length, (uint8_t)INTERNAL_KEY_MAX_LENGTH);
-
- node = perform_lookup(ht, key, key_length);
-
- if (!node || NODE_EMPTY(node))
- return NULL;
-
- return *node;
-}
-
-
-#if 0
-
-#include <stdlib.h>
-
-bool ht_test(void);
-
-static const void* test_get_key(const void* ptr, uint8_t* length)
-{
- const char* s = ptr;
- *length = strlen(s);
- return s;
-}
-
-#define NUM_ELEMENTS 256
-DECLARE_HASHTABLE_STATIC(test1, 256, test_get_key);
-DECLARE_HASHTABLE_INTERNALKEY_STATIC(test2, 256);
-
-static char data[NUM_ELEMENTS][10];
-static char keydomain[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-static bool single_test(void)
-{
- int i;
-
- ht_init(&test1);
- ht_init(&test2);
-
- for (i=0;i<NUM_ELEMENTS;i++)
- {
- int k;
- int klen;
-
- do
- {
- klen = (rand() % 8) + 1;
- for (k=0;k<klen;k++)
- data[i][k] = keydomain[rand() % (sizeof(keydomain)-1)];
- data[i][k]=0;
- } while (ht_find_str(&test1, data[i]) != NULL);
-
- ASSERT(ht_insert(&test1, data[i]));
- ASSERT(ht_insert_str(&test2, data[i], data[i]));
- }
-
- for (i=0;i<NUM_ELEMENTS;i++)
- {
- char *found1, *found2;
-
- found1 = (char*)ht_find_str(&test1, data[i]);
- if (strcmp(found1, data[i]) != 0)
- {
- ASSERT(strcmp(found1,data[i]) == 0);
- return false;
- }
-
- found2 = (char*)ht_find_str(&test2, data[i]);
- if (strcmp(found2, data[i]) != 0)
- {
- ASSERT(strcmp(found2,data[i]) == 0);
- return false;
- }
- }
-
- return true;
-}
-
-static uint16_t rand_seeds[] = { 1, 42, 666, 0xDEAD, 0xBEEF, 0x1337, 0xB00B };
-
-bool ht_test(void)
-{
- int i;
-
- for (i=0;i<countof(rand_seeds);++i)
- {
- srand(rand_seeds[i]);
- if (!single_test())
- {
- kprintf("ht_test failed\n");
- return false;
- }
- }
-
- kprintf("ht_test successful\n");
- return true;
-}
-
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- * All Rights Reserved.
- * -->
- *
- * \brief Portable hash table
- *
- * This file implements a portable hash table, with the following features:
- *
- * \li Open double-hashing. The maximum number of elements is fixed. The double hashing
- * function improves recovery in case of collisions.
- * \li Configurable size (which is clamped to a power of two)
- * \li Visiting interface through iterator (returns the element in random order).
- * \li The key is stored within the data and a hook is used to extract it. Optionally, it
- * is possible to store a copy of the key within the hash table.
- *
- * Since the hashing is open, there is no way to remove elements from the table. Instead, a
- * function is provided to clear the table completely.
- *
- * The data stored within the table must be a pointer. The NULL pointer is used as
- * a marker for a free node, so it is invalid to store a NULL pointer in the table
- * with \c ht_insert().
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.8 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.7 2006/06/01 12:27:39 marco
- *#* Added utilities for protocols
- *#*
- *#*/
-
-#ifndef MWARE_HASHTABLE_H
-#define MWARE_HASHTABLE_H
-
-#include <cfg/compiler.h>
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-/**
- * Enable/disable support to declare special hash tables which maintain a copy of
- * the key internally instead of relying on the hook to extract it from the data.
- */
-#define CONFIG_HT_OPTIONAL_INTERNAL_KEY 1
-
-/// Maximum length of the internal key (use (2^n)-1 for slight speedup)
-#define INTERNAL_KEY_MAX_LENGTH 15
-
-/**
- * Hook to get the key from \a data, which is an element of the hash table. The
- * key must be returned together with \a key_length (in words).
- */
-typedef const void *(*hook_get_key)(const void *data, uint8_t *key_length);
-
-
-/**
- * Hash table description
- *
- * \note This structures MUST NOT be accessed directly. Its definition is
- * provided in the header file only for optimization purposes (see the rationale
- * in hashtable.c).
- *
- * \note If new elements must be added to this list, please double check
- * \c DECLARE_HASHTABLE, which requires the existing elements to be at the top.
- */
-struct HashTable
-{
- const void **mem; ///< Buckets of data
- uint16_t max_elts_log2; ///< Log2 of the size of the table
- struct {
- bool key_internal : 1; ///< true if the key is copied internally
- } flags;
- union {
- hook_get_key hook; ///< Hook to get the key
- uint8_t *mem; ///< Pointer to the key memory
- } key_data;
-};
-
-
-/// Iterator to walk the hash table
-typedef struct
-{
- const void** pos;
- const void** end;
-} HashIterator;
-
-
-/**
- * Declare a hash table in the current scope
- *
- * \param name Variable name
- * \param size Number of elements
- * \param hook_gk Hook to be used to extract the key from the node
- *
- * \note The number of elements will be rounded down to the nearest
- * power of two.
- *
- */
-#define DECLARE_HASHTABLE(name, size, hook_gk) \
- static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
- struct HashTable name = { name##_nodes, UINT32_LOG2(size), { false }, hook_gk }
-
-/** Exactly like \c DECLARE_HASHTABLE, but the variable will be declared as static. */
-#define DECLARE_HASHTABLE_STATIC(name, size, hook_gk) \
- static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
- static struct HashTable name = { name##_nodes, UINT32_LOG2(size), { false }, { hook_gk } }
-
-#if CONFIG_HT_OPTIONAL_INTERNAL_KEY
- /** Declare a hash table with internal copies of the keys. This version does not
- * require a hook, nor it requires the user to allocate static memory for the keys.
- * It is mostly suggested for tables whose keys are computed on the fly and need
- * to be stored somewhere.
- */
- #define DECLARE_HASHTABLE_INTERNALKEY(name, size) \
- static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
- static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
- struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
-
- /** Exactly like \c DECLARE_HASHTABLE_INTERNALKEY, but the variable will be declared as static. */
- #define DECLARE_HASHTABLE_INTERNALKEY_STATIC(name, size) \
- static uint8_t name##_keys[(1 << UINT32_LOG2(size)) * (INTERNAL_KEY_MAX_LENGTH + 1)]; \
- static const void* name##_nodes[1 << UINT32_LOG2(size)]; \
- static struct HashTable name = { name##_nodes, UINT32_LOG2(size), { true }, name##_keys }
-#endif
-
-/**
- * Initialize (and clear) a hash table in a memory buffer.
- *
- * \param ht Hash table declared with \c DECLARE_HASHTABLE
- *
- * \note This function must be called before using the hash table. Optionally,
- * it can be called later in the program to clear the hash table,
- * removing all its elements.
- */
-void ht_init(struct HashTable* ht);
-
-/**
- * Insert an element into the hash table
- *
- * \param ht Handle of the hash table
- * \param data Data to be inserted into the table
- * \return true if insertion was successful, false otherwise (table is full)
- *
- * \note The key for the element to insert is extract from the data with
- * the hook. This means that this function cannot be called for hashtables
- * with internal keys.
- *
- * \note If an element with the same key already exists in the table,
- * it will be overwritten.
- *
- * \note It is not allowed to store NULL in the table. If you pass NULL as data,
- * the function call will fail.
- */
-bool ht_insert(struct HashTable* ht, const void* data);
-
-/**
- * Insert an element into the hash table
- *
- * \param ht Handle of the hash table
- * \param key Key of the element
- * \param key_length Length of the key in characters
- * \param data Data to be inserted into the table
- * \return true if insertion was successful, false otherwise (table is full)
- *
- * \note If this function is called for hash table with external keys,
- * the key provided must be match the key that would be extracted with the
- * hook, otherwise the function will fail.
- *
- * \note If an element with the same key already exists in the table,
- * it will be overwritten.
- *
- * \note It is not allowed to store NULL in the table. If you pass NULL as data,
- * the function call will fail.
- */
-bool ht_insert_with_key(struct HashTable* ht, const void* key, uint8_t key_length, const void* data);
-
-/**
- * Find an element in the hash table
- *
- * \param ht Handle of the hash table
- * \param key Key of the element
- * \param key_length Length of the key in characters
- * \return Data of the element, or NULL if no element was found for the given key.
- */
-const void* ht_find(struct HashTable* ht, const void* key, uint8_t key_length);
-
-/** Similar to \c ht_insert_with_key() but \a key is an ASCIIZ string */
-#define ht_insert_str(ht, key, data) ht_insert_with_key(ht, key, strlen(key), data)
-
-/** Similar to \c ht_find() but \a key is an ASCIIZ string */
-#define ht_find_str(ht, key) ht_find(ht, key, strlen(key))
-
-/// Get an iterator to the begin of the hash table \a ht
-INLINE HashIterator ht_iter_begin(struct HashTable* ht)
-{
- HashIterator h;
-
- h.pos = &ht->mem[0];
- h.end = &ht->mem[1 << ht->max_elts_log2];
-
- while (h.pos != h.end && !*h.pos)
- ++h.pos;
-
- return h;
-}
-
-/**
- * Get an iterator to the (exclusive) end of the hash table \a ht
- *
- * \note Like in STL, the end iterator is not a valid iterator (you
- * cannot call \c ht_iter_get() on it), and it must be used only to
- * detect if we reached the end of the iteration (through \c ht_iter_cmp()).
- */
-INLINE HashIterator ht_iter_end(struct HashTable* ht)
-{
- HashIterator h;
-
- h.pos = h.end = &ht->mem[1 << ht->max_elts_log2];
-
- return h;
-}
-
-/// Compare \a it1 and \a it2 for equality
-INLINE bool ht_iter_cmp(HashIterator it1, HashIterator it2)
-{
- ASSERT(it1.end == it2.end);
- return it1.pos == it2.pos;
-}
-
-/// Get the element within the hash table \a ht pointed by the iterator \a iter
-INLINE const void* ht_iter_get(HashIterator iter)
-{ return *iter.pos; }
-
-/** Return an iterator pointing to the element following \a h
- *
- * \note The order of the elements visited during the iteration is casual,
- * and depends on the implementation.
- *
- */
-INLINE HashIterator ht_iter_next(HashIterator h)
-{
- ++h.pos;
- while (h.pos != h.end && !(*h.pos))
- ++h.pos;
-
- return h;
-}
-
-#endif /* MWARE_HASHTABLE_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Heap subsystem (public interface).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.9 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.8 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.7 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.6 2004/10/26 09:02:13 bernie
- *#* heap_free(): Handle NULL pointers like free(), write documentation.
- *#*
- *#* Revision 1.5 2004/10/03 20:43:22 bernie
- *#* Import changes from sc/firmware.
- *#*
- *#* Revision 1.1 2004/07/31 16:33:58 rasky
- *#* Spostato lo heap da kern/ a mware/
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 17:27:00 bernie
- *#* Import kern/ subdirectory.
- *#*
- *#*/
-
-#include "heap.h"
-#include <string.h> // memset()
-#include <cfg/macros.h> // IS_POW2()
-#include <cfg/debug.h> // ASSERT()
-
-/* NOTE: struct size must be a 2's power! */
-typedef struct _MemChunk
-{
- struct _MemChunk *next;
- size_t size;
-} MemChunk;
-
-STATIC_ASSERT(IS_POW2(sizeof(MemChunk)));
-
-#define FREE_FILL_CODE 0xDEAD
-#define ALLOC_FILL_CODE 0xBEEF
-
-void heap_init(struct Heap* h, void* memory, size_t size)
-{
-#ifdef _DEBUG
- memset(memory, FREE_FILL_CODE, size);
-#endif
-
- /* Initialize heap with a single big chunk */
- h->FreeList = (MemChunk *)memory;
- h->FreeList->next = NULL;
- h->FreeList->size = size;
-}
-
-
-void *heap_allocmem(struct Heap* h, size_t size)
-{
- MemChunk *chunk, *prev;
-
- /* Round size up to the allocation granularity */
- size = ROUND2(size, sizeof(MemChunk));
-
- /* Handle allocations of 0 bytes */
- if (!size)
- size = sizeof(MemChunk);
-
- /* Walk on the free list looking for any chunk big enough to
- * fit the requested block size.
- */
- for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
- chunk;
- prev = chunk, chunk = chunk->next)
- {
- if (chunk->size >= size)
- {
- if (chunk->size == size)
- {
- /* Just remove this chunk from the free list */
- prev->next = chunk->next;
- #ifdef _DEBUG
- memset(chunk, ALLOC_FILL_CODE, size);
- #endif
- return (void *)chunk;
- }
- else
- {
- /* Allocate from the END of an existing chunk */
- chunk->size -= size;
- #ifdef _DEBUG
- memset((uint8_t *)chunk + chunk->size, ALLOC_FILL_CODE, size);
- #endif
- return (void *)((uint8_t *)chunk + chunk->size);
- }
- }
- }
-
- return NULL; /* fail */
-}
-
-
-void heap_freemem(struct Heap* h, void *mem, size_t size)
-{
- MemChunk *prev;
-
- ASSERT(mem);
-
-#ifdef _DEBUG
- memset(mem, FREE_FILL_CODE, size);
-#endif
-
- /* Round size up to the allocation granularity */
- size = ROUND2(size, sizeof(MemChunk));
-
- /* Handle allocations of 0 bytes */
- if (!size)
- size = sizeof(MemChunk);
-
- /* Special case: first chunk in the free list */
- ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList);
- if (((uint8_t *)mem) < ((uint8_t *)h->FreeList))
- {
- /* Insert memory block before the current free list head */
- prev = (MemChunk *)mem;
- prev->next = h->FreeList;
- prev->size = size;
- h->FreeList = prev;
- }
- else /* Normal case: not the first chunk in the free list */
- {
- /*
- * Walk on the free list. Stop at the insertion point (when mem
- * is between prev and prev->next)
- */
- prev = h->FreeList;
- while (prev->next < (MemChunk *)mem && prev->next)
- prev = prev->next;
-
- /* Make sure mem is not *within* prev */
- ASSERT((uint8_t*)mem >= (uint8_t*)prev + prev->size);
-
- /* Should it be merged with previous block? */
- if (((uint8_t *)prev) + prev->size == ((uint8_t *)mem))
- {
- /* Yes */
- prev->size += size;
- }
- else /* not merged with previous chunk */
- {
- MemChunk *curr = (MemChunk*)mem;
-
- /* insert it after the previous node
- * and move the 'prev' pointer forward
- * for the following operations
- */
- curr->next = prev->next;
- curr->size = size;
- prev->next = curr;
-
- /* Adjust for the following test */
- prev = curr;
- }
- }
-
- /* Also merge with next chunk? */
- if (((uint8_t *)prev) + prev->size == ((uint8_t *)prev->next))
- {
- prev->size += prev->next->size;
- prev->next = prev->next->next;
-
- /* There should be only one merge opportunity, becuase we always merge on free */
- ASSERT((uint8_t*)prev + prev->size != (uint8_t*)prev->next);
- }
-}
-
-#if CONFIG_HEAP_MALLOC
-
-void *heap_malloc(struct Heap* h, size_t size)
-{
- size_t *mem;
-
- size += sizeof(size_t);
- if ((mem = (size_t*)heap_allocmem(h, size)))
- *mem++ = size;
-
- return mem;
-}
-
-void *heap_calloc(struct Heap* h, size_t size)
-{
- void *mem;
-
- if ((mem = heap_malloc(h, size)))
- memset(mem, 0, size);
-
- return mem;
-}
-
-/**
- * Free a block of memory, determining its size automatically.
- *
- * \param h Heap from which the block was allocated.
- * \param mem Pointer to a block of memory previously allocated with
- * either heap_malloc() or heap_calloc().
- *
- * \note If \a mem is a NULL pointer, no operation is performed.
- *
- * \note Freeing the same memory block twice has undefined behavior.
- *
- * \note This function works like the ANSI C free().
- */
-void heap_free(struct Heap *h, void *mem)
-{
- size_t *_mem = (size_t *)mem;
-
- if (_mem)
- {
- --_mem;
- heap_freemem(h, _mem, *_mem);
- }
-}
-
-#endif /* CONFIG_HEAP_MALLOC */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999,2000,2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Heap subsystem (public interface).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \todo Heap memory could be defined as an array of MemChunk, and used
- * in this form also within the implementation. This would probably remove
- * memory alignment problems, and also some aliasing issues.
- *
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:27 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2005/11/27 23:36:19 bernie
- *#* Use appconfig.h instead of cfg/config.h.
- *#*
- *#* Revision 1.5 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.4 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.3 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.2 2004/08/04 15:54:18 rasky
- *#* Merge da SC: prima versione veramente funzionante
- *#*
- *#* Revision 1.1 2004/07/31 16:33:58 rasky
- *#* Spostato lo heap da kern/ a mware/
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 17:27:00 bernie
- *#* Import kern/ subdirectory.
- *#*
- *#*/
-
-#ifndef MWARE_HEAP_H
-#define MWARE_HEAP_H
-
-#include <cfg/compiler.h>
-#include <appconfig.h>
-
-struct _MemChunk;
-
-/// A heap
-struct Heap
-{
- struct _MemChunk *FreeList; ///< Head of the free list
-};
-
-
-/// Initialize \a heap within the buffer pointed by \a memory which is of \a size bytes
-void heap_init(struct Heap* heap, void* memory, size_t size);
-
-/// Allocate a chunk of memory of \a size bytes from the heap
-void *heap_allocmem(struct Heap* heap, size_t size);
-
-/// Free a chunk of memory of \a size bytes from the heap
-void heap_freemem(struct Heap* heap, void *mem, size_t size);
-
-
-#define HNEW(heap, type) \
- (type*)heap_allocmem(heap, sizeof(type))
-
-#define HNEWVEC(heap, type, nelem) \
- (type*)heap_allocmem(heap, sizeof(type) * (nelem))
-
-#define HDELETE(heap, type, mem) \
- heap_freemem(heap, mem, sizeof(type))
-
-#define HDELETEVEC(heap, type, nelem, mem) \
- heap_freemem(heap, mem, sizeof(type) * (nelem))
-
-
-#if CONFIG_HEAP_MALLOC
-
-void *heap_malloc(struct Heap* heap, size_t size);
-void *heap_calloc(struct Heap* heap, size_t size);
-void heap_free(struct Heap* heap, void * mem);
-
-#endif
-
-#endif /* MWARE_HEAP_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Poor man's hex arrays (implementation).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-
-#include "hex.h"
-
-const char hex_tab[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
-const char HEX_tab[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Poor man's hex arrays (implementation).
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#ifndef MWARE_HEX_H
-#define MWARE_HEX_H
-
-extern const char hex_tab[16];
-extern const char HEX_tab[16];
-
-#endif /* MWARE_HEX_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief General pourpose double-linked lists
- */
-
-#ifndef MWARE_LIST_H
-#define MWARE_LIST_H
-
-#include <cfg/compiler.h> /* INLINE */
-#include <cfg/debug.h> /* ASSERT() */
-
-/**
- * This structure represents a node for bidirectional lists.
- *
- * Data is usually appended to nodes by making them the first
- * field of another struture, as a poor-man's form of inheritance.
- */
-typedef struct _Node
-{
- struct _Node *succ;
- struct _Node *pred;
-} Node;
-
-/**
- * Head of a doubly-linked list of \c Node structs.
- *
- * Lists must be initialized with LIST_INIT() prior to use.
- *
- * Nodes can be added and removed from either end of the list
- * with O(1) performance. Iterating over these lists can be
- * tricky: use the FOREACH_NODE() macro instead.
- */
-typedef struct _List
-{
- Node head;
- Node tail;
-} List;
-
-/**
- * Extended node for priority queues.
- */
-typedef struct _PriNode
-{
- Node link;
- int pri;
-} PriNode;
-
-
-/**
- * Template for a naked node in a list of \a T structures.
- *
- * To be used as data member in other structures:
- *
- * \code
- * struct Foo
- * {
- * DECLARE_NODE_ANON(struct Foo)
- * int a;
- * float b;
- * }
- *
- * DECLARE_LIST_TYPE(Foo);
- *
- * void foo(void)
- * {
- * static LIST_TYPE(Foo) foo_list;
- * static Foo foo1, foo2;
- * Foo *fp;
- *
- * LIST_INIT(&foo_list);
- * ADDHEAD(&foo_list, &foo1);
- * INSERT_BEFORE(&foo_list, &foo2);
- * FOREACH_NODE(fp, &foo_list)
- * fp->a = 10;
- * }
- *
- * \endcode
- */
-#define DECLARE_NODE_ANON(T) \
- T *succ; T *pred;
-
-/** Declare a typesafe node for structures of type \a T. */
-#define DECLARE_NODE_TYPE(T) \
- typedef struct T##Node { T *succ; T *pred; } T##Node
-
-/** Template for a list of \a T structures. */
-#define DECLARE_LIST_TYPE(T) \
- DECLARE_NODE_TYPE(T); \
- typedef struct T##List { \
- T##Node head; \
- T##Node tail; \
- } T##List
-
-#define NODE_TYPE(T) T##Node
-#define LIST_TYPE(T) T##List
-
-/**
- * Get a pointer to the first node in a list.
- *
- * If \a l is empty, result points to l->tail.
- */
-#define LIST_HEAD(l) ((l)->head.succ)
-
-/**
- * Get a pointer to the last node in a list.
- *
- * If \a l is empty, result points to l->head.
- */
-#define LIST_TAIL(l) ((l)->tail.pred)
-
-// TODO: move in compiler.h
-#if COMPILER_TYPEOF
- #define TYPEOF_OR_VOIDPTR(type) typeof(type)
-#else
- #define TYPEOF_OR_VOIDPTR(type) void *
-#endif
-
-/**
- * Iterate over all nodes in a list.
- *
- * This macro generates a "for" statement using the following parameters:
- * \param n Node pointer to be used in each iteration.
- * \param l Pointer to list.
- */
-#define FOREACH_NODE(n, l) \
- for( \
- (n) = (TYPEOF_OR_VOIDPTR(n))LIST_HEAD(l); \
- ((Node *)(n))->succ; \
- (n) = (TYPEOF_OR_VOIDPTR(n))(((Node *)(n))->succ) \
- )
-
-/**
- * Iterate backwards over all nodes in a list.
- *
- * This macro generates a "for" statement using the following parameters:
- * \param n Node pointer to be used in each iteration.
- * \param l Pointer to list.
- */
-#define REVERSE_FOREACH_NODE(n, l) \
- for( \
- (n) = (TYPEOF_OR_VOIDPTR(n))LIST_TAIL(l); \
- ((Node *)(n))->pred; \
- (n) = (TYPEOF_OR_VOIDPTR(n))(((Node *)(n))->pred) \
- )
-
-/** Initialize a list. */
-#define LIST_INIT(l) \
- do { \
- (l)->head.succ = (TYPEOF_OR_VOIDPTR((l)->head.succ)) &(l)->tail; \
- (l)->head.pred = NULL; \
- (l)->tail.succ = NULL; \
- (l)->tail.pred = (TYPEOF_OR_VOIDPTR((l)->tail.pred)) &(l)->head; \
- } while (0)
-
-#ifdef _DEBUG
- /** Make sure that a list is valid (it was initialized and is not corrupted). */
- #define LIST_ASSERT_VALID(l) \
- do { \
- Node *n, *pred; \
- ASSERT((l)->head.succ != NULL); \
- ASSERT((l)->head.pred == NULL); \
- ASSERT((l)->tail.succ == NULL); \
- ASSERT((l)->tail.pred != NULL); \
- pred = &(l)->head; \
- FOREACH_NODE(n, l) \
- { \
- ASSERT(n->pred == pred); \
- pred = n; \
- } \
- ASSERT(n == &(l)->tail); \
- } while (0)
-
- #define INVALIDATE_NODE(n) ((n)->succ = (n)->pred = NULL)
-#else
- #define LIST_ASSERT_VALID(l) do {} while (0)
- #define INVALIDATE_NODE(n) do {} while (0)
-#endif
-
-/** Add node to list head. */
-#define ADDHEAD(l,n) \
- do { \
- ASSERT(l); \
- ASSERT(n); \
- (n)->succ = (l)->head.succ; \
- (n)->pred = (l)->head.succ->pred; \
- (n)->succ->pred = (n); \
- (n)->pred->succ = (n); \
- } while (0)
-
-/** Add node to list tail. */
-#define ADDTAIL(l,n) \
- do { \
- ASSERT(l); \
- ASSERT(n); \
- (n)->succ = &(l)->tail; \
- (n)->pred = (l)->tail.pred; \
- (n)->pred->succ = (n); \
- (l)->tail.pred = (n); \
- } while (0)
-
-/**
- * Insert node \a n before node \a ln.
- *
- * \note You can't pass in a list header as \a ln, but
- * it is safe to pass list-\>head of an empty list.
- */
-#define INSERT_BEFORE(n,ln) \
- do { \
- (n)->succ = (ln); \
- (n)->pred = (ln)->pred; \
- (ln)->pred->succ = (n); \
- (ln)->pred = (n); \
- } while (0)
-
-/**
- * Remove \a n from whatever list it is in.
- *
- * \note Removing a node that has not previously been
- * inserted into a list invokes undefined behavior.
- */
-#define REMOVE(n) \
- do { \
- (n)->pred->succ = (n)->succ; \
- (n)->succ->pred = (n)->pred; \
- INVALIDATE_NODE(n); \
- } while (0)
-
-/** Tell whether a list is empty. */
-#define LIST_EMPTY(l) ( (void *)((l)->head.succ) == (void *)(&(l)->tail) )
-
-/**
- * Insert a priority node in a priority queue.
- *
- * The new node is inserted immediately before the
- * first node with lower priority or appended to
- * the tail if no such node exists.
- */
-#define LIST_ENQUEUE(list, node) \
- do { \
- PriNode *ln; \
- FOREACH_NODE(ln, (list)) \
- if (ln->pri < (node)->pri) \
- break; \
- INSERT_BEFORE(&(node)->link, &ln->link); \
- } while (0)
-
-
-/**
- * Unlink a node from the head of the list \a l.
- *
- * \return Pointer to node, or NULL if the list was empty.
- */
-INLINE Node *list_remHead(List *l)
-{
- Node *n;
-
- if (LIST_EMPTY(l))
- return (Node *)0;
-
- n = l->head.succ; /* Get first node. */
- l->head.succ = n->succ; /* Link list head to second node. */
- n->succ->pred = &l->head; /* Link second node to list head. */
-
- INVALIDATE_NODE(n);
- return n;
-}
-
-/**
- * Unlink a node from the tail of the list \a l.
- *
- * \return Pointer to node, or NULL if the list was empty.
- */
-INLINE Node *list_remTail(List *l)
-{
- Node *n;
-
- if (LIST_EMPTY(l))
- return (Node *)0;
-
- n = l->tail.pred; /* Get last node. */
- l->tail.pred = n->pred; /* Link list tail to second last node. */
- n->pred->succ = &l->tail; /* Link second last node to list tail. */
-
- INVALIDATE_NODE(n);
- return n;
-}
-
-#endif /* MWARE_LIST_H */
+++ /dev/null
-#warning revise me!
-
-
-/**
- * DECLARE_SMEAN(temperature, uint8_t, uint16_t);
- * for (i = 0; i < TEMP_MEANS; ++i)
- * SMEAN_ADD(temperature, adc_get(), TEMP_MEANS);
- * printf("mean temperature = %d\n", SMEAN_GET(temperature));
- */
-
-/**
- * Instantiate a mean instance
- */
-#define DECLARE_SMEAN(name, Type, SumType) \
- struct { \
- SumType sum; \
- Type result; \
- int count; \
- } name = { 0, 0, 0 }
-
-/**
- * Insert a new sample into the mean.
- *
- * \note \a mean and \a max_samples are evaluated multiple times
- */
-#define SMEAN_ADD(mean, sample, max_samples) \
- do { \
- (mean).sum += (sample); \
- if ((mean).count++ >= (max_samples)) \
- { \
- (mean).result = (mean).sum / (max_samples); \
- (mean).sum = 0; \
- (mean).count = 0; \
- } \
- } while (0)
-
-/**
- * Return current mean value.
- */
-#define SMEAN_GET(mean) ((mean).result)
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Messages for LCD.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/07/19 12:56:28 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.1 2005/03/01 23:31:02 bernie
- *#* String table and localization stuff.
- *#*
- *#*/
-
-#include "msg.h"
-
-/**
- * Array of pointers to localized strings. Should be filled
- * by localization stuff, but not for now.
- */
-const char *msg_strings[MSG_COUNT] = {
- 0,
- // TODO: add your strings here
-};
-
-/* Buffer for catalog file */
-/* char msg_buf[MSG_BUFSIZE]; */
-
-
-/* The following does not work (move string tables into the DMSG/CMSG segments)
- * #pragma memory=dataseg(DMSG)
- * #pragma memory=constseg(CMSG)
- */
-
-
-/**
- * Untranslated constant strings used more than once are
- * grouped here to save ROM space.
- */
-const char
- str_empty[] = "";
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Definitions of constant string messages.
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.2 2006/02/10 11:30:37 bernie
- *#* C++ fixes.
- *#*
- *#* Revision 1.1 2005/03/01 23:31:02 bernie
- *#* String table and localization stuff.
- *#*
- *#*/
-#ifndef MWARE_MSG_H
-#define MWARE_MSG_H
-
-enum
-{
- MSG_NULL,
-
- // TODO: add your labels here.
-
- MSG_COUNT
-};
-
-
-#define MSG_BUFSIZE 6144 /* FIXME: how much? */
-
-/* String tables */
-extern const char *msg_strings const [MSG_COUNT];
-/* extern char msg_buf[MSG_BUFSIZE]; */
-
-
-/* Macros to access translated messages */
-#define MSG(x) msg_strings[x]
-#define PTRMSG(x) ((x) < (const_iptr_t)256 ? msg_strings[(unsigned int)(x)] : (const char *)(x))
-
-
-#endif /* MWARE_MSG_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Simple notifier for the observer/subject pattern (implementation)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "observer.h"
-#include <cpu/irq.h> // IRQ_DISABLE/IRQ_ENABLE
-
-
-void observer_SetEvent(Observer *observer, void (*event)(int event_id, void *param))
-{
- observer->event = event;
-}
-
-void observer_InitSubject(Subject *subject)
-{
- LIST_INIT(&subject->observers);
-}
-
-void observer_Subscribe(Subject *subject, Observer *observer)
-{
- ATOMIC(ADDHEAD(&subject->observers, &observer->link));
-}
-
-void observer_Unsubscribe(UNUSED_ARG(Subject *,subject), Observer *observer)
-{
- ATOMIC(REMOVE(&observer->link));
-}
-
-void observer_notify(Subject *subject, int event_id, void *param)
-{
- Observer *observer;
- cpuflags_t irqstate;
- IRQ_SAVE_DISABLE(irqstate);
-
- /*
- * Run over list with protection against other
- * threads, but re-enable irqs in callbacks.
- */
- FOREACH_NODE(observer, &subject->observers)
- {
- IRQ_RESTORE(irqstate);
- observer->event(event_id, param);
- IRQ_SAVE_DISABLE(irqstate);
- }
-
- IRQ_RESTORE(irqstate);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Simple notifier for the subject/observer pattern (interface)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-#ifndef MWARE_OBSERVER_H
-#define MWARE_OBSERVER_H
-
-#include <mware/list.h>
-
-/**
- *
- * Here's a simple example:
- *
- * \code
- * Subject kbd_driver;
- *
- * Observer kbd_observer;
- *
- * void key_pressed(int event, void *_param)
- * {
- * char *param = (char *)_param;
- *
- * if (event == EVENT_KBD_PRESSED)
- * printf("You pressed %c\n", *param);
- * }
- *
- * void register_kbd_listener(void)
- * {
- * observer_SetEvent(&kbd_observer, key_pressed);
- * observer_Subscribe(&kbd_driver, &kbd_observer);
- * }
- * \endcode
- */
-typedef struct Observer
-{
- Node link;
- void (*event)(int event_id, void *param);
-} Observer;
-
-typedef struct Subject
-{
- /// Subscribed observers.
- List observers;
-
-} Subject;
-
-void observer_SetEvent(Observer *observer, void (*event)(int event_id, void *param));
-
-#define OBSERVER_INITIALIZER(callback) { { NULL, NULL }, callback }
-
-void observer_InitSubject(Subject *subject);
-
-/// Aggiunge un Observer all'insieme
-void observer_Subscribe(Subject *subject, Observer *observer);
-
-/// Rimuove un Observer dall'insieme
-void observer_Unsubscribe(Subject *subject, Observer *observer);
-
-/// per tutti gli elementi nel set notifica l'evento, chiamando la relativa
-/// funzione event
-void observer_notify(Subject *subject, int event_id, void *param);
-
-#endif /* MWARE_OBSERVER_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2006 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- *
- * \brief Serial protocol parser and commands.
- *
- * This file contains the serial protocol parser and
- * the definition of the protocol commands. Commands are defined
- * in a "CmdTemplate" type array, containing:
- * - the name of the command,
- * - the arguments it expects to receive,
- * - the output values,
- * - the name of the function implementing the command.
- *
- * The arguments and results are passed to command function
- * using an union: the element of the union to use for each
- * argument is determined by format strings present in the
- * CmdTemplate table.
- */
-
-
-#include "parser.h"
-#include <drv/ser.h>
-
-#include <stdlib.h> // atol(), NULL
-#include <string.h> // strchr(), strcmp()
-
-#include <mware/hashtable.h>
-
-#include "appconfig.h"
-
-#define ARG_SEP_S " "
-#define ARG_SEP_C ' '
-
-#define MAX_COMMANDS_NUMBER 128 // 64
-
-/// Hashtable hook to extract the key from a command
-static const void* get_key_from_command(const void* cmd, uint8_t* length);
-
-/// Hashtable that handles the commands that can be executed
-DECLARE_HASHTABLE_STATIC(commands, MAX_COMMANDS_NUMBER, get_key_from_command);
-
-
-/**
- * \brief Tokenize one word at a time from a text.
- *
- * This function is similar to strtok, but does not use any implicit
- * context, nor it does modify the input buffer in any form.
- * The word is returned as a STL-like [begin,end) range.
- *
- * To extract the first word, make both begin and end point at the
- * start of the text, and call the function. Then, subsequent
- * calls will return the following words (assuming the begin/end
- * variable are not modified between calls).
- *
- * \param begin Will contain the index of the first character of the word
- * \param end Will contain the index of the character after the last
- * character of the word
- *
- * \return True if a word was extracted, false if we got to the end
- * of the string without extracting any word.
- */
-static bool get_word(const char **begin, const char **end)
-{
- const char *cur = *end;
-
- while ((*cur == ' ' || *cur == '\t') && *cur)
- ++cur;
-
- *begin = cur;
-
- while ((*cur != ' ' && *cur != '\t') && *cur)
- ++cur;
-
- *end = cur;
-
- return (*end != *begin);
-}
-
-
-/**
- * \brief Command arguments parser.
- *
- * Using the format pointed by the argument fmt
- * parses the input string filling the array argv
- * with input parameters of the correct type.
- *
- * \param fmt Parameters format string.
- * \param input Input string.
- * \param argv Array filled with parameters.
- *
- * \return False in case of errors, otherwise true.
- */
-static bool parseArgs(const char *fmt, const char *input, parms argv[])
-{
- const char *begin = input, *end = input;
-
- while (*fmt)
- {
- // Extract the argument
- if (!get_word(&begin, &end))
- return false;
-
- switch (*fmt)
- {
- case 'd':
- (*argv++).l = atol(begin);
- break;
-
- case 's':
- (*argv++).s = begin;
- break;
-
- default:
- ASSERT2(0, "Unknown format for argument");
- return false;
- }
-
- ++fmt;
- }
-
- /* check if there are remaining args */
- if (get_word(&begin, &end))
- return false;
-
- return true;
-}
-
-
-#ifdef UNUSED_CODE
-/**
- * \brief Command result formatting and printing.
- *
- * Prints out on device fd the values contained
- * in the array result, using the format specified
- * in fmt.
- *
- * \param ser Serial handle.
- * \param fmt Values format string.
- * \param result Array containing result to be printed.
- *
- * \return -1 in case of errors, otherwise 0.
- */
-static int printResult(struct Serial *ser, const char *fmt, parms result[])
-{
- long n;
- char repeat_cnt = 0;
-
- while (*fmt)
- {
- if (*fmt >= '0' && *fmt <= '9')
- {
- /* Collect repeat count digit (left to right order) */
- repeat_cnt = (repeat_cnt * 10) + (*fmt - '0');
- }
- else
- {
- /* Set default repeat cnt of 1 when not specified */
- if (repeat_cnt == 0)
- repeat_cnt = 1;
-
- /* Loop repeat_cnt times */
- do
- {
- switch (*fmt)
- {
- case 'd':
- ser_printf(ser, ARG_SEP_S "%ld", (*result).l);
- result++;
- break;
- case 'c':
- ser_print(ser, ARG_SEP_S);
- ser_print(ser, (*result).s);
- result++;
- break;
- case 's':
- ser_printf(ser, ARG_SEP_S "%s", (*result).s);
- result++;
- break;
- case 'n':
- n = (*result++).l;
- ser_printf(ser, ARG_SEP_S "%ld", n);
- while (n--) {
- ser_printf(ser, ARG_SEP_S "%ld", (*result).l);
- result++;
- }
- break;
- default:
- break;
- }
- }
- while (--repeat_cnt);
- }
-
- /* Skip to next format char */
- ++fmt;
-
- } /* while (*fmt) */
-
-
- ser_print(ser, "\r\n");
- return 0;
-}
-#endif /* UNUSED_CODE */
-
-/// Hook provided by the parser for matching of command names (TAB completion) for readline
-const char* parser_rl_match(UNUSED_ARG(void *,dummy), const char *word, int word_len)
-{
- HashIterator cur;
- HashIterator end = ht_iter_end(&commands);
- const char *found = NULL;
-
- for (cur = ht_iter_begin(&commands);
- !ht_iter_cmp(cur, end);
- cur = ht_iter_next(cur))
- {
- const struct CmdTemplate* cmdp = (const struct CmdTemplate*)ht_iter_get(cur);
- if (strncmp(cmdp->name, word, word_len) == 0)
- {
- // If there was another matching word, it means that we have a multiple
- // match: then return NULL.
- if (found)
- return NULL;
-
- found = cmdp->name;
- }
- }
-
- return found;
-}
-
-bool parser_get_cmd_id(const char* line, unsigned long* ID)
-{
- const char *begin = line, *end = line;
- char *end2;
-
- // The first word is the ID
- if (!get_word(&begin, &end))
- return false;
-
- *ID = strtoul(begin, &end2, 10);
- if (end2 != end)
- return false;
-
- return true;
-}
-
-const struct CmdTemplate* parser_get_cmd_template(const char *input)
-{
-// const struct CmdTemplate *cmdp;
-// int cmdlen;
- const char *begin = input, *end = input;
-
- // Skip the ID, and get the command
- if (!get_word(&begin, &end))
- return NULL;
- if (!get_word(&begin, &end))
- return NULL;
-
- return (const struct CmdTemplate*)ht_find(&commands, begin, end-begin);
-}
-
-static const char *skip_to_params(const char *input, const struct CmdTemplate *cmdp)
-{
- const char *begin = input, *end = input;
-
- // Skip the ID, and get the command
- if (!get_word(&begin, &end))
- return NULL;
- if (!get_word(&begin, &end))
- return NULL;
-
- ASSERT2(strlen(cmdp->name) == (size_t)(end-begin), "Invalid command template specified");
- ASSERT2(!strncmp(begin, cmdp->name, end-begin), "Invalid command template specified");
-
- return end;
-}
-
-bool parser_get_cmd_arguments(const char* input, const struct CmdTemplate* cmdp, parms args[PARSER_MAX_ARGS])
-{
- input = skip_to_params(input, cmdp);
- if (!input)
- return false;
-
- args[0].s = cmdp->name;
- if (!parseArgs(cmdp->arg_fmt, input, args + 1))
- return false;
-
- return true;
-}
-
-static const void* get_key_from_command(const void* cmd, uint8_t* length)
-{
- const struct CmdTemplate* c = cmd;
- *length = strlen(c->name);
- return c->name;
-}
-
-bool parser_process_line(const char* input)
-{
- const struct CmdTemplate *cmdp;
- parms args[PARSER_MAX_ARGS];
-
- cmdp = parser_get_cmd_template(input);
- if (!cmdp)
- return false;
-
- if (!parser_get_cmd_arguments(input, cmdp, args))
- return false;
-
- if (!parser_execute_cmd(cmdp, args))
- return false;
-
- return true;
-}
-
-void parser_register_cmd(const struct CmdTemplate* cmd)
-{
- ht_insert(&commands, cmd);
-}
-
-#if CONFIG_INTERNAL_COMMANDS
-static ResultCode cmd_help(void)
-{
-#ifdef _DEBUG
-
- // FIXME: There is no way at the moment to access the serial port. Dump
- // this through JTAG for now
- for (HashIterator iter = ht_iter_begin(&commands);
- !ht_iter_cmp(iter, ht_iter_end(&commands));
- iter = ht_iter_next(iter))
- {
- struct CmdTemplate* cmd = (struct CmdTemplate*)ht_iter_get(iter);
- kprintf("%-20s", cmd->name);
- for (unsigned j = 0; cmd->arg_fmt[j]; ++j)
- kprintf("%c ", 'a' + j);
- kprintf("\r\n");
- }
-#endif
-
- return RC_OK;
-}
-
-#include "cmd_hunk.h"
-DECLARE_CMD_HUNK(help, (NIL), (NIL));
-
-#endif // CONFIG_INTERNAL_COMMANDS
-
-
-void parser_init(void)
-{
- // Initialize the hashtable used to store the command description
- ht_init(&commands);
-
-#if CONFIG_INTERNAL_COMMANDS
- parser_register_cmd(&CMD_HUNK_TEMPLATE(help));
-#endif
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2006 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- *
- * \brief serial protocol parser and commands.
- */
-
-
-#ifndef PARSER_H
-#define PARSER_H
-
-#include <drv/ser.h>
-
-/** Max number of arguments and results for each command */
-#define PARSER_MAX_ARGS 8
-
-/**
- * Error generated by the commands through the return code.
- */
-typedef enum
-{
- RC_ERROR = -1, ///< Reply with error.
- RC_OK = 0, ///< No reply (ignore reply arguments).
- RC_REPLY = 1, ///< Reply command arguments.
- RC_SKIP = 2 ///< Skip following commands
-} ResultCode;
-
-/** union that contains parameters passed to and from commands */
-typedef union { long l; const char *s; } parms;
-/** pointer to commands */
-typedef ResultCode (*CmdFuncPtr)(parms args_results[]);
-
-/**
- * Define a command that can be tokenized by the parser.
- *
- * The format strings are sequences of characters, one for each
- * parameter/result. Valid characters are:
- *
- * d - a long integer, in decimal format
- * s - a var string (in RAM)
- *
- * \note To create and fill an instance for this function, it is strongly
- * advised to use \c DECLARE_CMD_HUNK (cmd_hunk.h).
- */
-struct CmdTemplate
-{
- const char *name; ///< Name of command
- const char *arg_fmt; ///< Format string for the input
- const char *result_fmt; ///< Format string for the output
- CmdFuncPtr func; ///< Pointer to the handler function
- uint16_t flags; ///< Currently unused.
-};
-
-/**
- * Initialize the parser module
- *
- * \note This function must be called before any other function in this module
- */
-void parser_init(void);
-
-
-/**
- * Register a new command into the parser
- *
- * \param cmd Command template describing the command
- *
- */
-void parser_register_cmd(const struct CmdTemplate* cmd);
-
-
-/**
- * Hook for readline to provide completion support for the commands
- * registered in the parser.
- *
- * \note This is meant to be used with mware/readline.c. See the
- * documentation there for a description of this hook.
- */
-const char* parser_rl_match(void* dummy, const char* word, int word_len);
-
-
-/**
- * \brief Command input handler.
- *
- * Process the input, calling the requested command
- * (if found) and calling printResult() to give out
- * the result (on device specified with parameter fd).
- *
- * \param line Text line to be processed (ASCIIZ)
- *
- * \return true if everything is OK, false in case of errors
- */
-bool parser_process_line(const char* line);
-
-
-/**
- * Execute a command with its arguments, and fetch its results.
- *
- * \param templ Template of the command to be executed
- * \param args Arguments for the command, and will contain the results
- *
- * \return False if the command returned an error, true otherwise
- */
-INLINE bool parser_execute_cmd(const struct CmdTemplate* templ, parms args[PARSER_MAX_ARGS])
-{
- return (templ->func(args) == 0);
-}
-
-
-/**
- * Find the template for the command contained in the text line.
- * The template can be used to tokenize the command and interpret
- * it.
- *
- * This function can be used to find out which command is contained
- * in a given text line without parsing all the parameters and
- * executing it.
- *
- * \param line Text line to be processed (ASCIIZ)
- *
- * \return The command template associated with the command contained
- * in the line, or NULL if the command is invalid.
- */
-const struct CmdTemplate* parser_get_cmd_template(const char* line);
-
-
-/**
- * Extract the arguments for the command contained in the text line.
- *
- * \param line Text line to be processed (ASCIIZ)
- * \param templ Command template for this line
- * \param args Will contain the extracted parameters
- *
- * \return True if everything OK, false in case of parsing error.
- */
-bool parser_get_cmd_arguments(const char* line, const struct CmdTemplate* templ, parms args[PARSER_MAX_ARGS]);
-
-
-/**
- * Extract the ID from the command text line.
- *
- * \param line Text line to be processed (ASCIIZ)
- * \param ID Will contain the ID extracted.
- *
- * \return True if everything ok, false if there is no ID
- *
- */
-bool parser_get_cmd_id(const char* line, unsigned long* ID);
-
-
-#endif /* PARSER_H */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 ,2006, 2007 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Support for reading program memory on Harvard architectures.
- *
- * Support is currently provided for AVR microcontrollers only.
- *
- * These macros allow building code twice, with and without
- * pgm support (e.g.: strcpy() and strcpy_P()).
- *
- * Set the _PROGMEM predefine to compile in conditional
- * program-memory support.
- *
- *
- * \note This module contains code ripped out from avr-libc,
- * which is distributed under a 3-clause BSD license.
- */
-#ifndef MWARE_PGM_H
-#define MWARE_PGM_H
-
-#include <cfg/compiler.h> /* For intXX_t */
-#include <cpu/detect.h>
-#include <cpu/attr.h> /* For CPU_HARVARD */
-#include <cpu/types.h> /* For SIZEOF_INT */
-
-#if CPU_AVR
-
- #ifdef __AVR_ENHANCED__
- #define pgm_read_char(addr) \
- ({ \
- uint16_t __addr16 = (uint16_t)(addr); \
- uint8_t __result; \
- __asm__ \
- ( \
- "lpm %0, Z" "\n\t" \
- : "=r" (__result) \
- : "z" (__addr16) \
- ); \
- __result; \
- })
- #define pgm_read_uint16_t(addr) \
- ({ \
- uint16_t __addr16 = (uint16_t)(addr); \
- uint16_t __result; \
- __asm__ \
- ( \
- "lpm %A0, Z+" "\n\t" \
- "lpm %B0, Z" "\n\t" \
- : "=r" (__result), "=z" (__addr16) \
- : "1" (__addr16) \
- ); \
- __result; \
- })
-
-
- #else /* !__AVR_ENHANCED__ */
-
- #define pgm_read_char(addr) \
- ({ \
- uint16_t __addr16 = (uint16_t)(addr); \
- uint8_t __result; \
- __asm__ \
- ( \
- "lpm" "\n\t" \
- "mov %0, r0" "\n\t" \
- : "=r" (__result) \
- : "z" (__addr16) \
- : "r0" \
- ); \
- __result; \
- })
- #define pgm_read_uint16_t(addr) \
- ({ \
- uint16_t __addr16 = (uint16_t)(addr); \
- uint16_t __result; \
- __asm__ \
- ( \
- "lpm" "\n\t" \
- "mov %A0, r0" "\n\t" \
- "adiw r30, 1" "\n\t" \
- "lpm" "\n\t" \
- "mov %B0, r0" "\n\t" \
- : "=r" (__result), "=z" (__addr16) \
- : "1" (__addr16) \
- : "r0" \
- ); \
- __result; \
- })
-
- #endif /* !__AVR_ENHANCED__ */
-
- #if SIZEOF_INT == 2
- #define pgm_read_int(addr) ((int)pgm_read_uint16_t(addr))
- #else
- #error Missing support for CPU word size != 16bit
- #endif
-
- #ifndef PROGMEM
- #define PROGMEM __attribute__((__progmem__))
- #endif
- #ifndef PSTR
- #define PSTR(s) ({ static const char __c[] PROGMEM = (s); &__c[0]; })
- #endif
- #ifndef PFUNC
- #define PFUNC(x) x ## _P
- #endif
-
-#elif CPU_HARVARD
- #error Missing CPU support
-#endif
-
-#ifndef PSTR
-#define PSTR /* nothing */
-#endif
-
-#ifndef PFUNC
-#define PFUNC(x) x
-#endif
-
-#ifndef PROGMEM
-#define PROGMEM /* nothing */
-#endif
-
-/**
- * \name Types for variables stored in program memory (harvard processors).
- * \{
- */
-typedef PROGMEM char pgm_char;
-typedef PROGMEM int8_t pgm_int8_t;
-typedef PROGMEM uint8_t pgm_uint8_t;
-typedef PROGMEM int16_t pgm_int16_t;
-typedef PROGMEM uint16_t pgm_uint16_t;
-typedef PROGMEM int32_t pgm_int32_t;
-typedef PROGMEM uint32_t pgm_uint32_t;
-/*\}*/
-
-/**
- * \name PGM support macros.
- *
- * These macros enable dual compilation of code for both program
- * and data memory.
- *
- * Such a function may be defined like this:
- *
- * \code
- * void PGM_FUNC(lcd_puts)(PGM_ATTR const char *str)
- * {
- * char c;
- * while ((c = PGM_READ_CHAR(str++))
- * lcd_putchar(c);
- * }
- * \endcode
- *
- * The above code can be compiled twice: once with the _PROGMEM preprocessor
- * symbol defined, and once without. The two object modules can then be
- * linked in the same application for use by client code:
- *
- * \code
- * lcd_puts("Hello, world!");
- * lcd_puts_P(PSTR("Hello, world!"));
- *
- * // To be used when invoking inside other PGM_FUNC functions:
- * PGM_FUNC(lcd_puts)(some_string);
- * \endcode
- *
- * \{
- */
-#ifdef _PROGMEM
- #define PGM_READ_CHAR(s) pgm_read_char(s)
- #define PGM_FUNC(x) PFUNC(x)
- #define PGM_STR(x) PSTR(x)
- #define PGM_ATTR PROGMEM
-#else
- #define PGM_READ_CHAR(s) (*(s))
- #define PGM_FUNC(x) x
- #define PGM_STR(x) x
- #define PGM_ATTR /* nothing */
-#endif
-/* \} */
-
-
-#endif /* MWARE_PGM_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Pool macros.
- *
- * \version $Id$
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.6 2006/07/19 12:56:28 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.5 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.4 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.3 2004/12/08 08:09:01 bernie
- *#* Add missing header.
- *#*
- *#*/
-#ifndef MWARE_POOL_H
-#define MWARE_POOL_H
-
-#include <cfg/macros.h>
-#include <mware/list.h>
-
-#define EXTERN_POOL(name) \
- extern List name
-
-#define DECLARE_POOL_WITH_STORAGE(name, type, num, storage) \
- static type name##_items[num]; \
- storage name; \
- INLINE void name##_init(void (*init_func)(type*)) \
- { \
- int i; \
- LIST_INIT(&name); \
- for (i=0;i<countof(name##_items);++i) \
- { \
- if (init_func) init_func(&name##_items[i]); \
- ADDTAIL(&name, (Node*)&name##_items[i]); \
- } \
- } \
- INLINE void name##_init(void (*init_func)(type*)) \
- /**/
-
-#define DECLARE_POOL(name, type, num) \
- DECLARE_POOL_WITH_STORAGE(name, type, num, List)
-
-#define DECLARE_POOL_STATIC(name, type, num) \
- DECLARE_POOL_WITH_STORAGE(name, type, num, static List)
-
-#define pool_init(name, init_func) (*(name##_init))(init_func)
-#define pool_alloc(name) REMHEAD(name)
-#define pool_free(name, elem) ADDHEAD(name, (Node*)elem)
-#define pool_empty(name) ISLISTEMPTY(name)
-
-#endif /* MWARE_POOL_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief Very simple rand() algorithm.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/* This would really belong to libc */
-static int rand(void)
-{
- static unsigned long seed;
-
- /* Randomize seed */
- seed = (seed ^ 0x4BAD5A39UL) + 6513973UL;
-
- return (int)(seed>>16);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- * All Rights Reserved.
- * -->
- *
- * \brief Line editing support with history
- *
- * Rationale for basic implementation choices:
- *
- * \li The history is implemented storing consecutive ASCIIZ strings within an array of memory. When
- * the history is full, the first (oldest) line is cancelled and the whole buffer is memmoved to
- * overwrite it and make room. while this is is obviously not the fastest algorithm (which would
- * require the use of a circular buffer) it is surely good enough for this module, which does not
- * aim at fast performances (line editing does not require to be blazingly fast).
- *
- * \li The first character in the history is always \c \\0, and it is used as a guard. By 'wasting' it
- * in this way, the code actually gets much simpler in that we remove many checks when moving
- * backward (\c i>0 and similar).
- *
- * \li While editing, the current index points to the position of the buffer which contains the
- * last character typed in (exactly like a stack pointer). This also allows to simplify calculations
- * and to make easier using the last byte of history.
- *
- * \li While editing, the current line is always kept null-terminated. This is important because
- * if the user press ENTER, we must have room to add a \c \\0 to terminate the line. If the line
- * is as long as the whole history buffer, there would not be space for it. By always keeping the
- * \c \\0 at the end, we properly ensure this without making index checks harder.
- *
- * \li When removing a line from the history (see \c pop_history()), instead of updating all the
- * indices we have around, we move backward the pointer to the history we use. This way, we don't
- * have to update anything. This means that we keep two pointers to the history: \c real_history
- * always points to the physical start, while \c history is the adjusted pointer (that is
- * dereference to read/write to it).
- *
- * \todo Use up/down to move through history The history line will be copied to the current line,
- * making sure there is room for it.
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-
-#include "readline.h"
-
-#include <cfg/compiler.h>
-#include <cfg/debug.h>
-
-#include <stdio.h>
-#include <drv/ser.h>
-
-
-/// Enable compilation of the unit test code
-#define DEBUG_UNIT_TEST 0
-
-/// Enable dump of the history after each line
-#define DEBUG_DUMP_HISTORY 0
-
-
-/** Special keys (escape sequences converted to a single code) */
-enum RL_KEYS {
- SPECIAL_KEYS = 0x1000,
-
- /*
- * Three byte keys:
- * #################
- * UpArrow: 0x1B 0x5B 0X41
- * DownArrow: 0x1B 0x5B 0X42
- * RightArrow: 0x1B 0x5B 0x43
- * LeftArrow: 0x1b 0x5B 0x44
- * Beak(Pause): 0x1b 0x5B 0x50
- */
- KEY_UP_ARROW,
- KEY_DOWN_ARROW,
- KEY_LEFT_ARROW,
- KEY_RIGHT_ARROW,
- KEY_PAUSE,
-
- /*
- * Four byte keys:
- * ################
- * F1: 0x1b 0x5B 0x5B 0x41
- * F2: 0x1b 0x5B 0x5B 0x42
- * F3: 0x1b 0x5B 0x5B 0x43
- * F4: 0x1b 0x5B 0x5B 0x44
- * F5: 0x1b 0x5B 0x5B 0x45
- * Ins: 0x1b 0x5B 0x32 0x7E
- * Home: 0x1b 0x5B 0x31 0x7E
- * PgUp: 0x1b 0x5B 0x35 0x7E
- * Del: 0x1b 0x5B 0x33 0x7E
- * End: 0x1b 0x5B 0x34 0x7E
- * PgDn: 0x1b 0x5B 0x36 0x7E
- */
- KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
- KEY_INS, KEY_HOME, KEY_PGUP, KEY_DEL, KEY_END, KEY_PGDN,
-
- /*
- * Five byte keys:
- * ################
- * F6: 0x1b 0x5B 0x31 0x37 0x7E
- * F7: 0x1b 0x5B 0x31 0x38 0x7E
- * F8: 0x1b 0x5B 0x31 0x39 0x7E
- * F9: 0x1b 0x5B 0x32 0x30 0x7E
- * F10: 0x1b 0x5B 0x32 0x31 0x7E
- * F11: 0x1b 0x5B 0x32 0x33 0x7E
- * F12: 0x1b 0x5B 0x32 0x34 0x7E
- */
- KEY_F6, KEY_F7, KEY_F8, KEY_F9,
- KEY_F10, KEY_F11, KEY_F12,
-};
-
-/** Check if \a c is a separator between words.
- * \note Parameter \a c is evaluated multiple times
- */
-#define IS_WORD_SEPARATOR(c) ((c) == ' ' || (c) == '\0')
-
-/// Write the string \a txt to the IO output (without any kind of termination)
-INLINE void rl_puts(const struct RLContext* ctx, const char* txt)
-{
- if (!ctx->put)
- return;
-
- while (*txt)
- ctx->put(*txt++, ctx->put_param);
-}
-
-/// Write character \a ch to the IO output.
-INLINE void rl_putc(const struct RLContext* ctx, char ch)
-{
- if (ctx->put)
- ctx->put(ch, ctx->put_param);
-}
-
-/** Read a character from the IO into \a ch. This function also takes
- * care of converting the ANSI escape sequences into one of the codes
- * defined in \c RL_KEYS.
- */
-static bool rl_getc(const struct RLContext* ctx, int* ch)
-{
- int c = ctx->get(ctx->get_param);
-
- if (c == EOF)
- {
- if (ctx->clear)
- ctx->clear(ctx->clear_param);
-
- return false;
- }
-
- if (c == 0x1B)
- {
- // Unknown ESC sequence. Ignore it and read
- // return next character.
- if (ctx->get(ctx->get_param) != 0x5B)
- return rl_getc(ctx, ch);
-
- /* To be added:
- * Home: 0x1b 0x5B 0x31 0x7E
- * F6: 0x1b 0x5B 0x31 0x37 0x7E
- * F7: 0x1b 0x5B 0x31 0x38 0x7E
- * F8: 0x1b 0x5B 0x31 0x39 0x7E
- * Ins: 0x1b 0x5B 0x32 0x7E
- * F9: 0x1b 0x5B 0x32 0x30 0x7E
- * F10: 0x1b 0x5B 0x32 0x31 0x7E
- * F11: 0x1b 0x5B 0x32 0x33 0x7E
- * F12: 0x1b 0x5B 0x32 0x34 0x7E
- * Del: 0x1b 0x5B 0x33 0x7E
- * End: 0x1b 0x5B 0x34 0x7E
- * PgUp: 0x1b 0x5B 0x35 0x7E
- * PgDn: 0x1b 0x5B 0x36 0x7E
- */
-
- c = ctx->get(ctx->get_param);
- switch (c)
- {
- case 0x41: c = KEY_UP_ARROW; break;
- case 0x42: c = KEY_DOWN_ARROW; break;
- case 0x43: c = KEY_RIGHT_ARROW; break;
- case 0x44: c = KEY_LEFT_ARROW; break;
- case 0x50: c = KEY_PAUSE; break;
- case 0x5B:
- c = ctx->get(ctx->get_param);
- switch (c)
- {
- case 0x41: c = KEY_F1; break;
- case 0x42: c = KEY_F2; break;
- case 0x43: c = KEY_F3; break;
- case 0x44: c = KEY_F4; break;
- case 0x45: c = KEY_F5; break;
- default: return rl_getc(ctx, ch);
- }
- break;
- default: return rl_getc(ctx, ch);
- }
- }
-
- *ch = c;
- return true;
-}
-
-INLINE void beep(struct RLContext* ctx)
-{
- rl_putc(ctx, '\a');
-}
-
-static bool pop_history(struct RLContext* ctx, int total_len)
-{
- // Compute the length of the first command (including terminator).
- int len = strlen(ctx->real_history+1)+1;
-
- // (the first byte of the history should always be 0)
- ASSERT(ctx->real_history[0] == '\0');
-
- // If it is the only one in the history, do nothing
- if (len == total_len)
- return false;
-
- // Overwrite the first command with the second one
- memmove(ctx->real_history, ctx->real_history+len, HISTORY_SIZE-len);
-
- // Move back the ctx->buffer pointer so that all the indices are still valid
- ctx->history -= len;
-
- return true;
-}
-
-/// Check if index \a i points to the begin of the history.
-INLINE bool is_history_begin(struct RLContext* ctx, int i)
-{ return ctx->history + i == ctx->real_history; }
-
-/// Check if index \a i points to the (exclusive) end of history
-INLINE bool is_history_end(struct RLContext* ctx, int i)
-{ return ctx->history + i == ctx->real_history + HISTORY_SIZE; }
-
-/// Check if index \a i points to the (exclusive) end of history, or somewhere past the end.
-INLINE bool is_history_past_end(struct RLContext* ctx, int i)
-{ return ctx->history + i >= ctx->real_history + HISTORY_SIZE; }
-
-/** Insert \a num_chars characters from \a ch into the history buffer at the
- * position indicated by \a curpos. If needed, remove old history to make room.
- * Returns true if everything was successful, false if there was no room to
- * add the characters.
- * \note \a num_chars can be 0, in which case we just make sure the line is
- * correctly zero-terminated (ASCIIZ format).
- */
-static bool insert_chars(struct RLContext* ctx, size_t *curpos, const char* ch, int num_chars)
-{
- ASSERT(!is_history_past_end(ctx, *curpos));
-
- while (is_history_past_end(ctx, *curpos+num_chars+1))
- {
- if (!pop_history(ctx, *curpos))
- return false;
- }
-
- while (num_chars--)
- ctx->history[++(*curpos)] = *ch++;
-
- ASSERT(!is_history_past_end(ctx, *curpos + 1));
- ctx->history[*curpos+1] = '\0';
- return true;
-}
-
-/// Insert a single character \a ch into the buffer (with the same semantic of \c insert_chars())
-static bool insert_char(struct RLContext* ctx, size_t *curpos, char ch)
-{
- return insert_chars(ctx, curpos, &ch, 1);
-}
-
-#if DEBUG_DUMP_HISTORY
-/// Dump the internal history of a context (used only for debug purposes)
-static void dump_history(struct RLContext* ctx)
-{
- int k;
- char buf[8];
- ASSERT(ctx->real_history[0] == '\0');
- rl_puts(ctx, "History dump:");
- rl_puts(ctx, "\r\n");
- for (k = 1;
- ctx->real_history + k != ctx->history + ctx->history_pos + 1;
- k += strlen(&ctx->real_history[k]) + 1)
- {
- rl_puts(ctx, &ctx->real_history[k]);
- rl_puts(ctx, "\r\n");
- }
-
- sprintf(buf, "%d\r\n", ctx->history_pos + (ctx->history - ctx->real_history));
- rl_puts(ctx, buf);
-}
-#endif /* DEBUG_DUMP_HISTORY */
-
-/// Complete the current word. Return false if no unambiguous completion was found
-static bool complete_word(struct RLContext *ctx, size_t *curpos)
-{
- const char* completed_word;
- size_t wstart;
-
- // If the current character is a separator,
- // there is nothing to complete
- wstart = *curpos;
- if (IS_WORD_SEPARATOR(ctx->history[wstart]))
- {
- beep(ctx);
- return false;
- }
-
- // Find the separator before the current word
- do
- --wstart;
- while (!IS_WORD_SEPARATOR(ctx->history[wstart]));
-
- // Complete the word through the hook
- completed_word = ctx->match(ctx->match_param, ctx->history + wstart + 1, *curpos - wstart);
- if (!completed_word)
- return false;
-
- // Move back the terminal cursor to the separator
- while (*curpos != wstart)
- {
- rl_putc(ctx, '\b');
- --*curpos;
- }
-
- // Insert the completed command
- insert_chars(ctx, curpos, completed_word, strlen(completed_word));
- rl_puts(ctx, completed_word);
- insert_char(ctx, curpos, ' ');
- rl_putc(ctx, ' ');
-
- return true;
-}
-
-void rl_refresh(struct RLContext* ctx)
-{
- rl_puts(ctx, "\r\n");
- if (ctx->prompt)
- rl_puts(ctx, ctx->prompt);
- rl_puts(ctx, ctx->history + ctx->history_pos + 1);
-}
-
-const char* rl_readline(struct RLContext* ctx)
-{
- size_t i = ctx->history_pos;
-
- if (ctx->prompt)
- rl_puts(ctx, ctx->prompt);
-
- insert_chars(ctx, &i, NULL, 0);
-
- while (1)
- {
- char ch;
- int c;
-
- ASSERT(ctx->history - ctx->real_history + ctx->line_pos < HISTORY_SIZE);
-
- if (!rl_getc(ctx, &c))
- return NULL;
-
- // Just ignore special keys for now
- if (c > SPECIAL_KEYS)
- continue;
-
- if (c == '\t')
- {
- // Ask the match hook if available
- if (!ctx->match)
- return false;
-
- complete_word(ctx, &ctx->line_pos);
- continue;
- }
-
- if (c == '\r' || c == '\n')
- {
- if (ctx->prompt)
- rl_puts(ctx, ctx->prompt);
-
- // Terminate line
- insert_chars(ctx, &ctx->line_pos, NULL, 0);
- rl_puts(ctx, "\r\n");
- break;
- }
-
- // Backspace cancels a character, or it is ignored if at
- // the start of the line
- if (c == '\b')
- {
- if (ctx->history[ctx->line_pos] != '\0')
- {
- --ctx->line_pos;
- rl_puts(ctx, "\b \b");
- }
- continue;
- }
-
- // Add a character to the buffer, if possible
- ch = (char)c;
- ASSERT2(ch == c, "a special key was not properly handled");
- if (insert_chars(ctx, &ctx->line_pos, &ch, 1))
- {
- rl_putc(ctx, ch);
- }
- else
- {
- beep(ctx);
- }
- }
-
- ctx->history_pos = ctx->line_pos + 1;
- while (ctx->history[ctx->line_pos] != '\0')
- --ctx->line_pos;
-
- // Do not store empty lines in the history
- if (ctx->line_pos == ctx->history_pos - 1)
- ctx->history_pos -= 1;
-
-#if DEBUG_DUMP_HISTORY
- dump_history(ctx);
-#endif
-
- // Since the current pointer now points to the separator, we need
- // to return the first character
- return &ctx->history[ctx->line_pos + 1];
-}
-
-
-#if DEBUG_UNIT_TEST
-
-/** Perform the unit test for the readline library */
-void rl_test(void);
-
-#if HISTORY_SIZE != 32
- #error This test needs HISTORY_SIZE to be set at 32
-#endif
-
-static struct RLContext test_ctx;
-
-static char* test_getc_ptr;
-static int test_getc(void* data)
-{
- return *test_getc_ptr++;
-}
-
-/** Perform a readline test. The function pipes the characters from \a input_buffer
- * through the I/O to \c rl_readline(). After the whole string is sent, \c do_test()
- * checks if the current history within the context match \a expected_history.
- */
-static bool do_test(char* input_buffer, char* expected_history)
-{
- rl_init_ctx(&test_ctx);
- rl_sethook_get(&test_ctx, test_getc, NULL);
-
- test_getc_ptr = input_buffer;
- while (*test_getc_ptr)
- rl_readline(&test_ctx);
-
- if (memcmp(test_ctx.real_history, expected_history, HISTORY_SIZE) != 0)
- {
- ASSERT2(0, "history compare failed");
- return false;
- }
-
- return true;
-}
-
-void rl_test(void)
-{
- char* test1_in = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n";
- char test1_hist[HISTORY_SIZE] = "\0l\0m\0n\0o\0p\0q\0r\0s\0t\0u\0v\0w\0x\0y\0z";
-
- if (!do_test(test1_in, test1_hist))
- return;
-
- kprintf("rl_test successful\n");
-}
-
-#endif /* DEBUG_UNIT_TEST */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright (C) 2004 Giovanni Bajo
- * Copyright (C) 2004 Develer S.r.l. (http://www.develer.com/)
- * All Rights Reserved.
- * -->
- *
- * \brief Line editing support with history
- *
- * This file implements a kernel for line editing through a terminal, with history of the typed lines.
- * Basic feature of this module:
- *
- * \li Abstracted from I/O. The user must provide hooks for getc and putc functions.
- * \li Basic support for ANSI escape sequences for input of special codes.
- * \li Support for command name completion (through a hook).
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-
-#ifndef MWARE_READLINE_H
-#define MWARE_READLINE_H
-
-#include <cfg/compiler.h>
-
-#include <string.h>
-
-#define HISTORY_SIZE 1024
-
-typedef int (*getc_hook)(void* user_data);
-typedef void (*putc_hook)(char ch, void* user_data);
-typedef const char* (*match_hook)(void* user_data, const char* word, int word_len);
-typedef void (*clear_hook)(void* user_data);
-
-struct RLContext
-{
- getc_hook get;
- void* get_param;
-
- putc_hook put;
- void* put_param;
-
- match_hook match;
- void* match_param;
-
- clear_hook clear;
- void* clear_param;
-
- const char* prompt;
-
- char real_history[HISTORY_SIZE];
- char* history;
- size_t history_pos;
- size_t line_pos;
-};
-
-INLINE void rl_init_ctx(struct RLContext *ctx)
-{
- memset(ctx, 0, sizeof(*ctx));
- ctx->history = ctx->real_history;
-}
-
-INLINE void rl_clear_history(struct RLContext *ctx)
-{
- memset(ctx->real_history, 0, sizeof(ctx->real_history));
- ctx->history_pos = 0;
- ctx->history = ctx->real_history;
-}
-
-INLINE void rl_sethook_get(struct RLContext* ctx, getc_hook get, void* get_param)
-{ ctx->get = get; ctx->get_param = get_param; }
-
-INLINE void rl_sethook_put(struct RLContext* ctx, putc_hook put, void* put_param)
-{ ctx->put = put; ctx->put_param = put_param; }
-
-INLINE void rl_sethook_match(struct RLContext* ctx, match_hook match, void* match_param)
-{ ctx->match = match; ctx->match_param = match_param; }
-
-INLINE void rl_sethook_clear(struct RLContext* ctx, clear_hook clear, void* clear_param)
-{ ctx->clear = clear; ctx->clear_param = clear_param; }
-
-INLINE void rl_setprompt(struct RLContext* ctx, const char* prompt)
-{ ctx->prompt = prompt; }
-
-const char* rl_readline(struct RLContext* ctx);
-
-void rl_refresh(struct RLContext* ctx);
-
-#endif /* MWARE_READLINE_H */
+++ /dev/null
-
-#include "resource.h"
-#include <mware/observer.h>
-
-/**
- * Internal structure for building a priority queue
- * of processes waiting for the resource to become free.
- */
-typedef struct ResourceWaiter
-{
- PriNode link;
- struct Observer *owner;
-
-} ResourceWaiter;
-
-
-bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest)
-{
- bool success = false;
-
- ASSERT(releaseRequest);
-
- sem_obtain(&res->lock);
-
- if (res->owner == releaseRequest)
- {
- // Already ours
- res->pri = pri;
- success = true;
- }
- else if (!res->owner)
- {
- // Trivial acquire: nobody was owning the resource
- res->pri = pri;
- res->owner = releaseRequest;
- success = true;
- }
- else
- {
- ResourceWaiter waiter;
-
- // Setup waiter structure and enqueue it to resource
- waiter.owner = releaseRequest;
- waiter.link.pri = pri;
- LIST_ENQUEUE(&res->queue, &waiter.link);
-
- // Resource busy: are we eligible for preemption?
- if ((res->pri < pri) && res->owner->event)
- res->owner->event(EVENT_RELEASE, res);
-
- // Wait in the queue until the timeout occurs.
- do
- {
- sem_release(&res->lock);
- // TODO: use a semaphore here instead
- ResMan_sleep();
- sem_obtain(&res->lock);
-
- // Check for ownership
- if (res->owner == releaseRequest)
- {
- success = true;
- break;
- }
- }
- while (timeout--);
-
- // Remove pending waiter
- if (!success)
- REMOVE(&waiter.link.link);
- }
-
- sem_release(&res->lock);
- return success;
-}
-
-void ResMan_Free(Resource *res)
-{
- ResourceWaiter *waiter;
-
- sem_obtain(&res->lock);
-
-
- ASSERT(res->owner);
- //TODO: check for real owner calling free
-
- // Check for new owner candidates.
- if ((waiter = (ResourceWaiter *)list_remHead(&res->queue)))
- {
- // Transfer ownership of the resource
- res->owner = waiter->owner;
- res->pri = waiter->link.pri;
- //ResMan_wakeup(waiter);
- }
- else
- {
- // Nobody waiting, free the resource
- res->owner = NULL;
- res->pri = -1;
- }
-
- sem_release(&res->lock);
-}
-
-void ResMan_Init(Resource *res)
-{
- res->owner = NULL;
- res->pri = -1;
-
- sem_init(&res->lock);
- LIST_INIT(&res->queue);
-}
-
+++ /dev/null
-#ifndef MWARE_RESOURCE_H
-#define MWARE_RESOURCE_H
-
-#include <drv/timer.h> // time_t
-#include <kern/sem.h>
-
-/*
- * Abstract locking primitives used by host OS.
- */
-#if CONFIG_KERNEL
-
- typedef Semaphore ResourceLock;
- #define ResMan_sleep() timer_delay(1)
- #define ResMan_time_t mtime_t
-
-#else /* FreeRTOS */
-
- #include <freertos.h>
- #include <semphr.h>
- #include <task.h> // vTaskDelay()
-
- #define ResMan_sleep() vTaskDelay((portTickType)1 * portTICK_RATE_MS)
- #define ResMan_time_t portTickType
-#endif
-
-
-// Forward decl
-struct Observer;
-
-/**
- * Hold context information for a resource such as an audio channel.
- *
- * Each driver registers one or more Resource instances with the
- * ResMan using ResMan_Register().
- *
- * Clients can then allocate the resource through ResMan_Alloc()
- * providing a desired priority and an Observer for asynchronous
- * notification.
- *
- * Allocated resources can be stolen by other clients asking for a
- * higher priority. ResMan notifies a preemption request by invoking
- * the Observer of the current owner.
- *
- * The Observer callback must take whatever action is needed to
- * release the resource as soon as possible to avoid blocking the
- * new owner.
- */
-typedef struct Resource
-{
-//Private
- /// Control access to fields below.
- Semaphore lock;
-
- /// Pointer to current owner's observer. NULL if resource is free.
- struct Observer *owner;
-
- /// Priority of current owner (higher values mean higher priority).
- int pri;
-
- /// Queue of processes waiting to obtain the resource.
- List queue;
-} Resource;
-
-/// Event sent by ResMan to owners when to request resource release.
-enum { EVENT_RELEASE = 1 };
-
-/// Try to allocate a resource \a res with priority \a pri for at most \a timeout ticks.
-bool ResMan_Alloc(Resource *res, int pri, ResMan_time_t timeout, struct Observer *releaseRequest);
-
-/// Free resource \a res. Will eventually wake-up other queued owners.
-void ResMan_Free(Resource *res);
-
-void ResMan_Init(Resource *res);
-
-#endif /* MWARE_RESOURCE_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief General-purpose run-length {en,de}coding algorithm (implementation)
- *
- * Original source code from http://www.compuphase.com/compress.htm
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/07/19 12:56:28 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.3 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.2 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.1 2004/08/04 02:35:54 bernie
- *#* Import simple RLE algorithm.
- *#*
- *#*/
-
-#include "rle.h"
-
-
-/**
- * Run-length encode \a len bytes from the \a input buffer
- * to the \a output buffer.
- */
-int rle(unsigned char *output, const unsigned char *input, int len)
-{
- int count, index, i;
- unsigned char first;
- unsigned char *out;
-
-
- out = output;
- count = 0;
- while (count < len)
- {
- index = count;
- first = input[index++];
-
- /* Scan for bytes identical to the first one */
- while ((index < len) && (index - count < 127) && (input[index] == first))
- index++;
-
- if (index - count == 1)
- {
- /* Failed to "replicate" the current byte. See how many to copy.
- */
- while ((index < len) && (index - count < 127))
- {
- /* Avoid a replicate run of only 2-bytes after a literal run.
- * There is no gain in this, and there is a risc of loss if the
- * run after the two identical bytes is another literal run.
- * So search for 3 identical bytes.
- */
- if ((input[index] == input[index - 1]) &&
- ((index > 1) && (input[index] == input[index - 2])))
- {
- /* Reset the index so we can back up these three identical
- * bytes in the next run.
- */
- index -= 2;
- break;
- }
-
- index++;
- }
-
- /* Output a run of uncompressed bytes: write length and values */
- *out++ = (unsigned char)(count - index);
- for (i = count; i < index; i++)
- *out++ = input[i];
- }
- else
- {
- /* Output a compressed run: write length and value */
- *out++ = (unsigned char)(index - count);
- *out++ = first;
- }
-
- count = index;
- }
-
- /* Output EOF marker */
- *out++ = 0;
-
- return (out - output);
-}
-
-
-/**
- * Run-length decode from the \a input buffer to the \a output
- * buffer.
- *
- * \note The output buffer must be large enough to accomodate
- * all decoded output.
- */
-int unrle(unsigned char *output, const unsigned char *input)
-{
- signed char count;
- unsigned char *out;
- unsigned char value;
-
-
- out = output;
-
- for (;;)
- {
- count = (signed char)*input++;
- if (count > 0)
- {
- /* replicate run */
- value = *input++;
- while (count--)
- *out++ = value;
- }
- else if (count < 0)
- {
- /* literal run */
- while (count++)
- *out++ = *input++;
- }
- else
- /* EOF */
- break;
- }
-
- return (out - output);
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- *
- * \brief General-purpose run-length {en,de}coding algorithm (interface)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.4 2006/07/19 12:56:28 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.3 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.2 2004/08/25 14:12:09 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.1 2004/08/04 02:35:54 bernie
- *#* Import simple RLE algorithm.
- *#*
- *#*/
-#ifndef RLE_H
-#define RLE_H
-
-int rle(unsigned char *output, const unsigned char *input, int length);
-int unrle(unsigned char *output, const unsigned char *input);
-
-#endif /* RLE_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2002, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief sprintf() implementation based on _formatted_write()
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include <mware/formatwr.h>
-#include <mware/pgm.h>
-#include <cfg/compiler.h>
-
-#include <stdio.h>
-
-
-static void __str_put_char(char c, void *ptr)
-{
- /*
- * This Does not work on Code Warrior. Hmm...
- * *(*((char **)ptr))++ = c;
- */
-
- **((char **)ptr) = c;
- (*((char **)ptr))++;
-}
-
-static void __null_put_char(UNUSED_ARG(char, c), UNUSED_ARG(void *, ptr))
-{
- /* nop */
-}
-
-
-int PGM_FUNC(vsprintf)(char *str, const char * PGM_ATTR fmt, va_list ap)
-{
- int result;
-
- if (str)
- {
- result = PGM_FUNC(_formatted_write)(fmt, __str_put_char, &str, ap);
-
- /* Terminate string */
- *str = '\0';
- }
- else
- result = PGM_FUNC(_formatted_write)(fmt, __null_put_char, 0, ap);
-
-
- return result;
-}
-
-
-int PGM_FUNC(sprintf)(char *str, const char * fmt, ...)
-{
- int result;
- va_list ap;
-
- va_start(ap, fmt);
- result = PGM_FUNC(vsprintf)(str, fmt, ap);
- va_end(ap);
-
- return result;
-}
-
-/**
- * State information for __sn_put_char()
- */
-struct __sn_state
-{
- char *str;
- size_t len;
-};
-
-/**
- * formatted_write() callback used [v]snprintf().
- */
-static void __sn_put_char(char c, void *ptr)
-{
- struct __sn_state *state = (struct __sn_state *)ptr;
-
- if (state->len)
- {
- --state->len;
- *state->str++ = c;
- }
-}
-
-
-int PGM_FUNC(vsnprintf)(char *str, size_t size, const char * PGM_ATTR fmt, va_list ap)
-{
- int result = 0;
-
- /* Make room for traling '\0'. */
- if (size--)
- {
- if (str)
- {
- struct __sn_state state;
- state.str = str;
- state.len = size;
-
- result = PGM_FUNC(_formatted_write)(fmt, __sn_put_char, &state, ap);
-
- /* Terminate string. */
- *state.str = '\0';
- }
- else
- result = PGM_FUNC(_formatted_write)(fmt, __null_put_char, 0, ap);
- }
-
- return result;
-}
-
-
-int PGM_FUNC(snprintf)(char *str, size_t size, const char * fmt, ...)
-{
- int result;
- va_list ap;
-
- va_start(ap, fmt);
- result = PGM_FUNC(vsnprintf)(str, size, fmt, ap);
- va_end(ap);
-
- return result;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief sprintf() implementation based on _formatted_write()
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "sprintf.c"
-#include "formatwr.c"
-#include "hex.c"
-#include <cfg/compiler.h>
-#include <mware/pgm.h>
-#include <stdio.h>
-
-#include <assert.h> /* assert() */
-#include <string.h> /* strcmp() */
-
-
-int main(UNUSED_ARG(int, argc), UNUSED_ARG(char **,argv))
-{
- char buf[256];
- static const char test_string[] = "Hello, world!\n";
- static const pgm_char test_string_pgm[] = "Hello, world!\n";
-
- snprintf(buf, sizeof buf, "%s", test_string);
- assert(strcmp(buf, test_string) == 0);
-
- snprintf(buf, sizeof buf, "%S", test_string_pgm);
- assert(strcmp(buf, test_string_pgm) == 0);
-
-#define TEST(FMT, VALUE, EXPECT) do { \
- snprintf(buf, sizeof buf, FMT, VALUE); \
- assert(strcmp(buf, EXPECT) == 0); \
- } while (0)
-
- TEST("%d", 12345, "12345");
- TEST("%ld", 123456789L, "123456789");
- TEST("%ld", -12345678L, "-12345678");
- TEST("%lu", 4294967295UL, "4294967295");
- TEST("%hd", -12345, "-12345");
- TEST("%hu", 65535U, "65535");
-
- TEST("%8d", 123, " 123");
- TEST("%8d", -123, " -123");
- TEST("%-8d", -123, "-123 ");
- TEST("%08d", -123, "-0000123");
-
- TEST("%8.2f", -123.456, " -123.46");
- TEST("%-8.2f", -123.456, "-123.46 ");
- TEST("%8.0f", -123.456, " -123");
-
-#undef TEST
-
- /*
- * Stress tests.
- */
- snprintf(buf, sizeof buf, "%s", NULL);
- assert(strcmp(buf, "<NULL>") == 0);
- snprintf(buf, sizeof buf, "%k");
- assert(strcmp(buf, "???") == 0);
- sprintf(NULL, test_string); /* must not crash */
-
- return 0;
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Poor man's hex arrays (implementation).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "strtol10.h"
-
-/**
- * Convert a formatted base-10 ASCII number to unsigned long binary representation.
- *
- * Unlike the standard strtoul(), this function has an interface
- * that makes it better suited for protocol parsers. It's also
- * much simpler and smaller than a full featured strtoul().
- *
- * \param first Pointer to first byte of input range (STL-style).
- * \param last Pointer to end of input range (STL-style).
- * Pass NULL to parse up to the first \\0.
- * \param val Pointer to converted value.
- *
- * \return true for success, false for failure.
- *
- * \see strtol10()
- */
-bool strtoul10(const char *first, const char *last, unsigned long *val)
-{
- // Check for no input
- if (*first == '\0')
- return false;
-
- *val = 0;
- for(/*nop*/; first != last && *first != '\0'; ++first)
- {
- if ((*first < '0') || (*first > '9'))
- return false;
-
- *val = (*val * 10L) + (*first - '0');
- }
-
- return true;
-}
-
-
-/**
- * Convert a formatted base-10 ASCII number to signed long binary representation.
- *
- * \see strtoul10()
- */
-bool strtol10(const char *first, const char *last, long *val)
-{
- bool negative = false;
-
- if (*first == '+')
- ++first; /* skip unary plus sign */
- else if (*first == '-')
- {
- negative = true;
- ++first;
- }
-
- bool result = strtoul10(first, last, (unsigned long *)val);
-
- if (negative)
- *val = - *val;
-
- return result;
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Poor man's hex arrays (implementation).
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-
-#ifndef MWARE_STRTOL10_H
-#define MWARE_STRTOL10_H
-
-#include <cfg/compiler.h> /* bool */
-
-bool strtoul10(const char *first, const char *last, unsigned long *val);
-bool strtol10(const char *first, const char *last, long *val);
-
-/**
- * Replacement for standard library function atol().
- */
-INLINE long atol(const char *str)
-{
- long val;
- strtol10(str, NULL, &val);
- return val;
-}
-
-/**
- * Replacement for standard library function atoi().
- */
-INLINE int atoi(const char *str)
-{
- return (int)atol(str);
-}
-
-#endif /* MWARE_STRTOL10_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- * \brief X-Modem serial transmission protocol (implementation)
- *
- * Supports the CRC-16 and 1K-blocks variants of the standard.
- * \see ymodem.txt for the protocol description.
- *
- * \todo Break xmodem_send() and xmodem_recv() in smaller functions.
- *
- * \todo Maybe convert drv/ser.c to the KFile interface for symmetry and
- * flexibility.
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-
-#include "xmodem.h"
-
-#include <appconfig.h>
-#include <string.h> /* for memset() */
-#include <drv/ser.h>
-#include <algo/crc.h>
-#include <cfg/debug.h>
-
-
-
-
-/**
- * \name Protocol control codes
- * \{
- */
-#define XM_SOH 0x01 /**< Start Of Header (128-byte block) */
-#define XM_STX 0x02 /**< Start Of Header (1024-byte block) */
-#define XM_EOT 0x04 /**< End Of Transmission */
-#define XM_ACK 0x06 /**< Acknowledge block */
-#define XM_NAK 0x15 /**< Negative Acknowledge */
-#define XM_C 0x43 /**< Request CRC-16 transmission */
-#define XM_CAN 0x18 /**< CANcel transmission */
-/*\}*/
-
-#define XM_MAXRETRIES 15 /**< Max retries before giving up */
-#define XM_MAXCRCRETRIES 7 /**< Max retries before switching to BCC */
-
-#if CONFIG_XMODEM_1KCRC == 1
- #define XM_BUFSIZE 1024 /**< 1024 bytes of block buffer */
-#else
- #define XM_BUFSIZE 128 /**< 128 bytes of block buffer */
-#endif
-
-
-#if CONFIG_XMODEM_RECV
-/**
- * \brief Receive a file using the XModem protocol.
- *
- * \param port Serial port to use for transfer
- * \param fd Destination file
- *
- * \note This function allocates a large amount of stack (\see XM_BUFSIZE).
- */
-bool xmodem_recv(struct Serial *port, KFile *fd)
-{
- char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
- int c, i, blocksize;
- int blocknr = 0, last_block_done = 0, retries = 0;
- char *buf;
- uint8_t checksum;
- uint16_t crc;
- bool purge = false;
- bool usecrc = true;
-
-
- XMODEM_PROGRESS("Starting Transfer...\n");
- purge = true;
- ser_setstatus(port, 0);
-
- /* Send initial NAK to start transmission */
- for(;;)
- {
- if (XMODEM_CHECK_ABORT)
- {
- ser_putchar(XM_CAN, port);
- ser_putchar(XM_CAN, port);
- XMODEM_PROGRESS("Transfer aborted\n");
- return false;
- }
-
- /*
- * Discard incoming input until a timeout occurs, then send
- * a NAK to the transmitter.
- */
- if (purge)
- {
- purge = false;
-
- if (ser_getstatus(port))
- XMODEM_PROGRESS("Retries %d\n", retries);
-
- ser_resync(port, 200);
- retries++;
-
- if (retries >= XM_MAXRETRIES)
- {
- ser_putchar(XM_CAN, port);
- ser_putchar(XM_CAN, port);
- XMODEM_PROGRESS("Transfer aborted\n");
- return false;
- }
-
- /* Transmission start? */
- if (blocknr == 0)
- {
- if (retries < XM_MAXCRCRETRIES)
- {
- XMODEM_PROGRESS("Request Tx (CRC)\n");
- ser_putchar(XM_C, port);
- }
- else
- {
- /* Give up with CRC and fall back to checksum */
- usecrc = false;
- XMODEM_PROGRESS("Request Tx (BCC)\n");
- ser_putchar(XM_NAK, port);
- }
- }
- else
- ser_putchar(XM_NAK, port);
- }
-
- switch (ser_getchar(port))
- {
- #if XM_BUFSIZE >= 1024
- case XM_STX: /* Start of header (1024-byte block) */
- blocksize = 1024;
- goto getblock;
- #endif
-
- case XM_SOH: /* Start of header (128-byte block) */
- blocksize = 128;
- /* Needed to avoid warning if XM_BUFSIZE < 1024 */
- goto getblock;
- getblock:
- /* Get block number */
- c = ser_getchar(port);
-
- /* Check complemented block number */
- if ((~c & 0xff) != ser_getchar(port))
- {
- XMODEM_PROGRESS("Bad blk (%d)\n", c);
- purge = true;
- break;
- }
-
- /* Determine which block is being sent */
- if (c == (blocknr & 0xff))
- /* Last block repeated */
- XMODEM_PROGRESS("Repeat blk %d\n", blocknr);
- else if (c == ((blocknr + 1) & 0xff))
- /* Next block */
- XMODEM_PROGRESS("Recv blk %d\n", ++blocknr);
- else
- {
- /* Sync lost */
- XMODEM_PROGRESS("Sync lost (%d/%d)\n", c, blocknr);
- purge = true;
- break;
- }
-
- buf = block_buffer; /* Reset pointer to start of buffer */
- checksum = 0;
- crc = 0;
- for (i = 0; i < blocksize; i++)
- {
- if ((c = ser_getchar(port)) == EOF)
- {
- purge = true;
- break;
- }
-
- /* Store in buffer */
- *buf++ = (char)c;
-
- /* Calculate block checksum or CRC */
- if (usecrc)
- crc = UPDCRC16(c, crc);
- else
- checksum += (char)c;
- }
-
- if (purge)
- break;
-
- /* Get the checksum byte or the CRC-16 MSB */
- if ((c = ser_getchar(port)) == EOF)
- {
- purge = true;
- break;
- }
-
- if (usecrc)
- {
- crc = UPDCRC16(c, crc);
-
- /* Get CRC-16 LSB */
- if ((c = ser_getchar(port)) == EOF)
- {
- purge = true;
- break;
- }
-
- crc = UPDCRC16(c, crc);
-
- if (crc)
- {
- XMODEM_PROGRESS("Bad CRC: %04x\n", crc);
- purge = true;
- break;
- }
- }
- /* Compare the checksum */
- else if (c != checksum)
- {
- XMODEM_PROGRESS("Bad sum: %04x/%04x\n", checksum, c);
- purge = true;
- break;
- }
-
- /*
- * Avoid flushing the same block twice.
- * This could happen when the sender does not receive our
- * acknowledge and resends the same block.
- */
- if (last_block_done < blocknr)
- {
- /* Call user function to flush the buffer */
- if (fd->write(fd, block_buffer, blocksize))
- {
- /* Acknowledge block and clear error counter */
- ser_putchar(XM_ACK, port);
- retries = 0;
- last_block_done = blocknr;
- }
- else
- {
- /* User callback failed: abort transfer immediately */
- retries = XM_MAXRETRIES;
- purge = true;
- }
- }
- break;
-
- case XM_EOT: /* End of transmission */
- ser_putchar(XM_ACK, port);
- XMODEM_PROGRESS("Transfer completed\n");
- return true;
-
- case EOF: /* Timeout or serial error */
- purge = true;
- break;
-
- default:
- XMODEM_PROGRESS("Skipping garbage\n");
- purge = true;
- break;
- }
- } /* End forever */
-}
-#endif
-
-
-#if CONFIG_XMODEM_SEND
-/**
- * \brief Transmit some data using the XModem protocol.
- *
- * \param port Serial port to use for transfer
- * \param fd Source file
- *
- * \note This function allocates a large amount of stack for
- * the XModem transfer buffer (\see XM_BUFSIZE).
- */
-bool xmodem_send(struct Serial *port, KFile *fd)
-{
- char block_buffer[XM_BUFSIZE]; /* Buffer to hold a block of data */
- size_t size = -1;
- int blocknr = 1, retries = 0, c, i;
- bool proceed, usecrc = false;
- uint16_t crc;
- uint8_t sum;
-
- /*
- * Reading a block can be very slow, so we read the first block early
- * to avoid receiving double XM_C char.
- * This could happen if we check for XM_C and then read the block, giving
- * the receiving device time to send another XM_C char misinterpretating
- * the blocks sent.
- */
- size = fd->read(fd, block_buffer, XM_BUFSIZE);
-
- ser_setstatus(port, 0);
- ser_purge(port);
- XMODEM_PROGRESS("Wait remote host\n");
-
- for(;;)
- {
- proceed = false;
- do
- {
- if (XMODEM_CHECK_ABORT)
- return false;
-
- switch (c = ser_getchar(port))
- {
- case XM_NAK:
- XMODEM_PROGRESS("Resend blk %d\n", blocknr);
- proceed = true;
- break;
-
- case XM_C:
- if (c == XM_C)
- {
- XMODEM_PROGRESS("Tx start (CRC)\n");
- usecrc = true;
- }
- else
- XMODEM_PROGRESS("Tx start (BCC)\n");
-
- proceed = true;
- break;
-
- case XM_ACK:
- /* End of transfer? */
- if (!size)
- return true;
-
- /* Call user function to read in one block */
- size = fd->read(fd, block_buffer, XM_BUFSIZE);
- XMODEM_PROGRESS("Send blk %d\n", blocknr);
- blocknr++;
- retries = 0;
- proceed = true;
- break;
-
- case EOF:
- ser_setstatus(port, 0);
- retries++;
- XMODEM_PROGRESS("Retries %d\n", retries);
- if (retries <= XM_MAXRETRIES)
- break;
- /* falling through! */
-
- case XM_CAN:
- XMODEM_PROGRESS("Transfer aborted\n");
- return false;
-
- default:
- XMODEM_PROGRESS("Skipping garbage\n");
- break;
- }
- }
- while (!proceed);
-
- if (!size)
- {
- ser_putchar(XM_EOT, port);
- continue;
- }
-
- /* Pad block with 0xFF if it's partially full */
- memset(block_buffer + size, 0xFF, XM_BUFSIZE - size);
-
- /* Send block header (STX, blocknr, ~blocknr) */
- #if XM_BUFSIZE == 128
- ser_putchar(XM_SOH, port);
- #else
- ser_putchar(XM_STX, port);
- #endif
- ser_putchar(blocknr & 0xFF, port);
- ser_putchar(~blocknr & 0xFF, port);
-
- /* Send block and compute its CRC/checksum */
- sum = 0;
- crc = 0;
- for (i = 0; i < XM_BUFSIZE; i++)
- {
- ser_putchar(block_buffer[i], port);
- crc = UPDCRC16(block_buffer[i], crc);
- sum += block_buffer[i];
- }
-
- /* Send CRC/Checksum */
- if (usecrc)
- {
- crc = UPDCRC16(0, crc);
- crc = UPDCRC16(0, crc);
- ser_putchar(crc >> 8, port);
- ser_putchar(crc & 0xFF, port);
- }
- else
- ser_putchar(sum, port);
- }
-}
-#endif
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 1999, 2001 Bernardo Innocenti <bernie@develer.com>
- *
- * -->
- * \brief X-Modem serial transmission protocol (interface)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- * \author Francesco Sacchi <batt@develer.com>
- */
-
-
-#ifndef MWARE_XMODEM_H
-#define MWARE_XMODEM_H
-#include <cfg/compiler.h>
-#include <kern/kfile.h>
-
-/**
- * Called to know if we want to abort data tranfer.
- * Redefine to whatever you need.
- * \{
- */
-#ifndef XMODEM_CHECK_ABORT
-#define XMODEM_CHECK_ABORT (false)
-#endif
-/*\}*/
-
-
-/**
- * Called to printf progress messages.
- * Default to kprintf debug, redefine to whatever you need.
- * \{
- */
-#ifndef XMODEM_PROGRESS
-#define XMODEM_PROGRESS(msg, ...) kprintf(msg, ## __VA_ARGS__)
-#endif
-
-
-/* fwd decl */
-struct Serial;
-
-bool xmodem_recv(struct Serial *port, KFile *fd);
-bool xmodem_send(struct Serial *port, KFile *fd);
-
-#endif /* MWARE_XMODEM_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \author Andrea Grandi <andrea@develer.com>
- *
- * \brief Tag protocol (protocol).
- *
- * TAG protocol is decribed in this way:
- * <pre>
- * ---------------------------------------------------
- * |STX (0x02)|data...(10 HEX chars)|CR|LF|ETX (0x03)|
- * ---------------------------------------------------
- * </pre>
- */
-
-#include "keytag.h"
-
-#include <kern/kfile.h>
-
-#include <drv/timer.h>
-#include <drv/ser.h>
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-static void keytag_clearPkt(struct TagPacket *pkt)
-{
- pkt->sync = false;
- pkt->len = 0;
-}
-
- void keytag_init(struct TagPacket *pkt)
- {
- keytag_clearPkt(pkt);
- }
-
- void keytag_poll(struct TagPacket *pkt)
-{
- int c;
-
- /* Get all chars from buffer */
- while ((c = kfile_getc(&pkt->tag_ser->fd)) != EOF)
- {
- /* Search for STX char in received chars */
- if (c == TAG_STX)
- {
- /* When STX is found a new packet begins */
- if (pkt->sync)
- kprintf("TAG double sync!\n");
- keytag_clearPkt(pkt);
- pkt->sync = true;
- }
- else if (pkt->sync)
- {
- /* Check for end of packet */
- if (c == TAG_ETX)
- {
- pkt->buf[TAG_MAX_PRINT_CHARS] = '\x0';
- /* Write read TAG on communication serial */
- kfile_printf(&pkt->comm_ser->fd, "tag %s", pkt->buf);
- pkt->sync = false;
- }
- else
- {
- /* Check for buffer overflow */
- if (pkt->len >= TAG_MAX_LEN)
- {
- kprintf("TAG buffer overflow\n");
- pkt->sync = false;
- }
- else
- {
- /* Add every char after STX to tag reading buffer */
- if (pkt->sync)
- {
- pkt->buf[pkt->len] = c;
- pkt->len++;
- }
- }
- }
- }
- }
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \author Andrea Grandi <andrea@develer.com>
- *
- * \brief Tag protocol. (interface).
- */
-
-#ifndef NET_KEYTAG_H
-#define NET_KEYTAG_H
-
-#include <kern/kfile.h>
-#include <drv/ser.h>
-
-/**
- * Starting communication char (STX).
- */
-#define TAG_STX 0x02
-
-/**
- * Ending communication char (ETX).
- */
-#define TAG_ETX 0x03
-
-/**
- * Max buffer lenght
- */
-#define TAG_MAX_LEN 14
-
-#define TAG_SER_PORT 0
-#define TAG_SER_BAUDRATE 9600
-
-/**
- * Max number of chars to print in the communication serial
- */
-#define TAG_MAX_PRINT_CHARS 12
-
-/**
- * Structure of a Tag packet
- */
-typedef struct TagPacket
-{
- KFileSerial *tag_ser; // Tag serial
- KFileSerial *comm_ser; // Communication serial
- bool sync; // Status flag: true if we find an STX
- uint16_t len; // Packet lenght
- uint8_t buf[TAG_MAX_LEN]; // Reception buffer
-} TagPacket;
-
-void keytag_init(struct TagPacket *pkt);
-void keytag_poll(struct TagPacket *pkt);
-
-#endif /* NET_TAG_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id: pocketbus.c 20131 2007-12-13 17:39:55Z batt $
- *
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief pocketBus protocol implementation.
- *
- * pocketBus protocol is a simple strictly master-slave protocol, usable
- * in embedded systems.
- * pocketBus frame is as follows:
- * <pre>
- * +----------------------------------------+
- * | STX | VER | ADDR | PAYLOAD | CKS | ETX |
- * +----------------------------------------+
- * | | | | | | |
- * + 1B + 1B + 2B + N Byte + 2B + 1B +
- * </pre>
- *
- * - STX, 1 byte (0x02), packet start
- * - VER, 1 byte, packet version
- * - ADDR, 2 byte, slave address
- * - PAYLOAD, N byte, data field
- * - CKS, 2 byte, checksum
- * - ETX, 1 byte, (0x03) packet end
- *
- * Protocol parsing start on STX reception. When the receiving routine
- * finds an STX char, it starts to read characters from the bus
- * until an ETX is received. Once a packet is received,
- * the parser checks packet correctness and checksum. If all is OK
- * the payload is returned.
- *
- * STX (0x02), ETX(0x03) and ESC(0x1B) are special characters and cannot be
- * transmitted inside payload without escaping them.
- * To escape a character you must precede it by the ESC char.
- * E.G. STX -> ESC + STX
- * ETX -> ESC + ETX
- * ESC -> ESC + ESC
- *
- * In the ADDR field is always specified the slave address.
- * In the case of master trasmitting, ADDR contains the slave destination
- * address.
- * In case of slave replying, ADDR contains the slave address itself.
- * Thus, the master device does not have an address. Packet must be routed to
- * master by hardware bus design.
- *
- * The checksum algorithm used is rotating hash algortihm, quite simple but more
- * reliable than simple checksum.
- * The checksum in computed on all fields excluding STX, ETX and CHK fields itself.
- * Checksum is computed on the packet *before* escaping.
- * Escape sequence counts for 1 character only (the escaped one).
- */
-
-#include "pocketbus.h"
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-
-#include <kern/kfile.h>
-
-#include <mware/byteorder.h>
-
-#include <string.h>
-
-/**
- * Send a character over pocketBus channel stream, handling escape mode.
- */
-void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c)
-{
- /* Update checksum */
- rotating_update1(c, &ctx->out_cks);
-
- /* Escape characters with special meaning */
- if (c == POCKETBUS_ESC || c == POCKETBUS_STX || c == POCKETBUS_ETX)
- kfile_putc(POCKETBUS_ESC, ctx->fd);
-
- kfile_putc(c, ctx->fd);
-}
-
-/**
- * Send pocketBus packet header.
- */
-void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr)
-{
- PocketBusHdr hdr;
-
- hdr.ver = POCKETBUS_VER;
- hdr.addr = cpu_to_be16(addr);
- rotating_init(&ctx->out_cks);
-
- /* Send STX */
- kfile_putc(POCKETBUS_STX, ctx->fd);
-
- /* Send header */
- pocketbus_write(ctx, &hdr, sizeof(hdr));
-}
-
-/**
- * Send buffer \a _data over bus, handling escape.
- */
-void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len)
-{
- const uint8_t *data = (const uint8_t *)_data;
-
- while (len--)
- pocketbus_putchar(ctx, *data++);
-}
-
-/**
- * Send pocketBus packet tail.
- */
-void pocketbus_end(struct PocketBusCtx *ctx)
-{
- /* Send checksum */
- rotating_t cks = cpu_to_be16(ctx->out_cks);
- pocketbus_write(ctx, &cks, sizeof(cks));
-
- /* Send ETX */
- kfile_putc(POCKETBUS_ETX, ctx->fd);
-}
-
-/**
- * Send buffer of \a data to address \a addr with a pocketBus packet over channel stream.
- */
-void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len)
-{
- pocketbus_begin(ctx, addr);
-
- /* Send data */
- pocketbus_write(ctx, data, len);
-
- pocketbus_end(ctx);
-}
-
-
-/**
- * Try to read a packet from the pocketBus.
- * \return true if a packet is received, false otherwise.
- */
-bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg)
-{
- int c;
-
- /* Process incoming characters until buffer is not empty */
- while ((c = kfile_getc(ctx->fd)) != EOF)
- {
- /* Look for STX char */
- if (c == POCKETBUS_STX && !ctx->escape)
- {
- /* When an STX is found, inconditionally start a new packet */
- if (ctx->sync)
- kprintf("pocketBus double sync!\n");
-
- ctx->sync = true;
- ctx->len = 0;
- rotating_init(&ctx->in_cks);
- continue;
- }
-
- if (ctx->sync)
- {
- /* Handle escape mode */
- if (c == POCKETBUS_ESC && !ctx->escape)
- {
- ctx->escape = true;
- continue;
- }
-
- /* Handle message end */
- if (c == POCKETBUS_ETX && !ctx->escape)
- {
- ctx->sync = false;
-
- /* Check minimum size */
- if (ctx->len < sizeof(PocketBusHdr) + sizeof(rotating_t))
- {
- kprintf("pocketBus short pkt!\n");
- continue;
- }
-
- /* Remove checksum bytes from packet len */
- ctx->len -= sizeof(rotating_t);
-
- /* Compute checksum */
- rotating_update(ctx->buf, ctx->len, &ctx->in_cks);
- rotating_t recv_cks = be16_to_cpu(*((rotating_t *)(ctx->buf + ctx->len)));
-
- /* Checksum check */
- if (recv_cks == ctx->in_cks)
- {
- PocketBusHdr *hdr = (PocketBusHdr *)(ctx->buf);
- /* Check packet version */
- if (hdr->ver == POCKETBUS_VER)
- {
- /* Packet received, set msg fields */
- msg->payload = ctx->buf + sizeof(PocketBusHdr);
- msg->addr = be16_to_cpu(hdr->addr);
- msg->len = ctx->len - sizeof(PocketBusHdr);
- msg->ctx = ctx;
- return true;
- }
- else
- {
- kprintf("pocketBus version mismatch, here[%d], there[%d]\n", POCKETBUS_VER, hdr->ver);
- continue;
- }
- }
- else
- {
- kprintf("pocketBus cks error, here[%04X], there[%04X]\n", ctx->in_cks, recv_cks);
- continue;
- }
-
- }
-
- ctx->escape = false;
-
- /* Check buffer overflow: simply ignore
- received data and go to unsynced state. */
- if (ctx->len >= CONFIG_POCKETBUS_BUFLEN)
- {
- kprintf("pocketBus buffer overflow\n");
- ctx->sync = false;
- continue;
- }
-
- /* Put received data in the buffer */
- ctx->buf[ctx->len] = c;
- ctx->len++;
- }
- }
-
- /*
- * Check stream status.
- */
- if (kfile_error(ctx->fd))
- {
- TRACEMSG("fd status[%04X]", kfile_error(ctx->fd));
- kfile_clearerr(ctx->fd);
- }
-
- return false;
-}
-
-
-/**
- * Initialize pocketBus protocol handler.
- */
-void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd)
-{
- ASSERT(ctx);
- ASSERT(fd);
-
- memset(ctx, 0, sizeof(*ctx));
- ctx->fd = fd;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id: pocketbus.h 20131 2007-12-13 17:39:55Z batt $
- *
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief pocketBus protocol interface.
- */
-
-#ifndef NET_POCKETBUS_H
-#define NET_POCKETBUS_H
-
-#include <algos/rotating_hash.h>
-#include <drv/ser.h>
-#include <kern/kfile.h>
-#include <cfg/compiler.h>
-#include "appconfig.h" //for CONFIG_POCKETBUS_BUFLEN
-
-/**
- * pocketBus special characters definitions.
- * \{
- */
-#define POCKETBUS_STX 0x02 //ASCII STX
-#define POCKETBUS_ETX 0x03 //ASCII ETX
-#define POCKETBUS_ESC 0x1B //ASCII ESC
-#define POCKETBUS_ACK 0x06 //ASCII ACK
-#define POCKETBUS_NAK 0x15 //ASCII NAK
-/*\}*/
-
-#define POCKETBUS_BROADCAST_ADDR 0xFFFF ///< pocketBus broadcast address
-
-/**
- * Type for pocketBus length.
- */
-typedef uint16_t pocketbus_len_t;
-
-/**
- * Type for pocketBus addresses.
- */
-typedef uint16_t pocketbus_addr_t;
-
-/**
- * Header of pocketBus messages.
- */
-typedef struct PocketBusHdr
-{
- #define POCKETBUS_VER 1
- uint8_t ver; ///< packet version
- pocketbus_addr_t addr; ///< slave address
-} PocketBusHdr;
-
-/**
- * pocketBus context structure.
- */
-typedef struct PocketBusCtx
-{
- struct KFile *fd; ///< File descriptor
- bool sync; ///< Status flag: true if we have received an STX, false otherwise
- bool escape; ///< Status flag: true if we are in escape mode, false otherwise
- rotating_t in_cks; ///< Checksum computation for received data.
- rotating_t out_cks; ///< Checksum computation for transmitted data.
- pocketbus_len_t len; ///< Received length
- uint8_t buf[CONFIG_POCKETBUS_BUFLEN]; ///< receiving Buffer
-} PocketBusCtx;
-
-/**
- * Structure holding pocketBus message parameters.
- */
-typedef struct PocketMsg
-{
- struct PocketBusCtx *ctx; ///< pocketBus message context
- pocketbus_addr_t addr; ///< address for received packet
- pocketbus_len_t len; ///< payload length
- const uint8_t *payload; ///< payload data
-} PocketMsg;
-
-/**
- * This ensure that endianess convertion functions work on
- * the right data size.
- * \{
- */
-STATIC_ASSERT(sizeof(pocketbus_addr_t) == sizeof(uint16_t));
-STATIC_ASSERT(sizeof(rotating_t) == sizeof(uint16_t));
-/*\}*/
-
-void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c);
-void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr);
-void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len);
-void pocketbus_end(struct PocketBusCtx *ctx);
-
-void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len);
-bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg);
-void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd);
-
-#endif /* NET_POCKETBUS_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id: pocketcmd.c 16587 2007-10-02 14:31:02Z batt $
- *
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief pocketBus protocol Command layer implementation.
- *
- * This module implements command layer over pocketBus
- * protocol.
- * Payload packets received by pocketBus are first checked for
- * address matching.
- * If a packet is addressed to us we look for a suitable
- * callback function to call.
- *
- * The received payload format is as follows:
- * <pre>
- * +----------------------------------------+
- * | CMD | DATA |
- * +----------------------------------------+
- * | | |
- * + 2B + 0..N Byte +
- * </pre>
- *
- * The CMD ID used is the same supplied by the master when
- * the command was sent.
- */
-
-#include "pocketcmd.h"
-#include "pocketbus.h"
-
-#include <cfg/macros.h>
-#include <cfg/debug.h>
-#include <cfg/module.h>
-
-#include <drv/timer.h>
-
-#include <mware/byteorder.h>
-
-#include <string.h>
-
-/**
- * pocketBus Command poll function.
- * Call it to read and process pocketBus commands.
- */
-void pocketcmd_poll(struct PocketCmdCtx *ctx)
-{
- PocketMsg msg;
-
- /* Try to read a packet from pocketBus */
- while (pocketbus_recv(ctx->bus_ctx, &msg))
- {
- /* Check address */
- if (msg.addr == ctx->addr ||
- msg.addr == POCKETBUS_BROADCAST_ADDR)
- {
- const PocketCmdHdr *hdr = (const PocketCmdHdr *)msg.payload;
- pocketcmd_t cmd = be16_to_cpu(hdr->cmd);
-
- /* We're no longer waiting for a reply (in case we were) */
- if (cmd == ctx->waiting)
- ctx->waiting = PKTCMD_NULL;
-
- /* Check for command callback */
- pocketcmd_hook_t callback = ctx->search(cmd);
-
- /* Call it if exists */
- if (callback)
- {
- PocketCmdMsg cmd_msg;
-
- cmd_msg.cmd_ctx = ctx;
- cmd_msg.cmd = cmd;
- cmd_msg.len = msg.len - sizeof(PocketCmdHdr);
- cmd_msg.buf = msg.payload + sizeof(PocketCmdHdr);
-
- callback(&cmd_msg);
- }
- }
- }
-}
-
-/**
- * Send command \a cmd to/from slave adding \a len arguments in \a buf.
- * Address used is contained in \a ctx->addr .
- * If we are master and the message has a reply, you must set \a wait_reply to true.
- * \return true if all is ok, false if we are already waiting a replay from another slave.
- */
-bool pocketcmd_send(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len, bool wait_reply)
-{
- /* Check if we are waiting a reply from someone */
- if (ctx->waiting != PKTCMD_NULL)
- {
- /* Check is reply timeout is elapsed */
- if (timer_clock() - ctx->reply_timer < ms_to_ticks(PKTCMD_REPLY_TIMEOUT))
- {
- TRACEMSG("Pkt discard! waiting cmd[%04X]\n", ctx->waiting);
- return false;
- }
- else
- {
- TRACEMSG("Timeout waiting cmd[%04X]\n", ctx->waiting);
- ctx->waiting = PKTCMD_NULL;
- }
- }
-
- /* Endianess! */
- cmd = cpu_to_be16(cmd);
-
- /* Send packet */
- pocketbus_begin(ctx->bus_ctx, ctx->addr);
- pocketbus_write(ctx->bus_ctx, &cmd, sizeof(cmd));
- pocketbus_write(ctx->bus_ctx, buf, len);
- pocketbus_end(ctx->bus_ctx);
-
- if (wait_reply)
- {
- ctx->waiting = cmd;
- ctx->reply_timer = timer_clock();
- }
- return true;
-}
-
-/**
- * Init pocketBus command layer.
- * \a ctx is pocketBus command layer context.
- * \a bus_ctx is pocketBus context.
- * \a addr is slave address (see pocketcmd_setAddr for details.)
- * \a search is the lookup function used to search command ID callbacks.
- */
-void pocketcmd_init(struct PocketCmdCtx *ctx, struct PocketBusCtx *bus_ctx, pocketbus_addr_t addr, pocketcmd_lookup_t search)
-{
- ASSERT(ctx);
- ASSERT(bus_ctx);
- ASSERT(search);
- MOD_CHECK(timer);
-
- memset(ctx, 0, sizeof(*ctx));
- ctx->bus_ctx = bus_ctx;
- ctx->search = search;
- pocketcmd_setAddr(ctx, addr);
-}
-
-/**
- * Helper function used to reply to master with an ACK.
- */
-void pocketcmd_replyAck(struct PocketCmdMsg *msg)
-{
- uint8_t ack[] = { POCKETBUS_ACK };
-
- pocketcmd_slaveReply(msg->cmd_ctx, msg->cmd, ack, sizeof(ack));
-}
-
-/**
- * Helper function used to reply to master with a NAK.
- */
-void pocketcmd_replyNak(struct PocketCmdMsg *msg)
-{
- uint8_t nak[] = { POCKETBUS_NAK };
-
- pocketcmd_slaveReply(msg->cmd_ctx, msg->cmd, nak, sizeof(nak));
-}
-
+++ /dev/null
-/**
- * \file
- * <!--
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- * -->
- *
- * \version $Id: pocketcmd.h 20030 2007-12-04 16:16:09Z batt $
- *
- * \author Francesco Sacchi <batt@develer.com>
- *
- * \brief pocketBus protocol command layer interface.
- */
-
-#ifndef NET_POCKETCMD_H
-#define NET_POCKETCMD_H
-
-#include "pocketbus.h"
-#include <cfg/compiler.h>
-
-#define PKTCMD_NULL 0 ///< pocketBus Null command
-
-#define PKTCMD_REPLY_TIMEOUT 50 ///< Command replay timeout in milliseconds
-
-typedef uint16_t pocketcmd_t; ///< Type for Command IDs
-
-/**
- * Header for transmitted pocketBus Commands.
- */
-typedef struct PocketCmdHdr
-{
- pocketcmd_t cmd; ///< command ID
-} PocketCmdHdr;
-
-/**
- * This ensure that endianess convertion functions work on
- * the right data size.
- * \{
- */
-STATIC_ASSERT(sizeof(pocketcmd_t) == sizeof(uint16_t));
-/*\}*/
-
-/* fwd declaration */
-struct PocketCmdCtx;
-
-/**
- * pocketBus command message structure.
- */
-typedef struct PocketCmdMsg
-{
- struct PocketCmdCtx *cmd_ctx; ///< command context
- pocketcmd_t cmd; ///< command id
- pocketbus_len_t len; ///< optional arg length
- const uint8_t *buf; ///< optional arguments
-} PocketCmdMsg;
-
-/**
- * Type for command hooks.
- */
-typedef void (*pocketcmd_hook_t)(struct PocketCmdMsg *cmd_msg);
-
-/**
- * Type for lookup function hooks.
- */
-typedef pocketcmd_hook_t (*pocketcmd_lookup_t)(pocketcmd_t cmd);
-
-/**
- * pocketBus context for command layer communications.
- */
-typedef struct PocketCmdCtx
-{
- struct PocketBusCtx *bus_ctx; ///< pocketBus context
- pocketbus_addr_t addr; ///< Our address
- pocketcmd_lookup_t search; ///< Lookup function used to search for command callbacks
- pocketcmd_t waiting; ///< The command ID we are waiting for or PKTCMD_NULL.
- ticks_t reply_timer; ///< For waiting_reply
-} PocketCmdCtx;
-
-/**
- * Set slave address \a addr for pocketBus command layer.
- * If we are a slave this is *our* address.
- * If we are the master this is the slave address to send messages to.
- */
-INLINE void pocketcmd_setAddr(struct PocketCmdCtx *ctx, pocketbus_addr_t addr)
-{
- ctx->addr = addr;
-}
-
-void pocketcmd_init(struct PocketCmdCtx *ctx, struct PocketBusCtx *bus_ctx, pocketbus_addr_t addr, pocketcmd_lookup_t search);
-void pocketcmd_poll(struct PocketCmdCtx *ctx);
-bool pocketcmd_send(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len, bool has_replay);
-void pocketcmd_replyNak(struct PocketCmdMsg *msg);
-void pocketcmd_replyAck(struct PocketCmdMsg *msg);
-
-/**
- * Helper function used by master to send a command to slave \a addr.
- */
-INLINE bool pocketcmd_masterSend(struct PocketCmdCtx *ctx, pocketbus_addr_t addr, pocketcmd_t cmd, const void *buf, size_t len)
-{
- pocketcmd_setAddr(ctx, addr);
- return pocketcmd_send(ctx, cmd, buf, len, true);
-}
-
-/**
- * Helper function used by slave to reply to a master command.
- */
-INLINE bool pocketcmd_slaveReply(struct PocketCmdCtx *ctx, pocketcmd_t cmd, const void *buf, size_t len)
-{
- return pocketcmd_send(ctx, cmd, buf, len, false);
-}
-
-
-#endif /* NET_POCKETCMD_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Portable abstraction for high-resolution time handling (implementation)
- *
- * \version $Id$
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-
-#include "hptime.h"
-
-#if defined(_WIN32)
-
-#include <windows.h>
-
-hptime_t hptime_get(void)
-{
- FILETIME ft;
-
- /*
- * La precisione dei FileTime sarebbe 100ns, ma il
- * valore viene ottenuto convertendo una struttura
- * SYSTEMTIME, che ha precisione di 1ms. Il numero
- * che otteniamo e' quindi sempre un multiplo di
- * 100000.
- */
- GetSystemTimeAsFileTime(&ft);
-
- /* Copy the upper/lower into a quadword. */
- return (((hptime_t)ft.dwHighDateTime) << 32) + (hptime_t)ft.dwLowDateTime;
-}
-
-#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-
-#include <sys/time.h> /* for gettimeofday() */
-#include <stddef.h> /* for NULL */
-
-hptime_t hptime_get(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return (hptime_t)tv.tv_sec * HPTIME_TICKS_PER_SECOND
- + (hptime_t)tv.tv_usec;
-}
-
-#else /* !__unix__ */
- #error OS dependent support code missing for this OS
-#endif /* !__unix__ */
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \brief Portable abstraction for high-resolution time handling (interface)
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- */
-#ifndef HPTIME_H
-#define HPTIME_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#ifdef _WIN32
-
- /** our type for "high precision absolute time" */
- typedef __int64 hptime_t;
-
- #define HPTIME_TICKS_PER_SECOND (10000000I64)
- #define HPTIME_TICKS_PER_MILLISEC (10000I64)
- #define HPTIME_TICKS_PER_MICRO (10I64)
-
-#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-
- #include <stdint.h> /* int64_t */
-
- #ifndef DEVLIB_MTIME_DEFINED
- #define DEVLIB_MTIME_DEFINED 1 /* Resolve conflict with <cfg/compiler.h> */
- typedef int32_t mtime_t;
- #define SIZEOF_MTIME_T (32 / CPU_BITS_PER_CHAR)
- #define MTIME_INFINITE 0x7FFFFFFFL
- #endif
-
- /** Type for "high precision absolute time". */
- typedef int64_t hptime_t;
-
- #define HPTIME_TICKS_PER_SECOND (1000000LL)
- #define HPTIME_TICKS_PER_MILLISEC (1000LL)
- #define HPTIME_TICKS_PER_MICRO (1LL)
-
-#else /* !__unix__ */
- #error OS dependent support code missing for this OS
-#endif /* !__unix__ */
-
-/**
- * Return the current time with the maximum precision made available from the hosting OS
- */
-extern hptime_t hptime_get(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* HPTIME_H */
+++ /dev/null
-#
-# $Id$
-# Copyright 2002,2003,2004,2005,2006 Develer S.r.l. (http://www.develer.com/)
-# All rights reserved.
-#
-# Based on:
-# GCC-AVR standard Makefile part 2
-# Volker Oth 1/2000
-#
-# Author: Bernardo Innocenti <bernie@develer.com>
-#
-
-# Remove all default pattern rules
-.SUFFIXES:
-
-# Verbosity
-ifeq ($(V),1)
-# Verbose build
-Q :=
-L := @echo >/dev/null
-else
-# Quiet build
-Q := @
-L := @echo
-endif
-
-# Select Bourne Again SHell as default make shell
-SHELL := bash
-
-# Checker build
-ifeq ($(C),1)
-CC = $(CHECKER)
-CFLAGS += -Wundef -D__x86_64__=1 -D__unix__=1 -D__linux__=1 -D__STDC_VERSION__=199901L
-endif
-
-# Initialize $(top_srcdir) with current directory, unless it was already initialized
-top_srcdir ?= $(shell pwd)
-
-# Products
-TRG_ELF = $(TRG:%=$(OUTDIR)/%.elf)
-TRG_S19 = $(TRG:%=$(OUTDIR)/%.s19)
-TRG_HEX = $(TRG:%=$(OUTDIR)/%.hex)
-TRG_BIN = $(TRG:%=$(OUTDIR)/%.bin)
-TRG_ROM = $(TRG:%=$(OUTDIR)/%.rom)
-TRG_COF = $(TRG:%=$(OUTDIR)/%.cof)
-TRG_EXE = $(TRG:%=$(OUTDIR)/%)
-
-
-RECURSIVE_TARGETS = all-recursive install-recursive clean-recursive
-
-# The default target
-.PHONY: all
-ifeq ($(EMBEDDED_TARGET),1)
-all:: all-recursive $(TRG_S19) $(TRG_HEX) $(TRG_BIN)
-else
-all:: all-recursive $(TRG_EXE)
-endif
-
-# Generate project documentation
-.PHONY: docs
-docs:
- $L "Building documentation"
- $Q $(DOXYGEN)
-
-# Generate ctags
-.PHONY: tags
-tags:
- $L "Rebuilding C tags database"
- $Q ctags -R --exclude=doc
-
-# Run testsuite
-.PHONY: check
-check:
- $L "Running testsuite"
- $Q ./run_tests.sh
-
-define build_target
-
-ifneq ($$(strip $$($(1)_MCU)),)
-# Define all project specific object files
-$(1)_CFLAGS += -mmcu=$$($(1)_MCU)
-$(1)_CXXFLAGS += -mmcu=$$($(1)_MCU)
-$(1)_ASFLAGS += -mmcu=$$($(1)_MCU)
-$(1)_CPPAFLAGS += -mmcu=$$($(1)_MCU)
-$(1)_LDFLAGS += -mmcu=$$($(1)_MCU)
-endif
-ifneq ($$(strip $$($(1)_CPU)),)
-# Define all project specific object files
-$(1)_CFLAGS += -mcpu=$$($(1)_CPU)
-$(1)_CXXFLAGS += -mcpu=$$($(1)_CPU)
-$(1)_ASFLAGS += -mcpu=$$($(1)_CPU)
-$(1)_CPPAFLAGS += -mcpu=$$($(1)_CPU)
-$(1)_LDFLAGS += -mcpu=$$($(1)_CPU)
-endif
-ifneq ($$(strip $$($(1)_LDSCRIPT)),)
-$(1)_LDFLAGS += -Wl,-T$$($(1)_LDSCRIPT)
-endif
-
-$(1)_CC = $$($(1)_CROSS)$$(CC)
-$(1)_CXX = $$($(1)_CROSS)$$(CXX)
-$(1)_AS = $$($(1)_CROSS)$$(AS)
-$(1)_OBJCOPY = $$($(1)_CROSS)$$(OBJCOPY)
-
-$(1)_COBJ = $$(foreach file,$$($(1)_CSRC:%.c=%.o),$$(OBJDIR)/$(1)/$$(file))
-$(1)_CXXOBJ = $$(foreach file,$$($(1)_CXXSRC:%.cpp=%.o),$$(OBJDIR)/$(1)/$$(file))
-$(1)_PCOBJ = $$(foreach file,$$($(1)_PCSRC:%.c=%_P.o),$$(OBJDIR)/$(1)/$$(file))
-$(1)_AOBJ = $$(foreach file,$$($(1)_ASRC:%.s=%.o),$$(OBJDIR)/$(1)/$$(file))
-$(1)_CPPAOBJ = $$(foreach file,$$($(1)_CPPASRC:%.S=%.o),$$(OBJDIR)/$(1)/$$(file))
-$(1)_OBJ := $$($(1)_COBJ) $$($(1)_CXXOBJ) $$($(1)_PCOBJ) $$($(1)_AOBJ) $$($(1)_CPPAOBJ)
-$(1)_SRC := $$($(1)_CSRC) $$($(1)_CXXSRC) $$($(1)_PCSRC) $$($(1)_ASRC) $$($(1)_CPPASRC)
-OBJ += $$($(1)_OBJ)
-
-ifneq ($$(strip $$($(1)_CXXSRC)),)
-$(1)_LD = $$($(1)_CROSS)$$(LDXX)
-else
-$(1)_LD = $$($(1)_CROSS)$$(LD)
-endif
-
-# Compile: instructions to create assembler and/or object files from C source
-$$($(1)_COBJ) : $$(OBJDIR)/$(1)/%.o : %.c
- $L "$(1): Compiling $$< (C)"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_CC) -c $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
-
-# Compile: instructions to create assembler and/or object files from C++ source
-$$($(1)_CXXOBJ) : $$(OBJDIR)/$(1)/%.o : %.cpp
- $L "$(1): Compiling $$< (C++)"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_CXX) -c $$(CXXFLAGS) $$($(1)_CXXFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
-
-# Generate assembly sources from C files (debug)
-$$(OBJDIR)/$(1)/%.s : %.c
- $L "$(1): Generating asm source $$<"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_CC) -S $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$< -o $$@
-
-# Generate special progmem variant of a source file
-$$($(1)_PCOBJ) : $$(OBJDIR)/$(1)/%_P.o : %.c
- $L "$(1): Compiling $$< (PROGMEM)"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_CC) -c -D_PROGMEM $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
-
-# Assemble: instructions to create object file from assembler files
-$$($(1)_AOBJ): $$(OBJDIR)/$(1)/%.o : %.s
- $L "$(1): Assembling $$<"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_AS) -c $$(ASFLAGS) $$($(1)_ASFLAGS) $$< -o $$@
-
-$$($(1)_CPPAOBJ): $$(OBJDIR)/$(1)/%.o : %.S
- $L "$(1): Assembling with CPP $$<"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_CC) -c $$(CPPAFLAGS) $$($(1)_CPPAFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
-
-
-# Link: instructions to create elf output file from object files
-$$(OUTDIR)/$(1).elf $$(OUTDIR)/$(1)_nostrip: bumprev $$($(1)_OBJ) $$($(1)_LDSCRIPT)
- $L "$(1): Linking $$@"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_LD) $$($(1)_OBJ) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
-
-# Strip debug info
-$$(OUTDIR)/$(1): $$(OUTDIR)/$(1)_nostrip
- $L "$(1): Generating stripped executable $$@"
- $Q $$($(1)_STRIP) -o $$@ $$^
-
-# Compile and link (program-at-a-time)
-$$(OUTDIR)/$(1)_whole.elf: bumprev $$($(1)_SRC) $$($(1)_LDSCRIPT)
- $L "$(1): Compiling and Linking whole program $$@"
- @$$(MKDIR_P) $$(dir $$@)
- $Q $$($(1)_CC) $$($(1)_SRC) $$(CFLAGS) $$($(1)_CFLAGS) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
-
-# Flash target
-# NOTE: we retry in case of failure because the STK500 programmer is crappy
-.PHONY: flash_$(1)
-flash_$(1): $(OUTDIR)/$(1).s19 flash_$(1)_local
- if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U flash:w:$$< ; then \
- $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U flash:w:$$< ; \
- fi
- #avarice --mkII -j usb --erase --program --verify --file images/triface.elf
-
-.PHONY: flash_$(1)_local
-flash_$(1)_local:
-
-.PHONY: fuses_$(!)
-fuses_$(1):
- if [ ! -z "$$($(1)_efuse)" ] ; then \
- if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U efuse:w:$$($(1)_efuse):m ; then \
- $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U efuse:w:$$($(1)_efuse):m ; \
- fi \
- fi
- if [ ! -z "$$($(1)_hfuse)" ] ; then \
- if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U hfuse:w:$$($(1)_hfuse):m ; then \
- $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U hfuse:w:$$($(1)_hfuse):m ; \
- fi \
- fi
- if [ ! -z "$$($(1)_lfuse)" ] ; then \
- if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lfuse:w:$$($(1)_lfuse):m ; then \
- $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lfuse:w:$$($(1)_lfuse):m ; \
- fi \
- fi
- if [ ! -z "$$($(1)_lock)" ] ; then \
- if ! $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lock:w:$$($(1)_lock):m ; then \
- $(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lock:w:$$($(1)_lock):m ; \
- fi \
- fi
-
-$$(OUTDIR)/$(1).hex: $$(OUTDIR)/$(1).elf
- $$($(1)_OBJCOPY) -O ihex $$< $$@
-
-$$(OUTDIR)/$(1).s19: $$(OUTDIR)/$(1).elf
- $$($(1)_OBJCOPY) -O srec $$< $$@
-
-$$(OUTDIR)/$(1).bin: $$(OUTDIR)/$(1).elf
- $$($(1)_OBJCOPY) -O binary $$< $$@
-
-$$(OUTDIR)/$(1).obj: $$(OUTDIR)/$(1).elf
- $$($(1)_OBJCOPY) -O avrobj $$< $$@
-
-$$(OUTDIR)/$(1).rom: $$(OUTDIR)/$(1).elf
- $$($(1)_OBJCOPY) -O $$(FORMAT) $$< $$@
-# $$($(1)_OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" -O $$(FORMAT) $$< $$(@:.rom=.eep)
-
-endef
-
-# Generate build rules for all targets
-$(foreach t,$(TRG),$(eval $(call build_target,$(t))))
-
-# Generate Qt's moc files from headers
-# NOTE: moc totally sucks and can generate empty files for some error conditions,
-# leading to puzzling linker errors. Kill 'em and abort build.
-%_moc.cpp: %.h
- $(MOC) -o $@ $<
- if [ ! -s $< ]; then \
- rm -f $@; \
- exit 1; \
- fi
-
-
-%.cof: %.elf
- $(COFFCONVERT) -O coff-ext-avr $< $@
-# $(COFFCONVERT) -O coff-avr $< $@ # For use with AVRstudio 3
-
-#make instruction to delete created files
-clean: clean-recursive
- -$(RM_R) $(OBJDIR)
- -$(RM_R) $(OUTDIR)
-
-$(RECURSIVE_TARGETS):
- @target=`echo $@ | sed s/-recursive//`; \
- for dir in $(SUBDIRS); do \
- if [ -e $$dir/configure.in ] || [ -e $$dir/configure.ac ] && [ ! -x $$dir/configure ]; then \
- echo "Running autogen.sh in $$dir..."; \
- ( cd $$dir && chmod a+x autogen.sh && ./autogen.sh && rm -f Makefile || exit 1 ); \
- fi; \
- if [ ! -e $$dir/Makefile ]; then \
- if [ -e "$$dir/build-$(ARCH)" ]; then \
- echo "Running build script in $$dir..."; \
- ( cd $$dir && chmod a+x build && ./build || exit 1 ); \
- else \
- echo "Running configure in $$dir..."; \
- ( cd $$dir && ./configure --prefix=$(PREFIX) || exit 1 ); \
- fi; \
- fi; \
- $(MAKE) -C $$dir $$target || exit 1; \
- done
-
-BUILDREV_H = buildrev.h
-
-ifeq ($(shell [ -e verstag.c ] && echo yes),yes)
-.PHONY: bumprev
-bumprev:
- @buildnr=0; \
- if [ -f $(BUILDREV_H) ]; then \
- buildnr=`sed <"$(BUILDREV_H)" -n -e 's/#define VERS_BUILD \([0-9][0-9]*\)/\1/p'`; \
- fi; \
- buildnr=`expr $$buildnr + 1`; \
- buildhost=`hostname`; \
- echo "#define VERS_BUILD $$buildnr" >"$(BUILDREV_H)"; \
- echo "#define VERS_HOST \"$$buildhost\"" >>"$(BUILDREV_H)"; \
- echo "Building revision $$buildnr"
-else
-.PHONY: bumprev
-bumprev:
-
-endif
-
-# Include dependencies
-ifneq ($(strip $(OBJ)),)
--include $(OBJ:%.o=%.d)
-endif
+++ /dev/null
-#!/bin/bash
-#
-# Copyright 2005 Develer S.r.l. (http://www.develer.com/)
-# All rights reserved.
-#
-# Author: Bernardo Innocenti <bernie@develer.com>
-#
-# $Id$
-#
-
-
-VERBOSE=1
-
-CC=gcc
-CFLAGS="-W -Wall -Wextra -I. -fno-builtin -D_DEBUG"
-
-CXX=g++
-CXXFLAGS="$CFLAGS"
-
-
-for test in `find . -name "*_test.*"`; do
- [ $VERBOSE -gt 0 ] && echo "Running $test..."
- case "$test" in
- *.cpp)
- $CXX $CXXFLAGS $test -o test || exit 1
- ./test || exit 1
- rm -f test
- ;;
- *.c)
- $CC $CFLAGS $test -o test || exit 1
- ./test || exit 1
- rm -f test
- ;;
- esac
-done
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Define application version strings
- */
-#include <verstag.h>
-
-/*
- * "buildrev.h" is auto-generated by the build infrastructure,
- * incrementing VERS_BUILD each time the project is rebuilt.
- */
-#include "buildrev.h"
-
-const char vers_tag[] = VERS_TAG;
-const char vers_build_str[] = _STRINGIZE(VERS_BUILD);
-const char vers_host[] = VERS_HOST;
-const int vers_build_nr = VERS_BUILD;
-
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004, 2005, 2006 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2001, 2002, 2003 by Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Declare application version strings
- */
-#ifndef DEVLIB_VERSTAG_H
-#define DEVLIB_VERSTAG_H
-
-#ifndef ARCH_CONFIG_H
- #include <cfg/arch_config.h>
-#endif
-
-#define APP_NAME "Appname"
-#define APP_DESCRIPTION "Long application name description"
-#define APP_AUTHOR "Develer"
-#define APP_COPYRIGHT "Copyright 2006 Develer (http://www.develer.com/)"
-
-#if (ARCH & ARCH_FOO)
- #define VERS_MAJOR 0
- #define VERS_MINOR 1
- #define VERS_REV 0
- #define VERS_LETTER ""
-#elif (ARCH & ARCH_BAR)
- #define VERS_MAJOR 0
- #define VERS_MINOR 1
- #define VERS_REV 0
- #define VERS_LETTER ""
-#else
- #error unknown architecture
-#endif
-
-/**
- * If _SNAPSHOT is defined, \c VERS_TAG contains the build date
- * date instead of a numeric version string.
- */
-#define _SNAPSHOT
-
-#ifdef _DEBUG
- #define VERS_DBG "D"
-#else
- #define VERS_DBG ""
-#endif
-
-#define __STRINGIZE(x) #x
-#define _STRINGIZE(x) __STRINGIZE(x)
-
-/** Build application version string (i.e.: "1.7.0") */
-#define MAKE_VERS(maj,min,rev) _STRINGIZE(maj) "." _STRINGIZE(min) "." _STRINGIZE(rev) VERS_LETTER VERS_DBG
-#ifdef _SNAPSHOT
- #define VERS_TAG "snapshot" " " __DATE__ " " __TIME__ " " VERS_LETTER " " VERS_DBG
-#else
- #define VERS_TAG MAKE_VERS(VERS_MAJOR,VERS_MINOR,VERS_REV)
-#endif
-
-/** Build application version string suitable for MS windows resource files (i.e.: "1, 7, 0, 1") */
-#define MAKE_RCVERS(maj,min,rev,bld) _STRINGIZE(maj) ", " _STRINGIZE(min) ", " _STRINGIZE(rev) ", " _STRINGIZE(bld)
-#define RCVERSION_TAG MAKE_VERS(VERS_MAJOR,VERS_MINOR,VERS_REV)
-
-/** The revision string (contains VERS_TAG) */
-extern const char vers_tag[];
-
-/** Sequential build number (contains VERS_BUILD) */
-extern const int vers_build_nr;
-//extern const char vers_build_str[];
-
-/** Hostname of the machine used to build this binary (contains VERS_HOST) */
-extern const char vers_host[];
-
-#endif /* DEVLIB_VERSTAG_H */